一、Server端
使用的indy控件:
idtcpsrvr1: TIdTCPServer;
a)设置默认端口
1 begin 2 Self.btn1.Enabled:=False; 3 idtcpsrvr1.DefaultPort:=2001; 4 idtcpsrvr1.Active:=True; 5 end;
b)对客户端连接事件响应
1 procedure TForm1.idtcpsrvr1Connect(AThread: TIdPeerThread); 2 var 3 ipStr:string; 4 begin 5 ipStr:=AThread.Connection.Socket.Binding.PeerIP; 6 ShowMessage('IP地址为: '+ipStr+' 的用户连接过来!'); 7 end;
c)对客户端发送过来的字符串进行显示,并通知客户端接收成功
1 procedure TForm1.idtcpsrvr1Execute(AThread: TIdPeerThread); 2 var 3 str:string; 4 begin 5 with AThread.Connection do 6 begin 7 str:=readln('',5000); 8 inc(messageId); 9 WriteLn('第'+inttostr(messageId)+'条数据接收成功,内容为:'+str); 10 end; 11 end;
二、Client端
a)指定Server端ip和端口号
1 begin 2 Socket := TIdTCPClient.Create(nil); 3 Socket.Host:='127.0.0.1'; 4 Socket.Port:=2001; 5 end;
b)建立连接
1 if not socket.Connected then 2 begin 3 try 4 socket.Connect(5000); 5 Memo1.Lines.Add('socke连接已经成功建立!'); 6 btn1.Caption:='断开连接'; 7 except 8 ShowMessage('连接失败,请检查连接设置!'); 9 end; 10 end
注:socket连接建立失败的两种情形: 1)探测找不到目标主机:此时会等到timeout时间结束后,抛出连接异常 2)探测到目标主机,但是目标主机上socket连接未开:立即抛出连接异常
c)发送与接收数据
1 var 2 RequestStr,BackStr:string; 3 begin 4 if socket.Connected then 5 begin 6 RequestStr:='tttttttttttt'; 7 try 8 socket.WriteLn(RequestStr); 9 Memo1.Lines.Add('发送数据:'+RequestStr); 10 BackStr:=socket.ReadLn('',5000); //实际上timeout是不起作用的,indy本身 11 //的bug;此时如果server端无数据则会死等 12 Memo1.Lines.Add('返回数据:'+BackStr); 13 except 14 ShowMessage('发送数据失败!'); 15 end; 16 end 17 else 18 begin 19 Memo1.Lines.Add('连接已被断开,无法发送!'); 20 end; 21 end;
说明:1)indy的TIdTCPClient是阻塞式的,程序会停在那里等待接收,故有以下两种读取数据的方式:
a)可以单独启一个线程来负责接收
b)通过timer来监控是否有新数据到
1 procedure timer.ontimer................. 2 var temp:string; 3 begin 4 idtcpclient.readfromstack(false,1,false); 5 while idtcpclient.InputBuffer.Size> 0 do begin 6 temp:=idtcpclient.ReadLn; 7 end; 8 end;
2)如果能知道要取的数据包的大小,可以用readbuffer(abuffer,包长度)来取得包。
d)断开连接
1 begin 2 try 3 socket.Disconnect; 4 Memo1.Lines.Add('socket连接已断开!'); 5 btn1.Caption:='建立连接'; 6 except 7 ShowMessage('断开连接时出错!'); 8 end; 9 end;
|
请发表评论