1,引入
在Linux下,我们使用ifconfig命令可以看到网络接口的MTU值,一般是1500,而且我们可以通过命令修改该MTU值,最近做了一些网络接口的编程,对遇到的一些疑问做个记录。
2,MTU 与MSS
MTU: 在数据链路层中,指网络链路中能传输的最大数据包大小,通常是1500,
为啥是1500?
原来: 早期的以太网使用共享链路的工作方式,为了保证CSMA/CD(载波多路复用/冲突检测)机制,所以规定了以太帧长度最小为64字节,最大为1518字节。 最小64字节是为了保证最极端的冲突能被检测到,64字节是能被检测到的最小值;最大不超过1518字节是为了防止过长的帧传输时间过长而占用共享链路太长时间导致其他业务阻塞,
讲人话就是:1500是共享链路传递数据的效率和延迟的最优解,这里为什么出现了1518,解释一下:
因为在链路层中也是存在封包的,其会在1500的基础上增加(目的mac和源mac地址 (12 Byte)+ 2byte 的类型 + 4Byte 校验和)

使用总结一下:
1518 Byte 是数据 链路层最大的数据报长,我们叫帧,而1500是数据链路层提供给上层的最大数据长度,即:网络层数据最大长度是1500.
MSS:指的是传输层TCP协议中一个连接允许的最大数据段大小,单位字节,不包括TCP头部,一般有:MSS = MTU - 20Byte IP头 - 20Byte TCP头。
当我们从应用层调用网络函数时(write、send等),当我们的数据量不超过1460时,网络层收到的数据将不会被分片,如果超过这个值将导致分片的产生。但是不用担心网络层已经帮我们实现了包的分片和重组。
值得注意的是:
当我们调用read/recv等函数时,不论TCP/UDP协议,我们都无法获取分片的数据报,我们只能获取到网络层已经重组完成的数据报,所以你想通过多次recv在应用层重组数据报就不现实。
综上: 1460 是TCP 协议的避免数据分片的最大长度,而我们知道UDP 头占8字节,所以1472是UDP协议避免分片的最大长度。
补充: 相信大家也见过或听过1492这个值,这个是PPPOE协议链路层封装后提供给上层的最大数据长度,如下: 其中的PPPOE字段占8 Byte.

3,总结
本文简单介绍了LINUX下MTU 和MSS,对平常疑惑的一些数据值做了解释,帮助理解和记忆,