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

标签 c linux sockets tcp

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

  1. 客户端告诉服务器保存一些数据(即写请求)。该请求由 4KB 的数据和少量附加字节的元数据(2xunsigned long + 1xint)组成。 Ther server 保存数据并且不响应写入请求。
  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。但这些都没有解决问题。

最佳答案

Why do a socket reads more data than what is actually sent?

事实并非如此。它会读取任何可用的数据,并在必要时在没有数据时进行阻塞。

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

关于c - 为什么套接字读取的数据多于实际发送的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18891005/

相关文章:

java - Android 应用程序(客户端)可以使用套接字与 Java Web 服务器通信吗?

linux - 来自/proc 的可能的内部套接字状态列表

c++ - 使用 GCC 进行原子 64 位写入

java - Tesseract 3.02.02 崩溃 JRE

c - c 中 malloc() 和 free() 的正确使用

在 C 中创建字符串值并将其添加到二维数组

c - TCP 100% 可靠吗?

c++ - 编译器是否有用 C++ 中的推断类型替换 auto 的功能?

linux - 在日志文件中报告状态 crontab 行 Linux RedHat

Python socket 客户端 Post 参数