2012-08-23 90 views
3

我有一个脚本(此时我没有代码示例,但是我使用了IO :: Async),它连接到远程服务器上的套接字并侦听。客户通常只是监听新数据。如何检测套接字连接何时丢失?

问题是客户端无法检测到网络问题是否发生,并且套接字连接消失。 我用IO ::异步,我也尝试过IO :: Socket。初始连接建立后,手柄始终“连接”。

如果再次建立网络连接,套接字连接自然仍然丢失,因为脚本不知道应该重新连接。

我想创建一种“keepAlive”,它每X秒(如果没有新的东西通过套接字)“ping”(syswrite)套接字来检查连接是否仍然存在。

这是做到这一点的正确方法,或者是否有另一种更具创造性或更清洁的解决方案?

+0

我想你说的是“心跳式”程序是唯一已知的解决了这个问题。这是相当干净和创造性的,我向你保证。 ) – raina77ow

回答

4

您可以设置SO_KEEPALIVE套接字选项,TCP选项用于发送定期保持消息,并可帮助检测此情况。如果检测到这种情况,您将收到EOF条件(最有可能导致包含IO::Async::Stream的消息on_read_eof)。

为了获得更好的解决方案,您可能会考虑某种应用级别保持活动消息,例如IRC的PING命令。

+0

有没有一种很好的方式将SO_KEEPALIVE直接传递给IO :: Async(Loop)? – toktok

+0

不是直接的,但给定的套接字句柄,你可以只是$ sock-> setsockopt(SOL_SOCKET,SO_KEEPALIVE,1); – LeoNerd

+0

默认的存活时间间隔是两个小时。如果保持活着失败,您将被传递'重置'条件,而不是EOS。 – EJP

2

简短的答案是没有默认的方式来自动检测perl中的丢弃套接字。

你的ping方法可能会工作得很好;您可以在发送ping请求的后台运行连续线程,并且如果它未收到响应,则可以通知主线程并发出重新连接。

如果你想弄乱你可以使用select()来检测保持活动的消息;但是这可能需要一些OS配置,具体取决于您的平台。

详情请参阅此线程:http://www.perlmonks.org/?node_id=566568

+1

正如我上面所说的那样,'SO_KEEPALIVE'选项通常在检测这种事情方面做得相当好。此外,对于应用程序级的ping支持,“IO :: Async”已经具有定期计时器等实体,这将有助于实现这一点。 – LeoNerd

+0

IO :: Async :: Timer :: Periodic看起来像一个伟大的方式来ping服务器 – toktok