MTU
Maximum Transmission Unit,最大传输单元,指的是数据链路层的最大payload,由硬件网卡设置MTU,是一个硬性限制
留给网络层的数据长度(以太网的有效载荷:Payload)只有 [64 -18, 1518 - 18] = [46, 1500]
留给传输层数据只有:[46-20, 1500-20] = [26, 1480]
TCP 协议头占了 20 Byte, UDP 协议头占了 8 Byte(TCP 之所以协议头比 UDP 大,因它功能比较多:可靠、流速控制、自动分包等
TCP 可以传的用户数据实际上只有 [26 - 20, 1480 - 20] = [6, 1460]
UDP 没有协商的能力,所以它只能直接把用户发送的数据,传给网络层(IP层),由网络层来进行分片。用 UDP 协议发送,那么如果网络发生了波动,丢失了某个 IP 包分片, 对于 UDP 而言, 它没有反馈丢失了哪个分片给发送方的能力,这就意味着:50k 的数据全都丢失了,如果需要重传,就得再次完整的传递这 50k 的数据。UDP 协议头有 2 byte 表示长度的字段。所以实际 UDP 数据包的长度不能超过65507字节(65,535 − 8字节UDP报头 − 20字节IP头部)所以如果一个应用采用 UDP 来通讯,一般都会特意控制下单个包体的大小,从而提高传输效率。
TCP 是流数据,没有该限制,而 TCP 只会重传这一个丢失的分片包。
tcpdump可以看到分片的情况,udp header只出现在一个ip分片中。(第一个,后面是ip-proto-17)(icmp也是,后面是ip-proto-1,1/17是协议号)
拓展
- tcp/ip 协议栈Linux源码分析一 IPv4分片报文重组分析
Q&A
- tcpdump抓包是在tcp分片重组之前?看到的是很大的包
- 1500字节包含链路层的头部和尾部吗?——不包含。
- MTU里包含802.1Q的头部VLAN tag吗?——包含。当网卡配置VLAN tag时,VLAN tag + Data <= MTU,有时VLAN tag不只有一个,可能是双标签,那这个VLAN tag就是4Byte*2=8Byte。——MTU(1514) = 14 + 802.1Qvlantag(4)+IPHeader(20) + icmpHeader(8) + (ping -s 1472)
- 对于IP协议来说,IP包的大小由MTU决定(IP数据包长度就是MTU-28(包头长度)。 MTU值越大,封包就越大,理论上可增加传送速率,但 MTU值又不能设得太大,因为封包太大,传送时出现错误的机会大增。一般默认的设置,PPPoE连接的最高MTU值是1492, 而以太网 (Ethernet)的最高MTU值则是1500,而在Internet上,默认的MTU大小是576字节。
- 网络分片是在哪一层完成的?——网络层。网络层必须将发给网卡API的包 <= MTU。网络层如果发现链路层的MTU小于IP包的大小(网络层可以调用函数获取链路层信息),也并不会立刻开始分片,还需要看IP包的是否允许分片位DF(Don’t Fragment),如果允许分片,就会分成多个ID一样的IP包
- 对于TCP包(MTU = 1500),payload最大值是多少,才可以不用分片?——MTU(1500) = IPHeader(20) + TCPHeader(20) + Data,Data = 1500 -20 - 20 = 1100
- 对于ICMP request/reply包(MTU = 1500),payload最大值是多少,才可以不用分片?——MTU(1500) = IPHeader(20) + ICMPHeader(8) + Data,Data = 1500 -20 - 20 = 1472
- 对于UDP包(MTU = 1500),payload最大值是多少,才可以不用分片?——MTU(1500) = IPHeader(20) + UDPHeader(8) + Data,Data = 1500 -20 - 8 = 1472
- 用wireshark捕包。 为什么frame那一行是1514bytes?—— 以太网封装IP数据包的最大长度是1500字节,也就是说以太网最大帧长应该是以太网首部加上1500,再加上7字节的前导同步码和1字节的帧开始定界符,具体就是:7字节前导同步码+1字节帧开始定界符+6字节的目的MAC+6字节的源MAC+2字节的帧类型+1500+4字节的CRC校验。按照上述,最大帧应该是1526字节,但是实际上我们抓包得到的最大帧是1514字节,为什么不是1526字节呢?原因是当数据帧到达网卡时,在物理层上网卡要先去掉前导同步码和帧开始定界符,然后对帧进行CRC检验,如果帧校验和错,就丢弃此帧。如果校验和正确,就判断帧的目的硬件地址是否符合自己的接收条件(目的地址是自己的物理硬件地址、广播地址、可接收的多播硬件地址等),如果符合,就将帧交“设备驱动程序”做进一步处理。这时我们的抓包软件才能抓到数据,因此,抓包软件抓到的是去掉前导同步码、帧开始分界符、CRC校验之外的数据,其最大值是6+6+2+1500=1514。 同理,tcpdump抓包看到的最小帧长度=60B。以太网EthernetII规定,以太网帧数据域部分最小为46字节,也就是以太网帧最小是6+6+2+46+4=64。除去4个字节的FCS,因此,抓包时就是60字节。 当数据字段的长度小于46字节时,MAC子层就会在数据字段的后面填充以满足数据帧长不小于64字节。由于填充数据是由MAC子层负责,也就是设备驱动程序。不同的抓包程序和设备驱动程序所处的优先层次可能不同,抓包程序的优先级可能比设备驱动程序更高,也就是说,我们的抓包程序可能在设备驱动程序还没有填充不到64字节的帧的时候,抓包程序已经捕获了数据。因此不同的抓包工具抓到的数据帧的大小可能不同。对于TCP 的ACK确认帧的大小一个是54字节,一个是60字节,wireshark抓取时没有填充数据段,sniffer抓取时有填充数据段。具体格式如下:
Preamble | Destination MAC address | Source MAC address | Type/Length | User Data | Frame Check Sequence |
---|---|---|---|---|---|
8 | 6 | 6 | 2 | 46 - 1500 | 4 |
- 最小帧长度,性能测试,数据以server端收到的为主(指标pps以最小包发包)
UDP:
[root@network ~]# iperf3 -c 30.0.1.8 -u -t 1 -l 18 //<=18的,帧长度都为64B,区别是IP