
前言:在网络通信中,当IP层需要传输的数据包大小超过数据链路层的MTU限制时,就必须进行分片处理。本文将完整解析IP分片的工作机制,包括分片字段的作用、如何减少分片,以及分片报文的组装原理。 IP报头解析请参考:子网划分核心原理 (网络原理1)-CSDN博客
在上一期的IP报头解析文章中,我们遗留了几个关键字段未作详述,即16位标识符、3位标志位以及13位片偏移量。这些字段实际上与IP分片和组装机制紧密相关,本章将对此展开详尽讲解。

由于物理介质等因素的限制,数据链路层规定从上层接收下来的完整报文大小不超过MTU(最大的传送单元),标准通常是1500字节。就像寄包裹时不能超过1kg,需要我们分成小块寄。
如果从IP层传下来的超过MTU就需要分片发送。到了对端IP层会再进行组装。
分片并不是一件好事,分片会增加丢包率——任意一个分片丢失都会导致整个报文失效。举个例子,假设报文的丢包率为1%,而一个报文被分成10份。要保证每一个报文都收到,才算不丢包,那么丢包率就变为1-99%^10,最后丢包率变为10%左右。
所以分片和组装不是主流,是被迫为之,不是“原罪”。既然分片有显著弊端,如何减少?关键在哪一层控制?

为什么说IP分片是被迫为之,传输层并不关心报文大小,只管将数据传给网络层,最终必须交付给对端传输层。而数据链路层的标准是不能超过1500字节,那么网络层夹在中间就很为难,需要自己解决这个问题,所以有了分片技术,在IP层分片交付到对端IP层在进行组装。分片技术的分与组均由网络层独立完成,与其他层解耦。
所以要减少分片,即IP层的工作。那么就要从数据链路层的下手。
怎么控制传输层数据量减少分片?MTU为1500字节,去掉IP报头20字节,那么从传输层传输下来的报文就要控制在1480字节以下。去掉传输层报头20字节,那么从发送缓存区取的报文就要控制在1460字节(称为MSS 最大段尺寸)以下。
而数据发送多少又跟滑动窗口有关。滑动窗口里面的数据是分段发送的,而不是大块数据一次性发送,就是在控制数据发送量减少分片。
关于滑动窗口讲解:TCP协议可靠性设计的核心机制与底层逻辑-CSDN博客
MTU除了上限也有下限,最小不能低于46字节。数据不仅在发的时候受MTU限制,收的时候也应该受MTU限制,而收到数据的大小是对端发多少决定的,需要由对端控制,所以在两个主机进行通信前,三次握手时会进行MSS协商。 怎么协商?在TCP报头里设置选项,然后以两端MSS较小值作为标准。
MTU为什么有下限? 数据帧碰撞。局域网就是碰撞域,一个时刻只能发一个数据帧。以太网被所有主机共享,是共享资源(临界资源)。所以使用以太网时间越短越好(冲突概率越低)。数据报量大占用时间太长。把它分成小量多份,但份多也会占用时间太长。 所以MTU不能它大也不能它小,控制在[46,1500]范围。至于为什么是这个范围我们无需关心,也许是硬件工程师做大量测试总结出来的。
本质:硬件影响软件。数据帧->MTU->滑动窗口->MSS
接下来讲解分片是如何组装的,理解如何组装,如何分片自然就能理解。
首先需要甄别出是否是分片报文?
看3位标志的第三位,如果是1,那么它100%是分片报文。如果是0我们还不能确定,需要继续看13位片偏移,如果不为0则就是分片报文(而且是最后一片)。对立的,如果3位标第3位为0,且13位片偏移为0则不是分片报文。
确定它是分片报文后,通过16位标识把它分类(相同报文的放在一起)。
怎么判断分片报文是否已经收全了?(或是否有丢失?)
划分为三种情况检测,第一片,中间片,最后一片。
如何组装?
非常感谢您能耐心读完这篇文章。倘若您从中有所收获,还望多多支持呀!