
上一篇把一个 IPv4 地址块划分成多个子网,解决的是"目的地址属于哪个网络"的问题。路由器知道该往哪个方向转发后,还需要读懂正在转发的 IP 数据报:它有多长,能否通过下一段链路,已经经过了多少跳,以及首部是否在传输中出错。
这一篇仍位于 TCP/IP 五层模型的网络层,聚焦 IPv4 数据报的首部。重点不是死记每一个字段的位置,而是理解三个很实际的问题:数据报为什么不会在路由环路中无限转发;遇到链路 MTU 不足时为什么会分片;路由器为什么要反复计算首部校验和。
一、IPv4 数据报由什么组成?
IPv4 数据报由两部分组成:
- 首部:携带转发和处理所需的控制信息;
- 数据部分:承载上层交下来的内容,例如 TCP 报文段、UDP 用户数据报或 ICMP 报文。
IPv4 首部有 20 字节的固定部分,还可以带可选字段,因此首部总长度为 20 到 60 字节。实际网络中大多数 IPv4 数据报使用 20 字节的固定首部;可选字段会增加每台路由器的处理开销,所以很少使用。
可以把它粗略看成一张随数据一起旅行的"转运单":源地址和目的地址说明从哪里来、往哪里去;总长度说明这件"包裹"有多大;TTL 防止它绕圈;分片字段帮助把过大的包裹拆开;首部校验和检查转运单本身有没有损坏。
二、首部中最值得掌握的字段
IPv4 的首部字段很多,但它们可以按用途理解。
| 字段 | 长度与单位 | 作用 |
|---|---|---|
| 版本 | 4 位 | 指明使用的 IP 版本;IPv4 的值为 4 |
| 首部长度 | 4 位,以 4 字节为单位 | 告诉接收方首部在哪里结束、数据从哪里开始;常见值为 5,表示 20 字节 |
| 区分服务 | 8 位 | 可用于表达服务质量或拥塞通知等处理需求 |
| 总长度 | 16 位,单位为字节 | 首部与数据部分的总长度,最大可表示 65535 字节 |
| 标识、标志、片偏移 | 16 位、3 位、13 位 | 三者配合实现分片与重组 |
| TTL | 8 位 | 限制数据报可经历的转发跳数 |
| 协议 | 8 位 | 指示数据部分交给哪个上层协议处理,例如 TCP、UDP、ICMP |
| 首部校验和 | 16 位 | 只检验 IPv4 首部是否出错 |
| 源地址、目的地址 | 各 32 位 | 标识发送接口和目标接口的 IPv4 地址 |
首部长度、总长度与数据长度
这三个长度概念最容易混淆:
text
数据长度 = 总长度 - 首部长度
首部长度以 4 字节为单位,是因为 IPv4 首部按 32 位边界组织。若存在可选字段,可能需要用全 0 填充,使整个首部长度仍是 4 字节的整数倍。
总长度则以字节为单位,包含首部和数据。若一个数据报的固定首部为 20 字节、总长度为 1500 字节,那么它的数据部分长度是 1480 字节。
协议字段不是"本次传输使用的网络协议"
协议字段回答的是:**IP 的数据部分应该交给谁处理。**例如值对应 TCP 时,目的主机的 IP 层会把数据部分交给 TCP;对应 UDP 时交给 UDP;ICMP 报文也直接封装在 IP 数据报中。
因此,IP 数据报的数据部分不一定是 TCP 或 UDP 数据。路由器和主机为网络诊断、路由控制等产生的某些网络层报文,同样可以由 IP 承载。
三、TTL:数据报为什么不会永远绕圈?
网络中可能出现临时的错误路由或路由环路。若没有限制,一个数据报就可能在几个路由器之间反复转发,占用链路和队列资源。
TTL 是 Time To Live 的缩写,位于 IPv4 首部中,占 8 位。现代网络中可将它直观理解为"允许继续转发的跳数预算":
- 源主机发送数据报时设置一个初始 TTL;
- 每台路由器在转发前将 TTL 减 1;
- 若减完变为 0,路由器丢弃该数据报,并通常向源端发送 ICMP 超时报告。
例如初始 TTL 为 3:第一台路由器把它改为 2 并转发,第二台改为 1 并转发,第三台减为 0 后丢弃。因此它最多能被成功转发两次,不能无限经过路由器。
这也是 traceroute 或 tracert 能逐跳探测路径的基础:工具有意发送 TTL 很小的数据报,让不同距离的路由器依次返回超时信息。
四、MTU 不够时,IPv4 为什么需要分片?
不同数据链路层技术对一帧中能承载的 IP 数据报大小有上限,这个上限叫 MTU,即最大传送单元。常见以太网 MTU 为 1500 字节,表示封装进一个以太网帧的数据部分最多装下 1500 字节的 IP 数据报。
若一个 IPv4 数据报总长度超过下一跳链路的 MTU,就无法直接封装成该链路的帧。IPv4 可以把原数据报拆成多个较小的分片分别发送;每个分片都是独立的 IPv4 数据报,都有自己的首部。目的主机收到所有分片后,再按首部信息重组出原始数据。
分片由哪三个字段配合?
| 字段 | 作用 |
|---|---|
| 标识 | 同一原始数据报产生的所有分片使用相同标识,便于目的主机归类 |
| 标志中的 DF 位 | DF 为 1 表示不允许分片;若包太大,路由器丢弃它并反馈错误信息 |
| 标志中的 MF 位 | MF 为 1 表示后面还有分片;最后一片的 MF 为 0 |
| 片偏移 | 指出本分片数据部分在原始数据部分中的相对位置,单位是 8 字节 |
标志字段还有一个保留位,必须为 0。片偏移以 8 字节为单位,所以除最后一个分片外,每个分片的数据部分长度必须是 8 字节的整数倍;这不是随意切分,而是首部字段表达能力带来的约束。
一个完整的分片计算例子
设原数据报使用 20 字节固定首部,总长度为 3820 字节,因此原数据部分为:
text
3820 - 20 = 3800 字节
下一跳 MTU 为 1420 字节。每个分片还要带 20 字节首部,所以一个"尽可能大"的非末片最多放 1400 字节数据;1400 恰好是 8 的倍数。
text
每个非末片最大数据长度 = 1420 - 20 = 1400 字节
于是可分成三片:
| 分片 | 数据部分长度 | 总长度 | 片偏移 | MF |
|---|---|---|---|---|
| 第 1 片 | 1400 字节 | 1420 字节 | 0 | 1 |
| 第 2 片 | 1400 字节 | 1420 字节 | 175 | 1 |
| 第 3 片 | 1000 字节 | 1020 字节 | 350 | 0 |
第二片从原数据的第 1400 字节开始,片偏移为 1400 除以 8,即 175;第三片从第 2800 字节开始,片偏移为 350。三片的标识字段相同,接收端据此、结合片偏移和 MF 位,才能知道怎样还原原来的 3800 字节数据部分。
分片并不是没有代价
任意一个分片丢失,目的主机就无法完成原数据报的重组,最终往往需要依赖上层协议重传。多个分片也会重复携带 IPv4 首部,增加开销。因此工程上通常通过路径 MTU 发现、发送端控制报文大小等方式,尽量避免中途分片。
五、首部校验和:为什么路由器每跳都要重算?
首部校验和占 16 位,只覆盖 IPv4 首部,不覆盖数据部分。它的作用是检查路由器据以转发的数据是否可靠,例如版本、首部长度、总长度、TTL、协议以及源和目的地址等首部信息是否出现差错。
计算时把首部按 16 位分组相加,采用"溢出回卷"的一补码加法,再对结果取反。验证时,接收方以同样规则把各 16 位字段和校验和相加;若结果正确,应得到全 1。
路由器每转发一次都会修改 TTL。因为 TTL 属于首部,原来的校验和立刻失效,路由器必须更新校验和后再发送。发生分片时,每个分片的总长度、标志和片偏移等字段也不同,也各自需要校验和。
需要区分两件事:
- **首部校验和只验证首部。**它不保证业务数据没有出错;
- **链路层和传输层还可能提供各自的差错检测。**例如以太网帧有 FCS,TCP/UDP 有覆盖报文内容的校验和。它们覆盖范围和职责不同,不是简单重复。
普通路由转发过程中,源地址和目的地址通常保持不变;TTL 才是每一跳必然变化的字段。NAT 等特殊设备可能改写地址,但那是额外的地址转换行为,不能当作普通路由器转发的常规步骤。
六、把一次转发过程串起来
当路由器收到一个以太网帧时,会先处理链路层帧,再查看其中的 IPv4 数据报:
- 检查 IPv4 首部的版本、首部长度和校验和是否合理;
- 根据目的地址查询转发表,确定出接口或下一跳;
- TTL 减 1;若到 0 则丢弃并报告超时;
- 若下一跳 MTU 不足且允许分片,则生成符合 MTU 的分片;若 DF 禁止分片,则丢弃并报告;
- 更新每个待发送数据报的首部校验和,重新封装为下一跳链路的帧并发送。
这也解释了前面"路由器工作原理"一文中的一个细节:路由器不会原封不动地转发旧的二层帧,但 IP 数据报通常会继续向目的地前进;途中 TTL、校验和,以及必要时的分片字段可能发生变化。
七、常见误区
| 误区 | 更准确的理解 |
|---|---|
| TTL 表示精确的秒数 | 现代网络中它主要按路由器转发跳数递减 |
| TTL 为 3 的数据报能成功通过 3 台路由器 | 第 3 台把 TTL 减到 0 后会丢弃;它最多被成功转发 2 次 |
| MTU 是 IPv4 数据部分的最大长度 | MTU 限制的是可装入链路层帧的整个 IP 数据报,即首部加数据 |
| 所有分片的数据长度都必须是 8 的倍数 | 最后一个分片可以不是;非末片必须满足 |
| 分片后只需要第一个分片带首部 | 每个分片都是独立 IP 数据报,都有自己的首部 |
| 首部校验和校验整个数据报 | IPv4 首部校验和只校验首部,数据部分由其他层的机制负责保护 |
| 普通路由器每跳都会改写源、目的 IP 地址 | 普通转发通常只改 TTL 等字段;改写地址属于 NAT 等特殊处理 |
八、总结
IPv4 首部让数据报具备跨网络转发所需的基本信息。TTL 为每个数据报设置了跳数上限,避免它因路由环路永久存在;MTU 限制决定过长数据报是否需要分片,标识、标志和片偏移让目的主机能够重组;首部校验和则保护路由决策依赖的首部信息,并因 TTL 的变化而需要逐跳更新。
理解地址、子网和数据报首部后,就能进一步回答一个很常见的问题:多台内网主机为什么能共用一个公网地址访问互联网?下一篇将从 NAT 的地址与端口转换机制展开。
如果这篇文章对你有帮助,欢迎点赞、评论、关注、收藏。你们的支持是我前进的动力!