TCP MTU 问题

做网络编程的时候大家可能会注意UDP分包的问题,当单个数据包大于MTU的时候,就会出现分包的情况,当UDP包不是纯数据(UDP包一般都会有自定义的包头)的时候,这种分包是破坏性的,所以一般UDP我们都不会让他超过1000字节,甚至更小

但是大家往往会忽略TCP其实也受MTU的限制,在某些情况下当用TCP发送数据包(不是数据流)的时候,忽略了这个问题,也是会出现意象不到的问题

1.从以太网帧说起

以太网 Ethernet 最大的数据帧是 1518字节 。 以太网帧的帧头 14字节和帧尾CRC校验4字节 (共占 18字节 ),剩下承载上层协议的地方也就是Data域最大就只剩1500字节. 这个值我们就把它称之为MTU。

cat /sys/class/net/eth0/mtu
1500

2.去掉IP包头和TCP包头

单个TCP包 实际传输的最大值:
1500- 20(IP头 )-32(20字节 TCP头和12字节TCP选项时间戳 ) = 1448 字节

3.大于这个值会发生什么

大于1448的数据包会被拆成多份发送,接收端收到的就不会是一完整的包,数据解析出来就会出错,
有的人把这个理解为TCP粘包,但这明显是分包了嘛,TCP粘包应该是另一个概念

4. 为什么我在本机测试没问题

IP层 非常关心MTU,因为 IP层 会根据MTU来决定是否把上层传下来的数据进行分片。就像一条运输线路的承载能力是有限的,碰到大东西要运输,只能把大东西拆开成为散件,分开运输,到达目的地之后还必须能再次 组装起来。
但你在本机上测试,会发生什么

 cat /sys/class/net/lo/mtu
 65536

知道为什么你自己测可以,放到服务器上就不行了吧

5.怎么办

有一些人会给出你建议:
改写read,write,
改成所谓 readall,writeall,但是你怎么知道接收的数据一定会有多长
可靠一点的做法,每个TCP包都不要超过1448字节?
喔,可能会粘包了,麻烦呀。。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章