UDP 数据报没有序列号,因此发送大量数据会导致数据报碎片化。例如,netcat 可以很容易地在 Linux 上用于生成 UDP 片段:
$ dd if=/dev/zero count=10 | nc 192.168.0.1 1234
使用 tcpdump,我们可以观察到数据报 id 的存在、增加的片段偏移量和“更多片段”标志:
# tcpdump -i eth0 -vvv udp and not port 53
00:41:35.449822 IP (tos 0x0, ttl 63, id 33788, offset 0, flags [+], proto UDP (17), length 1444)
192.168.0.2.38920 > 192.168.0.1.1234: UDP, bad length 5120 > 1416
00:41:35.449947 IP (tos 0x0, ttl 63, id 33788, offset 1424, flags [+], proto UDP (17), length 1444)
192.168.0.2 > 192.168.0.1: udp
00:41:35.449976 IP (tos 0x0, ttl 63, id 33788, offset 2848, flags [+], proto UDP (17), length 1444)
192.168.0.2 > 192.168.0.1: udp
00:41:35.450000 IP (tos 0x0, ttl 63, id 33788, offset 4272, flags [none], proto UDP (17), length 876)
192.168.0.2 > 192.168.0.1: udp
一些注意事项:
- 这不需要目标节点上的任何侦听器。
- 如果源和目标是同一台机器,它会产生不同的结果(似乎没有片段),例如定位
localhost。可能是因为我的lo 接口的 MTU 为 65536。
- TCP 数据报不被 netcat 分片,序列号用于在目的节点重组数据块。
我没有机会尝试 Windows 等价物,但它很可能也会产生碎片。鉴于这个问题无论如何是在十年前提出的,“Windows”限制可能不再重要了。