【问题标题】:Physical disconnection from network and intermittent socket error 10057与网络的物理断开和间歇性套接字错误 10057
【发布时间】:2017-10-03 09:56:52
【问题描述】:

我的一个客户有一个 Windows 应用程序,其中两台机器之间有网络连接。该系统应该处理丢失的连接。它通过在客户端位置上保留一个计数器来做到这一点,每次从服务器接收到数据时都会重置该计数器。如果计数器达到 60 秒(即我们在 60 秒内没有收到服务器的消息),它会执行一些预期的操作来应对连接丢失。

但是,客户遇到了一个问题,有时连接会丢失,但客户没有执行预期的操作。经调查,这似乎是由客户端到服务器的套接字引起的间歇性问题,有时在连接丢失时会引发错误 10057 (WSAENOTCONN / "Socket is not connected")。由于客户端在收到套接字错误时的行为不同,因此客户在收到此套接字错误时不会获得所需的行为。这对我来说并不难解决,但我对不同的行为有点困惑。

为了重现该问题,我将网络电缆从服务器机器的背面拉出。大多数时候,对客户端的影响是我们没有通过套接字获得任何数据,也没有收到错误。但有时会出现错误 10057。谁能解释为什么会出现这种不一致?客户端套接字是一个非阻塞的 STREAM 套接字。

【问题讨论】:

    标签: sockets winsock


    【解决方案1】:

    我希望您只有在尝试发送某些内容时才会收到错误消息。那就是 TCP 连接会发现它无法到达另一个端点的时候。这将花费不同的时间来发现故障,具体取决于网络往返时间。可能有一个“保持活动状态”选项,它强制套接字定期发送一些东西以检测故障,即使应用程序处于空闲状态。

    【讨论】:

    • 你是对的:当我们在尚未连接的套接字上执行“发送”时会发生错误。客户使用调用“连接”的第 3 方套接字包装类,但随后在获得 WSAAsyncSelect 回调之前将内部标志设置为“已连接” - 所以我们真的不知道我们是否已经连接。有人没有意识到这种细微差别,并在第三方套接字类中使用“已连接”来表示套接字实际上已连接。在我们下一次发送之前,有一点竞争条件来查看套接字是否连接。在仍未连接的地方,发送会导致 10057 错误。
    • 您可以从大多数 Winsock API 中获取 WSAENOTCONN,而不仅仅是 send()。
    • @EJP,是的,任何 API 都可能发出错误信号,但只有在 TCP 尝试发送某些东西时才能发现非连接状态,无论是应用程序数据还是内部生成的保持活动状态。
    【解决方案2】:

    WSAENOTCONN 是您的应用程序中的错误。这不是连接丢失的结果。连接丢失的结果是WSAECONNRESET. 您的代码必须得到WSAECONNRESET,,然后继续使用连接,就好像它仍然有效一样。 然后你得到WSAENOTCONN.

    【讨论】:

    • 谢谢,正如你所说,这是应用程序中的一个错误 - 请参阅下面我对 user1055568 的评论。我实际上并没有得到 WSAECONNRESET,但看起来我们只是在未连接的套接字上执行“发送”。
    猜你喜欢
    • 1970-01-01
    • 2014-10-29
    • 1970-01-01
    • 2011-01-05
    • 2015-08-02
    • 2019-06-03
    • 2019-09-04
    • 2020-06-27
    • 2013-03-18
    相关资源
    最近更新 更多