1

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

  1. 客户端告诉服务器保存一些数据(即写请求)。该请求由 4KB 的数据和几个额外的元数据字节组成(2xunsigned long + 1xint)。服务器保存数据并且不响应写入请求。
  2. 客户端向服务器请求数据(即读取请求)。该请求由几个字节的元数据组成(再次... 2xunsigned long + 1xint)。服务器只响应一个 4KB 的数据段。

服务器端的跟踪显示它总是发送 4KB 的数据段。但是,客户端的跟踪显示了一个不同的故事:不同大小的数据包。如果在某一时刻客户端接收到大小不是 4KB 的数据,则以下数据包加起来为 4KB 或 8KB。

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

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

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

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

4

1 回答 1

2

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

它没有。它读取任何可用的数据,必要时在没有数据的情况下进行阻塞。

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

于 2013-09-19T09:52:43.850 回答