3

有谁知道对方如何以及为什么会收到合并的 TCP 数据包而不是单独的数据包?我已经在套接字级别将 TCP Nodelay 设置为 true,但 tcpdump 仍然看到一些数据包已合并。在成功发送 4 个大小为 310 字节的数据包后,我得到了 3 x 1400 字节而不是 15 x 310 字节。这导致了一些重要的延迟。谢谢。

http://www.2shared.com/photo/_bN9UEqR/tcpdump2.html

s = new Socket(host, port);
s.setTcpNoDelay(true);
s.getOutputStream().write(byteMsg); 
s.getOutputStream().flush()
4

4 回答 4

5

TCP 是一种基于流的协议。它不保留send/recv调用的边界。唯一保证的是 's 的串联send将与 's 的串联相同recv(在正常情况下)。

如果您正在实现自定义协议并且需要某种方式将数据拆分为多个逻辑消息,则需要为此进行编码。

一个简单的编码是将每条消息编码为一个 32 位无符号整数,表示消息有效负载的长度,然后是实际的消息有效负载。然后,在接收端,根据此编码正确解码输入。为此,您将需要一个缓冲区来存储部分接收到的消息。如果处理原始整数有问题,您可以用其他方式对长度进行编码,例如作为十进制数字后跟换行符。

于 2012-06-28T10:25:34.763 回答
3

合并可以在许多地方发生

  • 发件人应用程序缓冲
  • 发件人操作系统缓冲
  • 发送方网络适配器缓冲区
  • 路由器缓冲区
  • 接收器网络适配器缓冲区
  • 接收器操作系统缓冲
  • 接收器应用程序缓冲区/队列

从您所说的看来,发送者网络适配器和接收者的操作系统之间存在合并。(因为 tcp-no-delay 指示操作系统不要在应用程序之前缓冲和 tcpdump 读取)

于 2012-06-28T09:19:38.360 回答
1

您可以尝试在使用的套接字上启用 TCP_NODELAY 选项(setTcpNoDelay()方法)。

默认情况下它是禁用的,这意味着传输的数据针对发送的最小数量的包进行了优化(请参阅Nagle 的算法)。

于 2012-06-28T09:40:54.557 回答
0

有谁知道对方如何以及为什么会收到合并的 TCP 包而不是单独的包?

因为那是 TCP 专门设计的。

于 2012-06-28T10:59:00.460 回答