如何检测套接字连接何时丢失?
Posted
技术标签:
【中文标题】如何检测套接字连接何时丢失?【英文标题】:How to detect when socket connection is lost? 【发布时间】:2012-08-18 22:45:46 【问题描述】:我有一个脚本(我现在没有代码示例,但我使用了 IO::Async),它连接到远程服务器上的套接字并进行侦听。客户端通常只是监听新数据。
问题是客户端无法检测到是否发生网络问题并且套接字连接消失了。 我使用了 IO::Async,也尝试了 IO::Socket。建立初始连接后,句柄始终“已连接”。
如果网络连接再次建立,套接字连接自然仍然丢失,因为脚本不知道它应该重新连接。
我正在考虑创建某种“keepAlive”,它每 X 秒“ping”(syswrite)套接字(如果没有新消息通过套接字)来检查连接是否仍然存在。
这是正确的方法吗,还是可能有另一种更有创意或更清洁的解决方案?
【问题讨论】:
我认为您所说的“心跳”程序是解决此问题的唯一已知方法。我向你保证,它非常干净和有创意。 ) 【参考方案1】:您可以设置SO_KEEPALIVE
套接字选项,对于 TCP,该选项会定期发送保活消息,并且可能有助于检测这种情况。如果检测到这种情况,您将收到一个 EOF 条件(很可能导致包含 IO::Async::Stream
触发 on_read_eof
)。
为了获得更好的解决方案,您可以考虑使用某种应用程序级别的 keepalive 消息,例如 IRC 的 PING
命令。
【讨论】:
有没有一种很好的方法可以将 SO_KEEPALIVE 直接传递给 IO::Async (Loop)? 不是直接的,但是给定套接字句柄,您可以 $sock->setsockopt(SOL_SOCKET, SO_KEEPALIVE, 1); 默认保活间隔为两小时。如果保持活动失败,您将收到“重置”条件,而不是 EOS。 公平点。你必须把间隔调短一些。有一些特定于 Linux 的 TCP 套接字选项。【参考方案2】:简短的回答是在 perl 中没有自动检测丢弃的套接字的默认方法。
您的 ping 方法可能会很有效;您可以在后台运行一个发送 ping 请求的连续线程,如果它没有收到响应,则可以通知主线程并重新连接。
如果你想弄得一团糟,你可以使用 select() 来检测保持活动消息;但是,这可能需要一些操作系统配置,具体取决于您的平台。
更多详情请参阅此主题:http://www.perlmonks.org/?node_id=566568
【讨论】:
正如我上面所说,SO_KEEPALIVE
选项通常可以很好地检测到这种事情。此外,对于应用程序级别的 ping 支持,IO::Async
已经拥有诸如周期性计时器之类的实体,这将有助于实现这一目标。
IO::Async::Timer::Periodic 看起来是 ping 服务器的好方法以上是关于如何检测套接字连接何时丢失?的主要内容,如果未能解决你的问题,请参考以下文章