为什么套接字读取的数据比实际发送的数据多?

我有一个客户端和一个服务器都写在C和运行在Linux上。 客户端请求数据段并将相似的数据段发送到服务器。 以下是客户端和服务器之间的典型交互。

  1. 客户端通知服务器保存一些数据(即写入请求)。 该请求由4KB数据和less量附加字节的元数据组成(2xunsigned long + 1xint)。 Ther服务器保存数据,不响应写请求。
  2. 客户端从服务器请求数据(即读取请求)。 请求是由几个元数据字节组成(再次… 2xunsigned长+ 1xint)。 服务器仅响应4KB数据段。

服务器端的跟踪显示它总是发送4KB的数据段。 然而,在客户端的踪迹显示了不同的故事:不同大小的包。 如果客户端收到的数据大小不是4KB,那么下面的数据包总计为4KB或8KB。

为了说明这个错误的模式,我在跟踪中看到了一些例子:

  • 4KB,1200字节,2896字节,4KB。
  • 4KB,1448字节,6744字节,4KB。

我可以在应用程序级别处理第一个场景(即1200B + 2896B),等待一个完整的4KB段被读取,但我不知道如何处理另一个场景。 但是,我宁愿避免整个问题,并强制客户端/服务器接收4KB的完整数据段。

我已经尝试禁用Naglealgorithm( TCP_NODELAY )并将MTU大小设置为4KB。 但是其中一个解决了这个问题。

为什么套接字读取的数据比实际发送的数据多?

它不。 它读取任何可用的数据,如果有必要的话,在没有数据的情况下阻塞。

你的问题是建立在一个谬论上的。 在TCP协议规范或伯克利套接字API中没有任何地方保证只读一个==写。 TCP是一个字节流协议。 如果有更多的数据到达,比预期的要多,并且提供给recv()或read()方法的缓冲区中有足够的空间,则会得到它。 如果你想要消息边界,那么你就可以严格执行它们。