【发布时间】:2017-07-09 21:16:57
【问题描述】:
我正在使用TIdTCPServer。我有一个客户端异常断开连接。
我正在尝试断开此客户端的连接,如下所示:
//class TClientConnection = class(TIdServerContext)
var
Clienttodisconnect: TClientConnection;
List := Server.Contexts.LockList;
try
for I := 0 to List.Count - 1 do
begin
Clienttodisconnect := TClientConnection(List.Items[I]);
if Clienttodisconnect.uuid = idtodiscnnect then
begin
try
Clienttodisconnect.Connection.Disconnect;
except
end;
end;
end;
finally
Server.Contexts.UnlockList;
end;
客户端有时会与服务器断开连接,有时会卡住,直到服务器重新启动。
我做错了什么?我只想断开客户端与上下文的连接。
这里是服务器 onexecute 事件
var
Connection: TClientConnection;
CMD: String;
Cache, OutboundCmds: TStringList;
I: integer;
UConnected : Boolean;
Len: Integer;
begin
sleep(10);
Try
UConnected := AContext.Connection.Connected;
Except
UConnected := False;
End;
If UConnected <> True Then
begin
AContext.Connection.Disconnect;
exit;
end;
Len := AContext.Connection.IOHandler.InputBuffer.Size;
If Len >= 200000 then
begin
AContext.Connection.Disconnect;
exit;
end;
Connection := AContext as TClientConnection;
// check for pending outbound commands...
OutboundCmds := nil;
try
Cache := Connection.OutboundCache.Lock;
try
if Cache.Count > 0 then
begin
OutboundCmds := TStringList.Create;
OutboundCmds.Assign(Cache);
Cache.Clear;
end;
finally
Connection.OutboundCache.Unlock;
end;
if OutboundCmds <> nil then
begin
for I := 0 to OutboundCmds.Count - 1 do
begin
AContext.Connection.IOHandler.Writeln(OutboundCmds.Strings[I],
IndyTextEncoding_UTF8);
end;
Connection.LastSendRecv := Ticks64;
end;
finally
if OutboundCmds <> nil then
begin
for I := 0 to OutboundCmds.Count - 1 do
begin
OutboundCmds.Objects[I].Free;
end;
end;
OutboundCmds.Free;
end;
// check for a pending inbound command...
if AContext.Connection.IOHandler.InputBufferIsEmpty then
begin
AContext.Connection.IOHandler.CheckForDataOnSource(100);
AContext.Connection.IOHandler.CheckForDisconnect;
if AContext.Connection.IOHandler.InputBufferIsEmpty then
begin
if GetElapsedTicks(Connection.LastSendRecv) >= 30000 then
AContext.Connection.Disconnect;
Exit;
end;
end;
.......
........
【问题讨论】:
-
idtodiscnnect来自哪里?其余的(除了当你找到正确的客户时异常吃和没有退出循环)似乎很好。 -
不要让 except 块裸露!始终记录错误(或在对话框或其他地方显示),它可以为您的调试过程提供重要信息
-
@Victoria
idtodiconnect是从客户端发送到服务器的 const 参数。 -
我在异常块上进行了一些日志跟踪,并且在断开异常断开的客户端时没有引发任何异常。
-
您的
OnExecute处理程序是什么样的?它的编码方式对TIdTCPServer进程如何断开连接有很大影响。而且这个问题中显示的代码无论如何都不是断开客户端的最安全方法。最好在OnExecute事件中处理它。使用超时,或标记TClientConnection并让OnExecute查找该标记,因此可以在拥有客户端连接的线程中调用Disconnect()。