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

IP分片发生在当报文大小超过网络层的MTU限制时,需将其拆分为多个小报文进行传输。每个分片包含16位分片标识、3位标志和13位片偏移用于重组。分片影响UDP和TCP,由于任何一部分丢失都会导致所有分片被丢弃,增加了丢包概率。对于UDP,分片增加丢包风险;而对于TCP,其内部缓冲区允许更灵活的数据段控制,减少分片需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、什么是分片?

二、如何分片?

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

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

2、组合分片报文

四、分片的影响

1、对UDP的影响

2、对TCP的影响


一、什么是分片?

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

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

二、如何分片?

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

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

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

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

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

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

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

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

2、组合分片报文

第一步,通过三位标识符的第三位标识“更多报文”判断当前收到的报文后面是否存在其他分片报文。

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

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

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

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

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

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

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

四、分片的影响

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

1、对UDP的影响

UDP没有发送缓冲区,应用层要发多少,到了网络层就是多少,这个时候就得老老实实分片。分片会增加丢包的概率,一旦某个分片报文丢了导致无法组装就会将相关的分片报文全部丢弃。(是否相关可以根据16位分片标识来判断)

2、对TCP的影响

因为TCP有缓冲区的存在,想发多少、什么时候发都由TCP决定,TCP可以做到自己控制数据段的长度,然后再传到网络层,此时就无需网络层来分片了。

但TCP每次可以发送的数据长度不是无限大,受制于MTU和对方主机的MSS(Max Segment Size),即最大消息长度。

  • 受制于MTU的意思是,为了不分片,TCP每次最多携带的数据是多少。不同系统的MTU可能有所不同,MTU减去TCP报头和IP报头的大小,就是TCP每次最多可以发送的数据量。
  • 受制于对方主机的MSS的意思是,对方每次最多可以接收多少。双方在发送SYN的时候会在TCP头部写入自己可以支持的MSS值,在得知对方的MSS以后,选取较小的作为最终MSS。MSS的值就是在TCP首部的40字节变长选项中(kind=2);
### TCP 报文分片与 UDP 报文分片的区别 #### 分片处理方式 对于 **TCP** 协议而言,由于其面向连接并提供可靠传输服务,因此在遇到网络路径最大传输单元 (MTU) 较小时,TCP 可以通过调整最大报文段长度(MSS, Maximum Segment Size)来避免 IP 层的分片操作。然而,当 MSS 设置不当或中间路由器 MTU 过低时,仍可能发生 IP 层的分片现象[^1]。 ```python # Python伪代码展示如何设置TCP socket选项中的MSS import socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) mss_value = 1460 # 假设的最大报文段大小 sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_MAXSEG, mss_value) ``` 相比之下,**UDP** 并不直接参与分片决策;相反,它依赖于底层 IP 层来进行必要的分片工作。这意味着一旦应用程序发送的数据量超过了当前链路层所能承载的最大尺寸,则这些数据会被分割成多个较小的部分并通过独立的数据包形式传送至目的地。值得注意的是,UDP 不具备内置机制用于检测或管理因IP级分片而产生的任何问题,这可能导致部分片段丢失而不被察觉的情况发生。 #### 数据重组过程 在一个成功的通信过程中: - 对于 **TCP** 来说,即使发生了 IP 级别的分片,最终目的主机上的协议栈也会负责重新组装原始消息,并按照正确的顺序交付给上层应用。这是因为 TCP 维护着一个滑动窗口机制,能够追踪已发出但尚未确认的消息序列号,从而确保所有接收到的数据都能按序排列。 - 而对于 **UDP** ,情况则有所不同。由于缺乏类似 TCP 的流量控制和拥塞控制特性,再加上没有专门针对分片管理和重组的功能设计,使得整个过程更加复杂且容易失败。特别是当某个分片未能成功抵达目标节点时,其余已经到达的目的地将无法完成完整的数据恢复,除非采取额外措施如自定义的应用程序级别重试逻辑。 #### 性能影响 从性能角度来看: - 使用 **TCP** 发送大量数据可能会触发更频繁的 ACK 和窗口更新消息交换,增加了往返时间延迟(RTT),但这有助于维持稳定性和可靠性。另外,尽管存在潜在的 IP 分片风险,但由于现代互联网基础设施普遍支持较大的 MTUs,实际遭遇这种情况的概率相对较低。 - 就 **UDP** 而言,虽然理论上它可以实现更低的开销和更高的吞吐率,但在面对较大规模的数据传输需求时,过度依赖 IP 分片反而可能带来负面效果——不仅增加了丢包的可能性,还加重了末端系统的负担,尤其是在需要执行复杂的分片重组任务的情况下。此外,如果某些关键分片网络中遗失,则整个事务都不得不放弃或重启,严重影响用户体验和服务质量。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值