如何从套接字客户端程序中找出远程连接已关闭(例如服务器已关闭)。当我执行recv并且服务器关闭时,如果我没有设置任何超时,则会阻塞。但是在我的情况下,我不能放置任何可靠的超时值来解决它,否则即使服务器启动时recv也会超时,但响应确实需要比我设置的超时值更长的时间。
答案 0 :(得分:3)
不幸的是,ZeroMQ只是将其传递给下一层。因此,您在ZeroMQ之上实现的协议必须处理这个问题。
Heartbeats are recommended.基本上,如果连接空闲,则只有一方发送消息。另一方可以将缺少此类消息视为失败条件并关闭连接。
您可能希望修改更高级别的协议以使其更加健壮。例如,您可以提交命令,查询其状态,并允许另一方忘记该命令。这样,如果连接丢失,您可以重新连接并查询任何未完成的命令。任何它没有,你知道没有通过,可以重新提交。一旦你得到一个命令结果的回复,你可以告诉对方它现在可以忘记响应。
这使您可以在长时间运行的命令中保持连接处于活动状态。你常常问,“一切都好吗”。另一方回答“是的”。您可以使用long polling,而另一方在命令正在进行时会延迟响应一秒钟。这允许它立即返回结果,而不必等待下一次查询。
具体细节取决于您的具体要求,但必须将此设计正确地纳入您的协议。
答案 1 :(得分:0)
如果远程主机发送时没有向您发送tcp FIN
包,那么您就没有机会检测到它。您可以通过在该端口上建立连接后对端口进行防火墙来测试该行为。你的程序将永远“挂起”。
但是,Linux内核支持一种名为TCP keep alives的机制,它意味着在给定的超时后关闭tcp连接。如果您无法为应用程序指定超时,那么就没有可靠的机会来使用它。最后的机会可能是使用应用程序协议的功能(你可以命名吗?),如果该协议不支持连接处理功能,你可以自己发明一些东西。