【问题标题】:Identifying remote disconnection in socket client识别套接字客户端中的远程断开连接
【发布时间】:2016-09-23 16:45:32
【问题描述】:

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

【问题讨论】:

  • 您在 TCP 之上使用什么协议?没有“一种正确的方法”可以做到这一点。这取决于您正在实施的特定协议。遵守协议的规则。
  • 我正在使用 ZeroMQ。我也在他们的论坛上提出这个问题,看看是否有这样的规定。

标签: linux sockets zeromq


【解决方案1】:

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

Heartbeats are recommended. 基本上,如果连接处于空闲状态,只需让一侧发送消息即可。对方可以将没有此类消息视为失败条件并关闭连接。

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

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 如果协议没有解决这个明显、众所周知和易于理解的问题,那么协议就从根本上被破坏了,应该被丢弃。
    • 我正在使用 ZeroMQ。我也在他们的论坛上提出这个问题,看看是否有这样的规定。
    • 这里有网站:zeromq.org,这里是他们关于 API 参考的文档:api.zeromq.org 我试图探索他们的 TCP KEEP ALIVE 选项,但到目前为止还没有弄清楚。跨度>
    • @user33804 他们以前提出的建议和我完全一样——使用保持活动状态——但似乎在那之后他们实现了“心跳”功能。
    猜你喜欢
    • 1970-01-01
    • 2010-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 2019-09-20
    相关资源
    最近更新 更多