报文分片(16位分片标识、3位标志、13位片偏移字段详解)

目录

一、什么是分片?

二、如何分片?

三、如何组装?(16位分片标识、3位标志、13位片偏移)

1、回顾16位分片标识、3位标志、13位片偏移

2、组合分片报文

三、分片的风险

一、什么是分片?

网络层再继续向下传递的时候,会限制报文的大小,mtu(max transform unit)是最大传送单元,代表了每次所能传输报文的大小(含IP报头)。当我们的报文大小(含IP报头)超过了1500 个字节的时候,将一个报文分成多部份来传递,这就是“分片”。

报文分片(16位分片标识、3位标志、13位片偏移字段详解)_第1张图片

注意:分片不是大多数情况,而是特殊情况。本来传递一个报文就有着丢包的风险,现在要传递一堆报文,丢包的概率会增加。

二、如何分片?

假设 IP协议 收到上层的报文大小为 1700 字节。这1700字节在IP协议看来就是数据,不考虑选项字段,加上IP报头的20个字节,要向下传递的大小为1720个字节,很显然超出了传输限制。

报文分片(16位分片标识、3位标志、13位片偏移字段详解)_第2张图片

那么说明需要对这1700个字节进行分片,注意,是1700个字节分片,而不是1720个字节,先对数据进行分片,然后每一部分再加上报头。因为是分成多个报文来发送,每一个报文都要送到对端,那就必须加上报头来告诉下一层目标主机的IP地址。

报文分片(16位分片标识、3位标志、13位片偏移字段详解)_第3张图片

三、如何组装?(16位分片标识、3位标志、13位片偏移)

1、回顾16位分片标识、3位标志、13位片偏移

因为这些报文由一个完整的报文分片得到,不能随意组合。这就需要用到IP报头中的三个字段16位分片标识、3位标志、13位片偏移。

  • 13位片偏移:分片以后,各个部分在原始报文的哪个位置,即在原始报文中的偏移量。

  • 16位分片标识:如果一个报文不分片,不同报文之间的16位标识符是不同的;如果一个报文分片了,分片报文的16位标识符是一样的,说明这些分片报文原本属于一个完整的报文。

  • 3位标识:1位保留、1位标识禁止分片、1位标识更多报文(1说明后面跟了具有16位标志符的报文,0说明后面没有)

报文分片(16位分片标识、3位标志、13位片偏移字段详解)_第4张图片

 

2、组合分片报文

第一步,通过三位标识符的第三位标识“更多报文”判断当前收到的报文后面是否跟了同样的16位标识符的报文。

如果第三位标识为1,说明当前报文是分片报文,加入到具有相同16位标识符的集合中,进入下一步;如果为0,可能为普通报文,也有可能是分片报文的最后一部分,此时需要根据片偏移判断。

  • 如果片偏移为0,说明是普通报文,结束判断,直接向上层交付;
  • 如果不为0,说明是分片报文,加入到具有相同16位标识符的集合中

报文分片(16位分片标识、3位标志、13位片偏移字段详解)_第5张图片

第二步,判断所有的报文是否收全。将集合中的报文按照片偏移进行升序排序。

判断起始分片报文是否收到:如果第一个报文的片偏移为0,说明起始分片报文收到了。

判断末尾分片报文是否收到:如果最后一个报文的三位标志位中的第三位为0,说明末尾分片报文收到了

判断中间报文是否收到:以第二个报文为例,第二个报文的片偏移理应等于 第一个报文的片偏移 + 第一个报文的数据长度,以此来判断第二个报文是否收到;依此类推,可以判断中间报文是否收到。

=》该集合中一旦发现少了任意一个报文,整个集合中的报文直接全部丢弃!也不会通知上层TCP

三、分片的风险

分片有风险,只要有一部分丢了,如果对端网络层无法组装,要组装的几部分会全部丢弃,对方TCP没有收到报文,就认为是丢包了。所以一般不建议分片,分片会增加丢包概率。

但是如果不想分片,是TCP说了算,因为TCP有缓冲区的存在,想发多少、什么时候发都由TCP决定,而IP只是个跑腿的。UDP就不一样了,没有发送缓冲区,该分片的时候还是得老老实实分片。

你可能感兴趣的:(Linux,网络基础,网络,服务器,网络协议)