读书人

麻烦大家帮小弟我看一下有关SOCKET的程

发布时间: 2013-03-26 09:54:34 作者: rapoo

麻烦大家帮我看一下有关SOCKET的程序,服务端和客户端一直连接不上,我都无语了
本帖最后由 dth886 于 2012-08-19 22:07:35 编辑 客户端


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, ScktComp,ExtCtrls;

type
TfrmMain = class(TForm)
Memo1: TMemo;
Client: TClientSocket;
StatusBar1: TStatusBar;
Label1: TLabel;
edtHost: TEdit;
Label2: TLabel;
edtPort: TEdit;
btnconnect: TButton;
btndisconnect: TButton;
btnsend: TButton;
btncreat: TButton;
Edit1: TEdit;
procedure btnconnectClick(Sender: TObject);
procedure btndisconnectClick(Sender: TObject);
procedure Edit1KeyPress(Sender: TObject; var Key: Char);
procedure ClientConnect(Sender: TObject; Socket: TCustomWinSocket);
procedure ClientRead(Sender: TObject; Socket: TCustomWinSocket);
procedure ClientDisconnect(Sender: TObject; Socket: TCustomWinSocket);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure btncreatClick(Sender: TObject);

private
{ Private declarations }
public
{ Public declarations }
end;

var
frmMain: TfrmMain;
TotalLen:Integer;

implementation
uses ShellAPI;

{$R *.dfm}



procedure TfrmMain.btnconnectClick(Sender: TObject);
begin
Client.Address:=edtHost.Text; //指定主机IP
Client.Port:=strtoint(edtPort.Text); //指定主机端口
Client.Active:=true;
end;

procedure TfrmMain.btndisconnectClick(Sender: TObject);
begin
Client.Active:=false;
end;

procedure TfrmMain.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
if key=#13 then //如果按下回车键,就发送文本
begin
if not Client.Active then
btnConnectClick(Sender);


Client.Socket.SendText(Edit1.Text);
edit1.SelectAll;
key:=#0; //“空操作”
end;
end;

procedure TfrmMain.ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
StatusBar1.Panels.Items[0].Text:='接受连接';
StatusBar1.Panels.Items[1].Text:='';
end;

procedure TfrmMain.ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
re:pchar;
sbuf:string;
relong:integer;
begin
re:=nil; //nil常用于指针对象,用于初始化为空值
while socket.ReceiveLength>0 do
begin
re:=AllocMem(socket.ReceiveLength); //分配内存的同时进行初始化
try
relong:=socket.ReceiveLength ;
socket.ReceiveBuf(re^,socket.ReceiveLength);
sBuf:=strpas(re); // pchar转换为string
setlength(sbuf,relong);
TotalLen:=TotalLen+relong;
Statusbar1.Panels.Items[1].Text:='总共接收(byte):'
+IntToStr(TotalLen);
Statusbar1.Update;
Finally
freemem(re);
end;
Memo1.Lines.Add(sbuf);
end;
end ;


//事件:关闭连接

procedure TfrmMain.ClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
Statusbar1.Panels.Items[0].Text:='关闭与主机的连接';
Statusbar1.Panels.Items[0].Text:='';
memo1.Lines.Clear;
edit1.Text:='';
end;

//关闭窗体 事件


procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin


if client.Active then
client.Close; //关闭socket
end;


procedure TfrmMain.btncreatClick(Sender: TObject);
begin
ShellExecute(self.Handle,nil,pchar(application.exename),nil,nil,sw_normal)
end;

end.




服务端

unit server;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, StdCtrls, ScktComp,Extctrls;

