TCP分组、IP分组、MTU、MSS
什么是MTU
最大传输单元(Maximum Transmission Unit, MTU) ,一般是指数据链路层所能够通过的最大数据包大小(以字节位单位,不包括链路层的首部与尾部),这个一般与通信接口(网卡、串口)等有关。假设两台路由器之间的MTU之间为1500,那么这两个路由器在数据链路层单次传输的数据包大小最大为1500字节,也就是规定了IP数据报的长度。
|帧首部| 帧的数据部分 |帧尾部|
|---------MTU--------|
路径MTU
上面说了MTU是指两台路由器之间在数据链路层单次传输的最大数据包大小。但是在互联网之中,一个数据包不仅仅是两个终端之间的通信,而是需要经过多个路由器转发后才能到目标终端,那在这条链路上所经过的IP跳的最小MTU就是这个路径MTU。
链路:terminal --MTU=1500--> router1 --MTU=900--> router2 --MTU=1200--> router3 --MTU=1880--> terminal
## 该链路的路径MTU就是900
IP分组
数据链路层的单个数据包的大小为MTU,那IP层的数据很容易会比MTU大,那此时IP层就需要对数据进行分组发送,到达目的地之后再按照分组编号对分组进行重组,形成完成的数据报文。以IPV4为例,由于MTU是包含20字节的IP报文首部的,所以每个IP分组中,数据部分最大是**(MTU-20)**字节。而IPV6的IP报文首部的大小为40字节。
|--------------------MTU--------------------|
|IP首部|---------------分组数据---------------|
|20字节|-------------(MTU-20)字节-----------|
前面也提到在一个链路上会经过很多的路由器,其中最小MTU为路径MTU。以IPv4为例当terminal根据当前链路MTU=1500进行IP分片时,经过router1与router2,router1默认会把当前的IP数据报按照MTU=900进行再次分片,以适合当前整个链路的通讯。但是也可以通过IPv4数据报的DF位进行设置,当关闭再次分组时,数据报不能够到达目的终端并提示“目的地不可达,需分片但DF位已设置”。IPv6默认不执行分片,但隐藏一个DF位,如果数据报超出链路MTU的大小则会提示“分组太大”。
TCP分组
TCP有一个MSS(maximum segment size,最大分节大小),用于向对端通告每个分节中能够发送的最大TCP数据量。__MSS的目的是为了告诉对端其重组缓冲区大小的实际值,从而试图避免分片。__重组缓冲区的实际值由 MSS 间接指定,以IPv4为例,如果 MSS 为700字节,则重组缓冲区的实际值就是 MSS + TCP 头部 (20字节)+ IP 头部(20字节),即740字节,也就是一个最大的 IP 数据报的大小。但是如果对端未通告 MSS,则认为对端只支持最小重组缓冲区,因此默认 MSS 为536字节(IPv4 最小重组缓冲区大小576字节减去 TCP 和 IPv4 头部)。一般重组缓冲区的大小和 MTU 是相等的。
|--IP首部--|--TCP首部--|------------TCP segment Data(MSS大小)--------------|
|-------------------------------(MTU)------------------------------------|
|------------------------------重组缓冲区 ----------------------------------|
当TCP在传输层对数据进行切分,根据MSS划分每一个分节,这样在经过IP层时,就不需要IP层对传输层的数据报进行分组,也就是说TCP是具有分组能力的。而UDP的首部只有8字节,并且没有MSS选项,也就是说UDP是没有分组的能力的,当一个大于重组缓冲区的UDP数据报进行发送的时候,就会依靠IP分组的能力进行分组传输,然后当IP数据报全部到达之后再重组成完整的UDP数据报给传输层。
最小重组缓冲区(minimum reassembly buffer size)是 IPv4 和 IPv6 的任何实现都必须支持的最小数据报大小,其值对于 IPv4 为576字节,对于 IPv6 为1500字节。