UDP中的MTU是65535,但以太网不允许超过1500字节的帧大小

我正在使用100 Mbps的快速以太网,其帧大小小于1500字节(根据我的教科书,有效负载为1472字节)。 在这种情况下,我能够发送和接收消息大小为65507字节的UDP数据包,这意味着数据包的大小是65507 + 20(IP Header)+8(UDP Header)= 65535。

如果帧的有效负载大小本身最大为1472字节(按照我的教科书),那么IP的数据包大小如何大于65535?

我使用发件人代码

char buffer[100000]; for (int i = 1; i < 100000; i++) { int len = send (socket_id, buffer, i); printf("%d\n", len); } 

接收器代码如

 while (len = recv (socket_id, buffer, 100000)) { printf("%d\n". len); } 

我观察到sendi > 65507 returns -1recv打印或接收maximum of length 65507的数据包。

UDP数据报与MTU的大小没有多大关系,你可以让它们像上面提到的64K一样大。 只要您使用的大型数据报大小的巨型帧,您甚至可以在整个数据包中发送其中的一个。

然而巨型框架必须由框架将通过的所有设备支持,这是一个问题。 出于实际的目的,以太网帧是最常见的传输大小,这些MTU大约是1500字节,我会说1500向前,但并不总是。 当你创build一个大于底层MTU的UDP数据报时(它通常是以太网),那么它将被安静地分成1500个字节的帧。 如果你tcpdump这个stream量,你会看到一些数据包在MTU边界破碎,将有更多的片段标志设置以及一个片段号码。 第一个数据包的片段号为0,设置的片段越多,最后一个数据包的片段号将为非零,而没有设置更多的片段。

那为什么要关心? 实现细节实际上很重要。 碎片化可能会损害networking中的性能不再是一个大问题,而是一个需要注意的问题。 如果它使用了一个巨大的数据报大小,那么应该丢失任何一个碎片,整个数据报将需要重新发送。 同样在大量和今天这些都是完全可以达到的量,那么重新组装时帧的错误关联是可能的。 如果一个碎片在一个防火墙上,而另一个碎片在另一个防火墙上,那么在分布式UDP数据包穿越企业防火墙configuration(负载平衡器将数据包传播出去)时也会出现问题,那么stream量将会丢失为不完整。

因此,不要创build大于MTU大小碎片的UDP数据报,除非必须,并且必须指定正在通信的基础架构接近(相同的子网closures),在此点巨型帧可能是一个不错的select。

IP层将在发送端分割您的数据包,然后在接收端将其重新组装回去,然后再传递给UDP。 从UDP层,你不能真正知道数据包已被分割。 如果您使用像Wireshark这样的数据包捕获工具,则应该能够看到您的计算机正在接收限于MTU的IP数据包。

事实certificate,允许TCP / IP堆栈根据需要对数据包进行分段,比发送单个数据包要低得多。

要回答你的问题,“如果帧的有效载荷大小本身最大为1472字节(根据我的教科书),那么IP的数据包大小如何大于65535?”

这是由于卸载function称为UFO(UDP碎片卸载)。 请参考这个链接。

您可以分别通过ethtool -k ethX和ethtool -K ethXvalidation并切换卸载function。

如果您要监视传出帧,则可能是networking适配器支持分段卸载,并且已启用。 启用分段卸载function后,网卡本身会将数据包/帧分段为适当的大小,而不是networking堆栈。 这样可以释放计算机中的CPU执行其他任务,从而提高性能。 在linux上,“ethtool -k [device]”将显示卸载标志。