3

如何从套接字客户端程序中找出远程连接已关闭(例如服务器已关闭)。当我执行 recv 并且服务器关闭时,如果我没有设置任何超时,它会阻塞。但是在我的情况下,我无法设置任何可靠的超时值来解决它,否则即使服务器启动,recv 也会超时,但响应确实需要比我设置的超时值更长的时间。

4

2 回答 2

3

不幸的是,ZeroMQ 只是将其传递到下一层。因此,您在 ZeroMQ 之上实现的协议将不得不处理这个问题。

建议使用心跳。基本上,如果连接处于空闲状态,只需让一侧发送消息。另一方可以将不存在此类消息视为失败条件并关闭连接。

您可能希望修改更高级别的协议以使其更健壮。例如,您可以提交命令,查询其状态,并允许对方忘记该命令。这样,如果连接丢失,您可以重新连接并查询任何未完成的命令。任何它没有,你知道没有通过,可以重新提交。一旦你得到一个命令结果的回复,你就可以告诉对方它现在可以忘记这个回复了。

这允许您在执行长时间运行的命令时保持连接处于活动状态。每隔一段时间你就会问,“一切都好吗”。对方回答:“是的”。您可以使用长轮询,其中在命令执行期间另一方延迟响应一秒钟左右。这允许它立即返回结果,而不必为下一个查询等待一秒钟。

具体细节取决于您的确切要求,但您必须将其正确设计到您的协议中。

于 2013-11-13T12:18:07.467 回答
0

如果远程主机在没有向您发送 tcpFIN包的情况下发生故障,那么您将没有机会检测到这一点。您可以通过在该端口上建立连接后对该端口设置防火墙来测试该行为。您的程序将永远“挂起”。

但是,Linux 内核支持一种称为TCP 保持活动的机制,该机制旨在在给定超时后关闭 tcp 连接。如果您不能为您的应用程序指定超时,那么就没有可靠的机会使用它。最后的机会可能是使用应用程序协议的特性(你能说出它的名字吗?),如果该协议不支持连接处理的特性,你可以在此基础上自己发明一些东西。

于 2013-11-13T12:02:56.333 回答