网络基础 — 浅析IP/TCP协议分片

时间:2022-11-28 10:29:13

浅析IP/TCP协议分片






首先我们需要知道一个概念,MTU是链路层中的网络对数据帧的一个限制,以以太网为例,MTU为1500个字节. 一个IP数据报在以太网中传输,如果它

长度大于该MTU值,就要进行分片传输,使得每片数据报的长度小于MTU. 分片传输的P数据报不一定按序到达,但IP首部中的信息能让这些数据报

片按 序组装. IP数据报的分片与重组是在网络层中进行完成的.


我们所熟知的应用层程序之间进行网络数据传输时,在发送端,数据会从应用层沿着协议栈向下传输,通过TCP/IP层,然后经由链路层发送出去,

而在接收端,则是相反的顺序,数据经由链路层接受,然后沿着协议栈向上传输,通过IP/TCP层,最后由应用程序进行读取.  而在IP层往链路层传

输数据的时候,如果数据大小大于等于我们的MTU时, 通常会在IP层进行一个分片操作. 而我们的TCP的数据报! 他们需要尽量避免在IP层被分片.

因为如果在IP层进行分片的话,如果其中的某片的数据丢失了,对于保证可靠性的TCP协议来说会增大数据报重传的概 率. 而且你会重传整个TCP分

组,因为TCP层是不知道IP层进行分片的细节的,它也不关心.


网络基础 — 浅析IP/TCP协议分片

当TCP层进行TCP分组的重传时,还会直接影响到应用程序的性能,特别是在应用程序使用阻塞IO进行读写的时候. 在我们的应用层程序中,我们可

以有自己的发送缓冲区,而TCP层本身也有自己的一个发送缓冲区. 当我们在应用层往TCP层当中写数据的时候,实际上是将应用层发送缓冲区的数

据拷贝至TCP层的发送缓冲区中. 当TCP层的发送缓冲区满或者网络空闲的时候,TCP层就会将其缓冲区中的数据通过IP层传到链路层的发送队列中.

如果TCP的发送缓冲区满并且应用层的数据没有写完时,内核会将write系统调用挂起,并不返回给应用程序,直到应用层的数据全部拷贝至TCP层

的缓冲区中. 而由于TCP层要保证数据包的可靠性,既数据包丢失时要进行重传,那么TCP层在往网络发送TCP分组后,需要在其发送缓冲区中暂时保

存发出的TCP分组数据用于后续可能的重传. 所以如果你的IP层对TCP的数据进行了分片,导致TCP数据丢失,那么缓冲区当中的数据无法及时清除,

因为他可能会重发. 那么就会有可能使得应用层程序一直在write系统调用处挂起等待,引起性能的下降.




TCP层避免数据被IP层分片所做的努力





首先我们回顾一下TCP建立连接的3次握手!

网络基础 — 浅析IP/TCP协议分片
其实呢 在这3次握手中,除了确认SYN之外,通信的两端还协商了一个值, MSS(最大分段大小)是TCP里的一个概念. MSS是TCP数据包每次能够传输的

最大数据分段,TCP报文段的长度大于MSS时,就需要进行分段传输. TCP协 在建立连接的时候通常要协商双方的MSS值,每一方都有用于通告它期望

接受的MSS选项(MSS选项只出现在SYN报文段中,既TCP三次握手的前两 次).  MSS的值 一般为MTU值减去两个首部大小所以如果用链路层以太网,MSS的

值往往为1460.而Internet上标准的MTU位   676,那么如果不设置,则 MSS的默 认值就为636个字节. 很多时候,MSS的值最好取512的倍数. TCP报文

段的分段与重组是在运输层完成的.


到了这里有一个问题自然就非常明了了,TCP分段的原因是MSS,IP分片的原因是MTU,由于一直有MSS<=MTU,很 明显,分段后每一段TCP报文段TCP

段再加上IP首部后的的长度不可能超过MTU,因此也就不需要再网络层进行IP分片了,因此TCP报文段很少会 发生IP分片的情况.

再来看UDP数据 报,由 于UDP数据报不需要保证可靠性,所以他不用保存发送的数据包,由于IP层本身也没有缓冲区,数据就会直接写到链路层的输

出队列中,在这种情况中,IP层会不会对来自UDP的数据进行分片,这个取决于UDP的大小和MTU的比较,如果大于MTU,IP对数据报就会分片,如果小

于MTU,IP层直接加上IP头部发送到链路层的输出队列中



MSS(最大分段大小)是TCP里的一个概念. MSS是TCP数据包每次能够传输的最大数据分段,TCP报文段的长度大于MSS时,就需要进行分段传输. TCP协

在建立连接的时候通常要协商双方的MSS值,每一方都有用于通告它期望接受的MSS选项(MSS选项只出现在SYN报文段中,既TCP三次握手的前两

次).  MSS的值 一般为MTU值减去两个首部大小所以如果用链路层以太网,MSS的值往往为1460.而Internet上标准的MTU位   676,那么如果不设置,则

MSS的默 认值就为636个字节. 很多时候,MSS的值最好取512的倍数. TCP报文段的分段与重组是在运输层完成的.

到了这里有一个问题自然就非常明了了,TCP分段的原因是MSS,IP分片的原因是MTU,由于一直有MSS<=MTU,很明显,分段后每一段TCP报文段TCP报

段再加上IP首部后的的长度不可能超过MTU,因此也就不需要再网络层进行IP分片了,因此TCP报文段很少会发生IP分片的情况.再来看UDP数据

报,由 于UDP数据报不会自己进行分段,因此当长度超过了MTU时,会在网络层进行IP分片. 同样的,ICMP同样会出现IP分片情况 再来看UDP数据报,

由于 UDP数据报不会自己进行分段,因此当长度超过了MTU时,会在网络层进行IP分片,同样的,ICMP同样会出现IP分片的情况.