Delphi + Synapse:如何检查我是不是仍然连接
Posted
技术标签:
【中文标题】Delphi + Synapse:如何检查我是不是仍然连接【英文标题】:Delphi + Synapse: How to check if I am still connectedDelphi + Synapse:如何检查我是否仍然连接 【发布时间】:2012-10-14 07:11:57 【问题描述】:我将TTCPBlockSocket
用于 TCP/IP 应用程序。问题是我无法确定连接何时丢失。
GetLastError
返回 0Read
返回 0
但即使应用程序已连接,我也会遇到这些值,因此我可以获取它如何在 TCP/IP 连接丢失时收到通知。
谢谢
【问题讨论】:
我会说CanRead
函数调用将 0 作为 Timeout
参数传递是您正在寻找的。此函数在内部调用 InternalCanRead
,它执行 Winsock select
函数。如果发生任何错误,CanRead
函数将返回 False。
@TLama 我会试试的,谢谢。
@TLama 你的回答让我走上了正确的道路,如果 TCPBlockSocket.CanRead(0) 和 TCPBlockSocket.WaitingData = 0 断开连接:= true,则必须满足以下条件以检查它是否断开连接。您可以将其发布为我接受的答案
@TLama 是突触专家!
【参考方案1】:
我想说,您可以使用CanRead
方法,将0 传递给它的Timeout
参数。该函数在内部为套接字执行select
函数,并在发生错误时返回 False。仅使用此方法就足够了,因为如果您失去连接,select
函数将返回 SOCKET_ERROR
,并且它会导致 CanRead
方法返回 False 作为结果。所以我认为,以这种方式检查套接字连接是否存在就足够了:
function IsSocketAlive(ASocket: TTCPBlockSocket): Boolean;
begin
Result := ASocket.CanRead(0);
end;
【讨论】:
Nope 是不够的,自己测试一下 +1WaitingData
方法(如您添加的那样)返回网络输入缓冲区中待处理的数据量,如果该内部 ioctlsocket
函数调用没有因 SOCKET_ERROR
而失败并返回当您的连接已经丢失时,待处理的数据量并不能反映您的需求。还是我错了? (很遗憾,我现在无法测试)【参考方案2】:
正如 opC0de 所说,要检查客户端是否仍然连接,您需要同时检查 TCPBlockSocket.CanRead(0) 和 TCPBlockSocket.WaitingData = 0
function IsSocketAlive(ASocket: TTCPBlockSocket): Boolean;
begin
Result := (ASocket.Socket = INVALID_SOCKET) or ((ASocket.WaitingData = 0) and ASocket.CanRead(0));
end;
我在我的项目中使用这种方式,所以我可以确认它有效。
【讨论】:
【参考方案3】:我使用的是 kattunga 的答案,但在我的压力测试期间遇到了很多误报触发。我的假设是数据包有时会在 WaitingData 和 CanRead 条件之间到达服务器,导致服务器认为套接字已死。 我改变了条件的顺序,问题就消失了。
function TTCPSynWorkThread.IsSocketDead(ASocket: TTCPBlockSocket): boolean;
begin
Result := (ASocket.Socket = INVALID_SOCKET) or (ASocket.CanRead(0) and (ASocket.WaitingData = 0));
end;
【讨论】:
以上是关于Delphi + Synapse:如何检查我是不是仍然连接的主要内容,如果未能解决你的问题,请参考以下文章