type
TForm1 = class(TForm)
Server: TServerSocket;
Label1: TLabel;
edtSend: TEdit;
btnSend: TButton;
Label2: TLabel;
Label3: TLabel;
ComboBox1: TComboBox;
Memo1: TMemo;
StatusBar1: TStatusBar;
btnOneSend: TButton;
procedure ServerAccept(Sender: TObject; Socket: TCustomWinSocket);
procedure ServerClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerClientRead(Sender: TObject; Socket: TCustomWinSocket);
procedure ServerClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerClientError(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
procedure btnSendClick(Sender: TObject);
procedure btnOneSendClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

Type UsrRec=Record
SocketID:Integer;
UsrName:string;
Passwd:string;
IP:string;
ReceivingData:string;
End;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ServerAccept(Sender: TObject; Socket: TCustomWinSocket);
var Tempstr:pchar;


begin
TempStr:=pchar('欢迎登录服务器 '#13#10);
socket.SendText(TempStr);
TempStr:=pchar('##############################'+#13#10);
Socket.SendText(TempStr);
TempStr:=pchar('你所输入的内容将发送给所有在线用户'+#13#10);
socket.SendText(TempStr);
end;

procedure TForm1.ServerClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
var
strlp,strHost:string;
Count:Integer;
begin
strlp:=Socket.RemoteAddress;
strHost:=Socket.RemoteHost;
memo1.Lines.Add('当前登录用户');
memo1.Lines.Add(#9'SocketID:'+IntToStr(Socket.SocketHandle));
combobox1.Items.Add(IntToStr(Socket.SocketHandle));
memo1.Lines.Add(#9'IP地址:'+strlp);
memo1.Lines.Add(#9'主机名:'+strHost);
Count:=Server.Socket.ActiveConnections;
Statusbar1.Panels.Items[1].Text:='在线用户:'+IntToStr(Count);
end;

procedure TForm1.ServerClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
p:pchar;
length:longint;
Count,i:integer;
begin
p:=nil;
while socket.ReceiveLength>0 do
begin
length:=socket.ReceiveLength; //到达缓存区的字节数
getmem(p,length); //未到达缓存区的数据分配内存
end;
try
socket.ReceiveBuf(p^,socket.ReceiveLength); //接收消息
Count:=Server.Socket.ActiveConnections;
for i:=0 to Count-1 do
server.Socket.Connections[i].SendBuf(p^,length);
finally
freemem(p);
end;
end;
procedure TForm1.ServerClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
var
Count:Integer; //对当前用户数进行计数
IDIndex:Integer;
begin
memo1.Lines.Add('用户离线');
memo1.Lines.Add(' SocketID:'+Inttostr(socket.SocketHandle));
IDIndex:=Combobox1.Items.IndexOf(IntToStr(socket.SocketHandle));
Combobox1.Items.Delete(IDIndex); //清除ID信息
Count:=Server.Socket.ActiveConnections-1;
StatusBar1.Panels.Items[1].Text:='在线用户:'+IntToStr(Count);
end;

procedure TForm1.ServerClientError(Sender: TObject;


Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
//错误判断
Case ErrorCode of
10054:Memo1.Lines.Add('网络连接被用户重置');
Else
Memo1.Lines.Add('发生Socket错误,错误代码:'+IntToStr(errorcode));
end;
ErrorCode:=0;
end;
procedure TForm1.btnSendClick(Sender: TObject);
var
i:integer;
Count:Integer;
begin
Count:=Server.Socket.ActiveConnections;
for i:=0 to Count-1 do
server.Socket.Connections[i].SendText(edtSend.Text); //发送信息
end;

procedure TForm1.btnOneSendClick(Sender: TObject); //指定发送
var
ID:Integer;
Socket:TCustomWinSocket;
begin
if Combobox1.Text=''
then exit;
ID:=StrToInt(combobox1.Text);
Socket:=TCustomWinSocket.Create(ID);
Socket.SendText(edtSend.Text);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
server.Active:=true;

StatusBar1.Panels.Items[0].Text:='服务器已启动。主机名:'
+server.Socket.LocalHost
+' 监听端口:'+IntToStr(Server.Port);
self.Caption:=StatusBar1.Panels.Items[0].Text;
application.Title:=statusbar1.Panels.Items[0].Text;
statusbar1.Panels.Items[1].Text:='在线用户人数:'+IntToStr(server.Socket.ActiveConnections);

end;

end.


[解决办法]
server只设置port
client端只要设定host为server的IP,port跟server的一样,就可以连接了

若连不上,可能是有防火墙

读书人网 >.NET

热点推荐