4

我正在丢失套接字上的数据,因为我正在执行close().

Linux 特定的shutdown()联机帮助页没有帮助:

shutdown() 调用导致与 sockfd 关联的套接字上的全双工连接全部或部分关闭。如果 SHUT_RD 是多少,将不允许进一步的接收。如果 SHUT_WR 怎样,则不允许进一步传输。如果 SHUT_RDWR 怎么样,将不允许进一步的接收和传输。

微软的MSDN更好,但它是特定于 Windows 的,它与 Linux 之间存在差异:

为确保在连接的套接字关闭之前发送和接收所有数据,应用程序应在调用 closesocket 之前使用 shutdown 关闭连接。等待通知远程端已发送其所有数据并启动正常断开连接的一种方法使用 WSAEventSelect 函数,如下所示:

1. Call WSAEventSelect to register for FD_CLOSE notification.
2. Call shutdown with how=SD_SEND.
3. When FD_CLOSE received, call the recv or WSARecv until the function completes with success and indicates that zero bytes were received. If SOCKET_ERROR is returned, then the graceful disconnect is not possible.
4. Call closesocket.

我的问题

  • 在 Linux 下,什么相当于等待FD_CLOSE(步骤 1)?

我收到的答案和评论认为我在询问 Windows 上的行为。我问的是 Linux 上的行为,我只是参考Windows 文档,因为它比 Linux 联机帮助页更清晰和完整。

4

2 回答 2

5

在我对close() 没有正确关闭套接字的非常详细的回答中遵循了 MSDN 建议。这与Remy Lebeau 的回答基本相同。

于 2012-10-11T07:07:24.770 回答
3

请注意您引用的 Microsoft 文档如何使用WSAEventSelect. 这意味着它不是唯一的方法。相同的文档还描述了使用“重叠接收呼叫”的类似方法WSARecv()。然而,更常见(而非事件驱动)的方法是先调用shutdown(),然后recv()在循环中调用,直到它返回 0(正常断开连接)或SOCKET_ERROR(-1),然后再调用closesocket()

于 2012-10-10T22:04:46.843 回答