Delphi 中停止 TIdTCPServer 服务

在 Delphi 中使用 TIdTCPServer 做 TCP 服务端的时候,会遇到一个问题。当我们希望停止服务端的服务的时候,如果还有客户端连接没有断开,则服务端会卡死。实际上,只要服务端认定还有客户端尚未断开,就会卡死,这就导致客户端一旦异常下线,服务端停止服务的时候就会卡死。

网上提供的解决方法是,在停止服务之前,依次断开所有的客户端,再执行 Active:=False 操作。具体的代码是:

var
  List:TList;
  i:Word;
begin
  List:=IdTCPServer.Contexts.LockList;
  if List.Count>0 then
  begin
    for i:=0 to List.Count-1 do
    begin
      try
        TIdContext(List[i]).Data.Destroy;
        TIdContext(List[i]).Data:=Nil;
        TIdContext(List[i]).Connection.Disconnect;
      except

      end;
    end;
  end;
  List.Clear;
  IdTCPServer.Contexts.UnlockList;
  try
    IdTCPServer.Active:=False;
  except

  end;
end;

实践证明,这种方法是行不通的,至少在我机子上实验,照旧卡死,依旧卡死在 IdTCPServer.Active:=False 这一句。

最终找到解决方案。上述方法不能成功的原因是,TIdContext(IdTCPServer.Contexts.LockList[i]).Connection.Disconnect 并不能成功的断开连接。(为什么?我不甚了解,正在研究中。)只要将这句换成 TIdContext(List[i]).Connection.Socket.Close 问题就解决了。

具体的原因神马的慢慢研究,先将此方法记录在此。