麻烦大家帮小弟我看一上有关SOCKET的程序,服务端和客户端一直连接不下,小弟我都无语了
麻烦大家帮我看一下有关SOCKET的程序,服务端和客户端一直连接不上,我都无语了
客户端
服务端
客户端
- Delphi(Pascal) code
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.
服务端
- Delphi(Pascal) code
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.