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 是不够的,自己测试一下 +1 WaitingData 方法(如您添加的那样)返回网络输入缓冲区中待处理的数据量,如果该内部 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:如何检查我是不是仍然连接的主要内容,如果未能解决你的问题,请参考以下文章

Delphi - 检查内存是不是“按时”释放

delphi 如何检测代理服务器是不是正常

如何在 Delphi 中测试泛型类型变量是不是与 Default(T) 相等?

delphi 如何检查指定服务的状态

Delphi网格面板检查单元格是不是为空

Delphi - 使用套接字从 Web 下载文件