为何能发送超过WiFi接口MTU的UDP数据包?
为何能发送超过WiFi接口MTU的UDP数据包?
嗨,这个问题问得特别到位!其实背后是IP分片机制在默默工作,咱们一步步把这个事儿说清楚:
先搞懂MTU到底管啥:MTU是单个链路层帧能装下的最大IP数据报大小(不含链路层自己的头部)。你的WiFi接口MTU是1500,意思是单个以太网帧最多能塞1500字节的IP数据(包含IP头、UDP头和UDP内容)。但这只是链路层的限制,IP层有办法绕开它。
当你发送的UDP包加上IP头的总大小超过MTU时,IP层会自动把这个大的IP数据报拆分成多个小分片,每个分片都刚好适配MTU的大小。比如你发的65500字节UDP数据,加上20字节IP头和8字节UDP头,总共有65528字节。IP层会把它拆成大概44个分片(每个分片除了最后一个,都能装1480字节的UDP数据——1500-20=1480,减去IP头的大小)。
这些分片会各自打包成独立的以太网帧发送出去,等它们都到达目标服务器后,服务器的IP层会把这些分片重新拼接成完整的UDP数据包,所以你能收到完整的消息。
如果你去Wireshark里仔细看,能找到这些分片的痕迹:每个分片的IP头里有**分片偏移(Fragment Offset)**字段,还有MF(More Fragments)标记——除了最后一个分片,其他分片的MF标记都是1,用来告诉接收方“后面还有分片哦”。你可以用过滤规则
ip.fragment快速找到这些分片。
另外还要提醒你几个注意点:
- 虽然IP分片能让大UDP包成功发送,但它有个明显的弊端:只要任何一个分片丢失,整个UDP包就没法组装完成,而且UDP本身没有重传机制,这就意味着整个包直接丢了。所以大UDP包的丢包风险会比小包高很多。
- 有些网络设备(比如部分路由器)会启用“不分片”(DF位,Don't Fragment)的设置,这时候如果你的UDP包超过MTU,就会收到ICMP错误(目标不可达,需要分片但DF位已设置),导致发送失败。你的代码里没设置DF位,所以IP层默认就帮你分片了。
备注:内容来源于stack exchange,提问作者Akash Karnatak
相关产品推荐
相关产品推荐

