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

时间:2013-09-19 09:29:07

标签: c linux sockets tcp

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

  1. 客户端告诉服务器保存一些数据(即写请求)。该请求由4KB数据和少量额外字节的元数据组成(2xunsigned long + 1xint)。 Ther服务器保存数据,不响应写请求。
  2. 客户端从服务器请求数据(即读取请求)。该请求由少量字节的元数据组成(同样...... 2xunsigned long + 1xint)。服务器仅响应4KB数据段。
  3. 服务器端的跟踪显示它始终发送4KB数据段。但是,客户端的跟踪显示了不同的故事:不同大小的数据包。如果客户端在某一时刻收到大小超过4KB的数据,那么以下数据包将加起来为4KB或8KB。

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

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

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

    我已经尝试禁用Nagle算法(TCP_NODELAY)并将MTU大小设置为4KB。但其中任何一个都没有解决这个问题。

1 个答案:

答案 0 :(得分:2)

  

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

没有。它会读取所有可用的数据,如有必要则在没有数据时进行阻塞。

你的问题是建立在一个谬误的基础上的。 TCP协议规范或Berkeley套接字API中的任何地方都无法保证读取==一次写入。 TCP是字节流协议。如果到达的数据超出了您的预期,并且您提供给recv()或read()方法的缓冲区中有足够的空间,您将获得它。如果您想要消息边界,则完全由您来实现它们。