TCP数据包在网络级合并

有人知道对方是如何以及为什么会收到合并的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() 

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

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

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

聚结可以在许多地方发生

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

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

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

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

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

因为这是TCP专门设计的目的。