TCP数据包在网络级别合并

时间:2012-06-28 09:11:52

标签: java networking tcp tcpdump

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

答案 0 :(得分:4)

TCP是基于流的协议。它不会保留send / recv次调用的边界。唯一保证的是send的连接将与​​recv的连接相同(在正常情况下)。

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

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

答案 1 :(得分:3)

在许多地方可以进行合并

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

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

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

  

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

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