【问题标题】:Socet recv hangs when server crashes当服务器崩溃时,Soet recv 挂起
【发布时间】:2014-12-10 17:14:24
【问题描述】:

我正在使用 Windows 和 MAC 上的套接字开发客户端服务器程序,目前面临的问题是,当服务器程序使用任务管理器崩溃/终止时,客户端调用 recv 会永远阻塞。我将一些数据发送到服务器并使用recv异步等待回复。此回复将在一段时间后来自服务器,无法确定。 当套接字的其他端死亡时,我期待 recv 出现错误。不知道如何处理这种情况。

建议?

谢谢,

【问题讨论】:

    标签: sockets


    【解决方案1】:

    使用setsockopt()SO_RCVTIMEO 选项设置读取超时,将其设置为一些合理的值。

    【讨论】:

    • 或者使用select()/poll()/epoll()来等待有超时的入站数据,并且只有在确实有东西等待被读取时才调用recv()(包括优雅的对等端的流结束关闭)。
    【解决方案2】:

    如果您使用 TCP 并且对等套接字正确关闭并且两个系统之间的通信正常(没有损坏的电缆等),您的 recv 不应挂起(而是指示关闭的连接)。在 UNIX 中,即使进程崩溃或被杀死,内核也会正确关闭套接字,但我不知道在这种情况下 Windows 的行为。

    如果您使用 UDP 进行通信,recv 仍然会挂起,因为没有明确的连接关闭。

    【讨论】:

    • 你应该得到一个流的结束,而不是一个错误。但是发送 host 可能会以这样的方式失败,甚至没有发送。
    • 是的,但主要是recv 不会再挂了。是的,发送主机可能完全失败,但在这种情况下,两个系统之间的通信将不再工作。如果主机崩溃,则不会关闭套接字,并且如果主机稍后再次出现,它将不知道另一端可能仍然打开的任何套接字。可能会使用超时或 so_keepalive 之类的东西来检测这一点 - 但目前甚至不清楚 OP 是否完全使用 TCP 进行通信(超时当然也适用于 UDP)。
    • '对等套接字正确关闭' - 我认为 OP 更担心这种情况不会发生。在这种情况下,TCP 的默认结果是半关闭的连接永远挂起,等待永远不会到来的数据。
    • 至少在 UNIX 上,即使进程被杀死,套接字也会正确关闭,这是 OP 所担心的。就像我说的,我不知道 Windows 的行为是否相同,但我实际上会期待它。再说一遍 - 只要我们甚至不知道 OP 使用的是哪种通信协议(TCP、UDP),就很难推测。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-17
    • 1970-01-01
    • 1970-01-01
    • 2011-01-15
    • 2019-12-04
    • 2020-12-24
    • 2015-11-17
    相关资源
    最近更新 更多