为什么TCP/IP包长会大于MTU?
为什么TCP/IP包长会大于MTU?
呵大官人 发表于3年前
为什么TCP/IP包长会大于MTU?
  • 发表于 3年前
  • 阅读 269
  • 收藏 2
  • 点赞 3
  • 评论 1

标题:腾讯云 新注册用户域名抢购1元起>>>   

前戏

当你看到这个标题第一眼到你看到这篇文章的内容期间,你心里也许会想,特么在逗我呢吧?TCP/IP包怎么可能会大于MTU?难道书上都是骗人的?确实在tcp/ip第一卷里面描述IP协议分片一节里面讲到,当IP包大于MTU时,会对包进行分片。既然会分片,那么这个包大于MTU是几个意思?且听我慢慢道来。

什么是MTU

MTU(Maximum Transmission Unit),即最大传输单元,意思是在网络通信协议里规定最大传输的字节数量,通常是1500字节(不同网络大小不一样,可使用ifconfig查看),最小是46。

起因

首先事情的起因是因为跟前端调数据,前端老吼没收到数据,我说发了,他说没收到,我说发了........双方难分胜负,唯有抓包,方能一决雌雄。说时迟那时快,抄起tcpdump就开干,然后在抓包过程中,偶尔有那么几个包居然比MTU还长,我当时就纳了闷了,说好的IP包分片呢?人与机器最基本的信任都没有了,我还打个卵的码啊。于是翻了一些资料,终于知道这个分片不是发生在IP协议上,而是在TCP协议上(其实主要还是不熟悉tcpdump,因为如果有tcp分片,seq格式就是当前seq:下一个seq,并且连续几个包的ack都一样)。包内容如下:


结果

虽然现在已经知道是tcp分片而非ip分片,但是包的大小还是超出了MTU,于是又一轮google,原来有个东西叫tso(tcp segment offload),意思是如果网卡支持tso,操作系统发送大的tcp包时,不需要消耗CPU来计算分片,而是将整个包发送到网卡,由网卡的NPU来进行分片处理,这样还能减少TCP头的传输次数(一个64K的数据包,需要45个分片,那么将多传输1760字节(40x44)的tcp头)。

查看你网卡是否支持tso,请使用如下命令:

ethtool --show-offload eth0

这时候我们来禁用一下tso,只需要执行如下命令

ethtool -K eth0 tso off

再来一轮tcpdump测试,发现数据包终于正常了,不再会大于MTU了。


其实无论服务器发送的包多大,反正最终都会被分片,可能是操作系统,可能是网卡,因此客户端收到的包都是小于MTU的。


分片

为什么ip有分片了,tcp还要再搞一个分片呢?因为ip层不保证数据成功送达,并且ip层分片可能发生在源主机,也可能在路由器上,一旦有分片丢失,将会造成整个ip包重传(其实这个重传是tcp层发起的,因为目标机器没有收到完整的ip包,也不会有ack,那么源机器在一定时间内就会发起重传,导致整个tcp包又被传了一次),因此就有了tcp分片,当一片数据丢失,只需要重传丢失的那一片即可。


结论

tcpdump抓包的数据是在包送到网卡之前的信息,所以在tcpdump里面的包大小可能会大于MTU,但是一旦数据进入网卡后的处理信息在tcpdump里面是反应不了的,因此数据包被分片这样的消息自然是没办法知道,只有在目标方才能反应出具体的分包细节。所以这次发现tcp/ip包长大于MTU其实算是个“假象”,因为在真正的链路层上传输数据时是不会大于MTU的。


参考资料

https://en.wikipedia.org/wiki/Large_segment_offload

标签: tso MTU TCP/IP
共有 人打赏支持
呵大官人
粉丝 110
博文 16
码字总数 14742
作品 1
评论 (1)
tuber
wen性能指南上提了一句tso,学习了
×
呵大官人
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: