为什么 iperf3 或 TCP 堆栈会合并 TCP 数据包?

为什么 iperf3 或 TCP 堆栈会合并 TCP 数据包?

使用这个简单的命令:

iperf3 -c localhost --time 1 -l 100 --bitrate 100M

然后使用以下命令观察输出:

sudo tcpdump -i lo -B 10000000 tcp port 5201

我期望看到大量 100 字节的数据包通过线路传输,但是我看到的却是如下内容(过滤掉 ACK 数据包等):

05:40:18.722627 IP [...]: Flags [P.], seq 12447838:12449238, ack 1, win 64240, options [...], length 1400
05:40:18.722644 IP [...]: Flags [P.], seq 12450738:12450838, ack 1, win 64240, options [...], length 100
05:40:18.722655 IP [...]: Flags [P.], seq 12450838:12452038, ack 1, win 64240, options [...], length 1200
05:40:18.723647 IP [...]: Flags [P.], seq 12452038:12452138, ack 1, win 64240, options [...], length 100

我们有两个符合预期的 100 字节数据包,但还有另外两个数据包,其中 14 和 12 条消息已被批处理。为什么要进行批处理,在 Ubuntu 22.04 上有没有办法关闭它?

(注意,日志缩写为适合屏幕上的长度而不滚动:第一个[...]localhost.43286 > localhost.5201,第二个是[nop,nop,TS val 838423036 ecr 838423036]。)

答案1

1500 字节是常见的最大传输单元大小。这就是为什么您会看到该大小的数据包。

此 iperf 问题提到讨论了-l https://github.com/esnet/iperf/issues/1094

TCP 协议是面向字节流的...它不保留发送的消息的大小。因此,如果您使用 -l 参数,它将控制 iperf3 发送的消息的大小,但 TCP 可能会将多个发送合并为一个更大的数据包,或者它可能将一个大发送拆分为多个较小的数据包。通常,TCP 会尝试在网络上发送其可以发送的最大数据包。

您可以尝试使用 -M 标志来告诉 TCP 不要发送大于给定大小的数据包,尽管使用此选项的一些先前经验表明它是不可靠的。

相关内容