Bootstrap

关于idtcpserver的使用


 用idTCPServer,客户端接上来时,如何取得客户端的IP? 

IP:=AThread.Connection.Binding.PeerIP;
Port:=AThread.Connection.Binding.PeerPort; 


尝试解答你的疑问:
问题一:
在Form1中放入IDTCPServer控件,一旦有socket连接,IDTCPServer自动建立一个线程与之
建立一个TCP/IP连接,我们在IDTCPServer.OnExecute中写入自己的代码就可以在这个独立
的线程中完成我们所希望的动作吗?
解答:
一旦有socket连接,IDTCPServer 不仅建立一个线程,更需要把这个建立的线程保存到一个
线程列表中去。然后在 IDTCPServer.OnExecute 中传入“每线程”这个参数,程序从传入
的“每线程”这个参数,检索出对应的 socket 连接。

问题二:
如果我们在OnExecute中调用TForm1.aaa这个函数,那么这个函数是不是会造成同步问题,
例如登录人数的统计。
解答:
统计登录人数不应该在这个事件中处理。其实只要读一下线程列表就可以知道结果。OnExecute
中的同步,是 indy 的一个工作要求,同时发生的客户必须排队处理。所以,原则上不会
造成同步问题,但是,如果你引用的 Form 过程中,有异步变量,就要注意可能的同步问题。

不知道这样的回答,是否能让你满意。


您是不是不要这样理解:
“FForm.IdTCPClient1.Connected then // IdTCPClient1 在 FForm 这个主线程中”
您可以理解为:IdTCPClient1 是类实例 FForm 的一个成员。至于您的 TReceiveThread
中引用了 FForm 这个类,并把这个 FForm 类做为了 TThread 类的成员就值得考虑了。
按你描述的意思,大概这个 TfmClient 是一个 TForm 类,这时候除非你动态在线程里创建
这个 TfmClient 类,不然的话就可能有苦头吃了,很容易造成死锁。 

 

 

已经说了,Indy 是一个多线程控件,在 Server 连接的时候,针对每客户会创建一个线程,
只要有客户发送数据,就会激活 Srever 的 OnExecute 事件。需要做的,就是在 OnExecute
中识别是哪个客户(也即线程)发来的请求,针对这个客户的 socket 连接返回服务就可以
了。
Server 端首先是响应客户的 Connect 事件,一旦连接了,就自动在服务端建立了一个连接
线程。而这个连接线程是需要 Server 维护的,indy 的最大连接线程数不会大于 600 个,
有 600 个线程你还不够用的话,基本上就不能使用 indy 控件了。 


Event handler for peer thread execution.

property OnExecute: TIdServerThreadEvent;

Description

OnExecute is an event handler for TIdServerThreadEvents. OnExecute occurs when a TIdPeerThread attempts to perform the

TIdPeerThread.Run method. OnExecute receives AThread as a parameter, representing the TIdPeerThread thread that will be

started.

Assign a TIdServerThreadEvent event handler procedure to OnExecute to respond to the event notification.

Use CommandHandlers and CommandHandlersEnabled to provide finer control over commands executed for a peer thread connection.
-----
procedure TIdListenerThread.Run;
var
 LIOHandler: TIdIOHandler;
 LPeer: TIdTCPServerConnection;
 LThread: TIdPeerThread;
begin
 try
   if Assigned(Server) then begin  // This is temporary code just to test one exception
     while True do begin
       LThread := nil;
       LPeer := TIdTCPServerConnection.Create(Server);
       LIOHandler := Server.IOHandler.Accept(Binding.Handle, SELF);
       if LIOHandler = nil then begin
         FreeAndNil(LPeer);
         Stop;
         Exit;
       end
       else begin
         LThread := TIdPeerThread(Server.ThreadMgr.GetThread);
         LThread.FConnection :

;