最近要写一个上位机软件,需要用到idtcpserver来接收客户端发来的数据,但是发现idtcpserver这个控件比较难控制,总是出现一些未知的错误,网上也找不到相关资料,只能自己一步步来研究了,经过1天的摸索,终于大功告成,共享出来,希望大家少走弯路。
FClientList: TList; //用来存放客户端连接
maxconnect:integer; //最大连接数
procedure TForm1.BtnConnectClick(Sender: TObject);//开启服务,不用多说了
begin
maxconnect:=strtoint(LEdtMaxClient.text);
IdTCPServer1.DefaultPort := StrToIntDef(LEdtPort.Text, strtoint(LEdtPort.Text));
IdTCPServer1.Active := True;
StatusBar1.Panels[0].Text := ifthen(IdTCPServer1.active,'服务已启动','服务未开启');
end;
//这里是客户端连接事件
procedure TForm1.IdTCPServer1Connect(AContext: TIdContext);
var
adata: TClient;
IP: String;
Port: integer;
begin
ip := AContext.Binding.PeerIP;
Port := AContext.Binding.PeerPort;
if FClientList.Count >= maxconnect then
begin
AContext.Connection.IOHandler.WriteLn('notConnect');
Memo1.Lines.Add(ip+'客户端连接超出最大限制数量');
AContext.Connection.Socket.Close; //很重要
AContext.Connection.Disconnect;
end
else begin
adata := TClient.Create;
adata.PeerPort := Port;
adata.PeerIP := ip;
adata.AContext := Acontext;
FClientList.Add(adata);
StatusBar1.Panels[1].Text := '连接数:'+inttostr(FClientList.Count);
AContext.Connection.IOHandler.WriteLn('okConnect');
Memo1.Lines.Add(IP+'客户端连接成功');
end;
end;
//客户端断开事件
procedure TForm1.IdTCPServer1Disconnect(AContext: TIdContext);
var
port, i: integer;
client: TClient;
begin
port := AContext.Binding.PeerPort;
for i := FClientList.Count - 1 downto 0 do
begin
client := TClient(FClientList.Items[i]);
if client.PeerPort = port then
begin
Client.Free;
FClientList.Delete(i);
end;
end;
memo1.Lines.Add('断开客户端IP:'+inttostr(port));
statusbar1.Panels[1].Text := '连接数:'+inttostr(FClientList.count);
end;
//接收到数据
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
begin
if (Acontext.Connection.Connected) and (AContext.Connection.IOHandler.InputBuffer.Size > 0) then //已经连街上的一个进程
begin
OnReceiveData(AContext);
end
else begin
Sleep(1);
end;
end;
//解析数据
procedure TForm1.OnReceiveData(AContext: TIdContext);
var
iFileSize: integer;
rbyte: TIdBytes;
begin
iFileSize:= AContext.Connection.IOHandler.InputBuffer.Size;
Acontext.Connection.IOHandler.ReadBytes(rbyte,iFileSize,true);
//dosomething
end;
//服务器端关闭服务
procedure TForm1.BtnDisconnectClick(Sender: TObject);
var
i: integer;
AContext: TIdContext;
ALockList: TList;
begin
ALockList := IdTCPServer1.Contexts.LockList;
try
for i := ALockList.Count - 1 downto 0 do
begin
添加try来过滤某些错误
AContext := TIdContext(ALockList.Items[I]);
AContext.Connection.IOHandler.WriteLn('disconnect');
AContext.Connection.Socket.Close; //很重要,否则客户端接收不到断开事件
AContext.Connection.Disconnect;
end;
finally
IdTCPServer1.Contexts.UnlockList;
end;
IdTCPServer1.Bindings.Add.CloseSocket;
IdTCPServer1.Active:=False;
IdTCPServer1.Bindings.Clear;
StatusBar1.Panels[0].Text := ifthen(IdTCPServer1.active,'服务已启动','服务未开启');
statusbar1.Panels[1].Text := '连接数:'+inttostr(FClientList.count);
end;
源码地址:
//download.csdn.net/download/zjw6199218/11995104