在 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 问题就解决了。
具体的原因神马的慢慢研究,先将此方法记录在此。