c++ - 在没有 SO_LINGER > 0 的情况下强制关闭服务器端套接字会丢失数据,对吗?

标签 c++ linux windows sockets

我正在编写一个使用套接字的跨平台客户端应用程序,该应用程序是用 C++ 编写的。当服务器向我发送信息后,它正在硬关闭套接字,我遇到了问题。

我一直在阅读关于这个主题的其他帖子,我对这种方法的正确与错误不太感兴趣,但服务器似乎明确设置了 SO_LINGER=0,或者这是默认行为那个系统(不确定,它是一个 Linux 机器)。

我可以看到(在 Wireshark 中)数据发送给我后在几毫秒内通过 RST,表明服务器硬关闭。我个人不同意这种方法,因为它应该由客户端关闭套接字。

服务器团队表示这种方法没有任何问题(硬关闭而不是关机),这是服务器上避免累积 TIMED_WAIT 套接字的典型做法。在 Windows 上,我的 select() 返回指示有内容要读取(虽然我还没有读取任何此“传输中”数据)。

但是,由于 RST 的快速到达,在 Windows 上 recv() 返回 -1,我看到错误代码为 10054(连接被对等方重置)。如果我至少可以获得发送的数据,这还不算太糟糕,但似乎一旦我的客户端的套接字堆栈看到 RST,我就不再可以使用任何未读字节。

在 Linux(客户端)上,没有问题。似乎 TCP 堆栈的行为略有不同,因为我可以在 RST 兑现之前读取未完成的字节。鉴于它适用于 Linux 客户端,我很难说服服务器人员他们有一个错误。

首先,我是对的吗?这是服务器端问题吗?看不出客户端有什么不对,就一定是对的吧?

似乎服务器团队坚持要执行关闭,他们不想有 TIMED_WAITs,所以我打算插入他们添加一个 SO_LINGER,比如 2 秒?这听起来能解决我的问题吗?据我了解,这将阻止服务器在发送数据后很快发送 RST,并且应该让我有机会读取未完成的字节。

最佳答案

找到了我自己问题的明确答案:

“...收到 RST 段后,接收方将立即中止连接。此声明的含义不仅仅是意味着您将无法从该连接接收或发送更多数据。< strong>这也意味着任何仍在 TCP 接收缓冲区中的未读数据都将丢失......”它引用了“TCP/IP Internetworking Volume II”一书。我没有那本书,所以我只能相信他的话。在 Linux 上似乎不会丢弃数据,只有 Windows...

Olivier Langlois's blog

关于c++ - 在没有 SO_LINGER > 0 的情况下强制关闭服务器端套接字会丢失数据,对吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13543126/

相关文章:

c++ - 将 Glade 与 CUDA 编译器 (Nvidia Eclipse Nsight) 结合使用 -> 哪个 NVCC 链接器设置?

c - 带有 GUI 的内存 View

c - 当 sig 0 发送到 TARGET REAL UID == CURRENT EFFECTIVE UID 的进程时,kill 的返回值是多少?

c++ - 这是什么意思?这是关于c++中的DWORD变量

windows - bcdedit 错误 : "The parameter is incorrect"

c++ - 在C++编译器中编译C程序

c++ - 嵌套名称说明符中命名的不完整类型

linux - 如何在 bash 中计算 arccos()?

Django 错误 (13, 'Permission denied')

c++ - C++远程读取文件