计算机网络篇22:网络层——公网的三级地址划分与逐跳转发,从私网出口替换到 IP 分片组装


📚 本文收录于「流浪」的系列专栏

🐧 Linux系统 ⚙️ C++
📊 数据结构与算法 🐍 Python
🔗 LangChain & LangGraph 🗄️ MySQL 数据库
🌿 Git 工具 🌐 计算机网络
🤖 LLM 💯 大厂面试、八股
📚 学习筑基专栏

🏠 博客主页:流浪 | 📝 原创首发于 CSDN


前言: 篇21 把地址怎么切讲完,收在「私网地址要在出口换成公网地址」这一句。这篇把它展开:公网怎么一级一级搭起来,报文在哪一步被换掉地址,跨网络时 MTU 怎么把大报文拆开、对端又怎么拼回去。


一、运营商与路由器的两套 IP

1.1 什么是运营商:建网、要号段、分 IP

  1. 运营商就是电信、联通、移动这类公司,国际上叫 ISP(Internet Service Provider,互联网服务提供商)。它的活儿有三件:自己建网络、向上级申请公网 IP 号段、给接入的用户分配 IP 地址。
  2. 路由器本身就具有构建子网的能力,这是它和普通交换机最本质的差别之一:一个接口接上一段网络,它就能把这段网络组织成一个子网。
  3. 路由器又有给所有主机分配 IP 的能力。家里的电脑手机开机就连上网、不用手动配地址,靠的就是这个能力。

运营商的定位一句话:对上替你申请公网资源,对下替你组建并管理子网,中间那台路由器就是它的落地点。

1.2 一台路由器要有两套 IP

  1. 以运营商路由器为主来看,一台路由器要配两套 IP:一套 WAN 口 IP 对外,一套子网 IP 也就是 LAN 口 IP 对内。
  2. WAN 口朝向上级网络,LAN 口朝向自己组建的子网。一个盒子站在两个网络的交界处,两边各有一个身份。
  3. 篇21 讲过这两套地址怎么共存,这里只留结论:对外要求唯一、对内允许重复,靠的就是这个双身份设计。

两套 IP 不是奢侈配置,是路由器"跨界"这件事的必然结果------它必须同时属于两边。

1.3 家用路由器:运营商子网里的一个节点

  1. 家里的路由器是运营商构建的子网中的一个节点,它自己也有两套 IP:子网 IP 和 WAN 口 IP。
  2. 家用路由器的 WAN 口 IP 与运营商路由器的子网 IP 处在同一个子网里,这一点决定了两者能直接对话。
  3. 家用路由器同样能给家里的主机分配 IP。手机连上 WiFi 拿到的 192.168.1.x,就是它在发地址。
  4. 发数据时的路径是:主机 → 家用路由器 → 运营商路由器 → 公网。运营商路由器就是公网的出入口路由器,报文在它这里完成"出内网"这一步。

从家到公网不是一跳,而是一串路由器的接力,每一站做的是同一件事:判断下一站是谁。

二、私网 IP 为什么不能出现在公网

2.1 重复:全世界都在用 192.168.*

  1. 假设本机是 192.168.1.201,要访问 122.77.241.3,形成的报文里写的是 Src: 192.168.1.201、Dst: 122.77.241.3。
  2. 问题出在源地址上。192.168.* 是私有地址段,全世界的家庭、学校、公司内网都在用,同一个地址在成千上万台主机上同时存在。
  3. 公网设备收到请求、处理完要回包时,手上只有一个源地址 192.168.1.201,它不知道这个地址该送回哪个国家的哪台机器。

私网地址能成立的前提是"只在局部唯一",公网要的是"全局唯一",两套规则在公网上正面撞车。

2.2 出口替换:报文到路由器就换 WAN 口 IP

  1. 为了保证私网 IP 不出现在公网上,报文发送时到达路由器后,源地址被替换成这台路由器的 WAN 口 IP,再往上交付。
  2. 上一级路由器同样处理,逐级替换。最后一个路由器的 WAN 口 IP 本身就是公网 IP,所以报文到达公网时,头里已经找不到任何内网地址。
  3. 这一整套"在出口把私网地址换成公网地址"的动作,就叫 NAT(Network Address Translation,网络地址转换)。
  4. 因为多个内网可以共用一个公网地址,NAT 能缓解 IP 地址不足的问题,篇21 末尾把它归为三条解法之一。
  5. 转换表怎么建、同一个公网 IP 底下多台主机怎么区分,属于 NAT 的详细机制,另开一篇讲。这里只需要记住一件事:替换发生在每一层出口。

NAT 的动作极简:每过一层出口,内网地址就被换成对外的地址,换到最外层就只剩公网 IP。

2.3 运营商能控制报文出不出口

  1. 报文必须经过运营商的出口路由器才能到公网,出与不出,由出口设备上的转发与过滤策略决定。
  2. 不在策略允许范围内的报文,出口设备直接不转发,报文到不了公网,这就是平常直接访问国外网站访问不了的由来。
  3. 大家口中的"防火墙",很多就铺在这些出口节点上。

网络边界不只是通道,还是闸门;闸门开多大,由出口设备上的规则说了算。

三、公网是逐级搭起来的:国家 8 位、省 8 位、市 4 位

3.1 公网 IP 从哪来:各国运营商自主申请

  1. 公网 IP 由各个国家的运营商自主申请。运营商不仅组建内网,也要组建自己国家的公网环境。
  2. 一个地区能有多大的网络,取决于自己手里有多少公网 IP。
  3. 分配不看国家面积,而是结合网民数量按地区划分,人多设备多的地方拿到的号段就大。

公网不是抽象概念,它是被一段段号段占满的实体资源,谁的网民多,谁占的段就大。

3.2 国际路由:用 8 位表示国家

  1. 全球有近 200 个主权国家。用一个简化模型来理解国际路由:拿 8 位表示特定国家。
  2. 按这个模型举例:俄罗斯 1.0.0.0/8、美国 2.0.0.0/8、英国 3.0.0.0/8、法国 4.0.0.0/8、中国 5.0.0.0/8、意大利 6.0.0.0/8。以下数字全部是假设举例,不是真实分配。
    • 每个国家一个 /8,就是 2 的 24 次方,约 1677 万个地址
    • 掩码 /8 让国际路由器一次按位与就能把其余所有国家排除掉
  3. 每个国家的国际路由器 WAN 口也落在这一段里,比如俄罗斯 1.0.0.1/8、美国 2.0.0.1/8。

8 位国家号的意义不在编号好看,而在于一次比对就能把候选从"全球"砍到"一国"。

3.3 国内路由:再取 8 位区分省份

  1. 中国拿到 5.0.0.0/8 之后,国内还有陕西、河南、浙江、吉林、河北等省份,需要再分。
  2. 为了区分省份,从地址里再拿出 8 位做国内路由:陕西 5.1.0.0/16、河南 5.2.0.0/16,同样是举例。
  3. 省级路由器横跨两级:WAN 口接国家公网,比如陕西 5.1.0.1/16;向下还有互联口接省内下一级设备,写作 5.1.128.1/30 这类形式。
    • /30 只留 2 个可用地址,正好够两台设备点对点互联
    • 河南同样有 5.2.0.1/16 与 5.2.128.1/30 两套对外口

每多切一级,前缀就长一截:/8 到 /16 用掉 8 位,剩下的位留给下一层去分。

3.4 省内路由:再取 4 位区分市

  1. 省下面还有市,那就再取 4 位来区分,做省内路由。
  2. 假如西安分配到 1 号:0001 0000 → 16,那么西安这一段就是 5.1.16.0/20。
  3. 西安市路由器的配置是:WAN 口 5.1.16.1/20 对外,LAN 口 10.1.1.1/24 对内。
  4. LAN 口落进 10.x,说明市以下是运营商搭建的内网,用的是私有地址段,与篇21 的 RFC 1918 三段正好对上。

到市这一级,公网的层级划分就停住了,再往下交给运营商的私网自治。

划分全链路

3.5 两种看法与全网连通

  1. 从上往下看,是把一个大的网络划分为一个个子网;从下往上看,是把一个个子网组建成为一个大的网络。
  2. 国际路由器之间可以互相通信,靠路由条目识别对方;向下每一级也是同样的道理。
  3. 西安之后就不能再分了,往下由运营商做子网划分,于是整个网络就连通了。
  4. 路由器要横跨网络,所以要有两套 IP。国家级的路由器比如俄罗斯,两套 WAN 一套管国际、一套管国内;省市级比如河南、西安,WAN 对公网、LAN 对内网。

所谓公网,就是无数台配着两套 IP 的路由器层层互联拼出来的一张大网。

3.6 真实世界怎么分配

  1. 真实的网络结构复杂得多:全球地址由 ICANN 统一管理,往下按区域分给 APNIC、RIPE NCC 等机构,再由 Tier1 运营商和各国 ISP 逐级申请使用。
  2. 课堂按"国家 /8、省 /16、市 /20"的模型是刻意简化,为的是看清逐级划分、逐级转发的思路,不是真实分配规则。

模型给你的是直觉:一层一层切、一层一层转发;真实世界只是层数更多、前缀更碎。

四、IP 的查找与转发全过程

4.1 从俄罗斯访问 5.1.16.X:逐级按位与

  1. 假设俄罗斯境内一台主机访问 5.1.16.X。
  2. 报文到达俄罗斯最上层路由器,与 /8 掩码按位与得到 5.0.0.0,正好对上中国的号段,于是找到下一跳,也就是中国在国际线路上的路由器 IP。
  3. 报文到中国后,继续与 /16 掩码按位与定位到陕西,再与 /20 掩码按位与定位到西安,一层层转发下去,直到目标网段。

查路不存在全局计算,每一层只做同一件事:按位与、对表、交给下一跳。

4.2 路由表:转发判断的依据

  1. 每个节点内部都维护一张路由表,转发时拿目的 IP 逐行比对:与这一行的掩码按位与,结果等于该行的目的网络,就算命中。
  2. 表项由几个参数组成:Destination 目的网络地址、Genmask 子网掩码、Gateway 下一跳地址、Iface 发送接口,以及 Flags 标志。
    • Flags 里的 U 表示这条记录有效,可以临时禁用某条记录
    • Flags 里的 G 表示下一跳是某台路由器的地址;没有 G 说明目的网络与本机接口直接相连,不必经路由器
  3. 所有行都不匹配时,按缺省路由条目,从规定接口发往缺省网关。
  4. 举例:目的地址 192.168.56.3,逐行与掩码按位与,命中直连的 192.168.56.0/24,直接从对应接口发给目标主机,不经路由器。
  5. 再举一例:目的地址 202.10.1.2,与前几行都不匹配,走缺省路由,从 eth0 发往 192.168.10.1,由那台路由器按自己的表决定下一跳。
  6. 命中多条时选前缀最长的那条,这就是篇21 讲过的最长前缀匹配,落到这里就是越具体的路由越优先。

路由表按网段记账,不按主机记账;它回答的是"这个网段往哪走",不是"这台机器在哪"。

4.3 路由表怎么来的

  1. 路由表可以由网络管理员手动维护,这叫静态路由。
  2. 也可以由算法自动生成,这叫动态路由,常见的有距离向量算法、LS 算法、Dijkstra 算法。
  3. 这些算法属于选学内容,本篇不展开;需要记住的是,不管表怎么来,转发时每台路由器只查自己的表。

谁生成表不重要,重要的是没有任何一台设备掌握整条路径,路径是每一跳现场拼出来的。

五、MTU:报文太大就要分片

5.1 MTU 1500 与网络层自动分片

  1. 数据要遵守各层规定:上层交下来的报文,大小不能超过 MTU(Maximum Transmission Unit,最大传送单元),以太网一般是 1500 字节。
  2. 超过这个上限时,网络层会自动把它切成分片,每片加上自己的 IP 报头再往下传。
  3. 到对端后,由对端的网络层把分片组装回完整报文,再交给上层。

MTU 是链路层的容量上限,分片是网络层为了遵守这个上限自己做的妥协。

5.2 分片的代价:丢一片,整包全丢

  1. 任何一个分片丢失,都代表整个报文丢失,缺一片就拼不回原样。
  2. 所以分片越多,丢包概率越大:原本一条报文成功一次就够,切成 N 片就要成功 N 次。
  3. 要减少分片,就得从源头减少报文长度。

分片不是白给的能力,它拿"整体成功率"换"能塞进链路",片数越多这笔交易越亏。

5.3 减少分片的办法:传输层控制长度

  1. 网络层只是把上层发来的报文打包向下传,它不知道多长才合适,所以报文长度该由传输层来控制。
  2. IP 报头 20 字节、TCP 报头 20 字节:1500 − 20 − 20 = 1460,传输层一次最多发 1460 字节,这个上限就是 MSS(Maximum Segment Size,最大段尺寸)。
  3. 所以滑动窗口并不是把所有数据一次性打包发出去,而是拆成一个个段分开发送,篇18 讲的是窗口怎么控制节奏,这里的重点是这个拆段动作本身就是为了减
    少分片。

MSS 是传输层递给网络层的安全尺寸:按这个尺寸切段,中间每一跳都不需要再动刀。

六、分片的识别与组装

6.1 三个字段各管什么

  1. 报文的分片和组装,与 IP 报头里的 16 位标识、3 位标志、13 位片偏移三个字段有关。篇20 拆过它们在报头里的位置,这里讲它们怎么用。
  2. 16 位标识:不同报文的标识不同;同一个报文的所有分片,标识相同。
  3. 3 位标志:第二位 DF 置 1 表示禁止分片,超过 MTU 就直接丢弃;第三位 MF 表示更多分片,分片时最后一片置 0、其余置 1,相当于一个结束标记。
  4. 13 位片偏移:本片数据在原完整 IP 数据报数据部分里的起始位置,以 8 字节为单位。

三个字段凑成一套寻亲机制:标识说我们是一家的,MF 说后面还有没有,片偏移说我排第几。

6.2 怎么判断一个报文被分片了

在IPV4协议报头中 有一个三位标志:

  • 第 0 位(保留 R)
  • 第 1 位 DF
  • 第 2 位 MF
  1. MF 是 1:后面还有分片,这个报文一定被分片了。
  2. MF 是 0 但片偏移不等于 0:它自己是最后一片,同样说明原报文被切过。
  3. 反过来,MF 是 0 且片偏移也是 0,才说明这是一个没被切过的完整报文。
  4. 判定为分片后,提取 16 位标识,标识相同的分片归到同一组,属于同一个原始报文。

片偏移:标记当前这片数据,在原始 IP 报文的数据部分里,从哪个位置开始

MF 和片偏移一组合,"是不是分片""是不是最后一片"两个问题一次答完。

6.3 怎么发现分片丢了:三种情况

  1. 第一片丢失:找不到片偏移为 0 的那个分片,排头没到,后面到的片不知道该往哪放。
  2. 尾片丢失:找不到 MF 为 0 的那个分片,没有结束标记,就永远不知道收齐没有。
  3. 中间丢失:把收到的分片按片偏移升序排序,验证"片偏移 + 自身数据长度 = 下一个分片的片偏移"。
    • 升序排好后相邻两片本应首尾相接
    • 逐对验证,等式断掉的位置就是缺口

三种丢失共用一个原理:分片本应首尾相接铺满原始报文,任何一处接不上都是丢失的证据。

6.4 组装完成,交给上层

  1. 分片全部到齐、校验没有缺口后,按片偏移排序拼合,恢复出完整的 IP 数据报,交给上层协议处理。
  2. 分片和组装都发生在网络层,对传输层是透明的:传输层只按 MSS 切段,不关心底下有没有再切、又是怎么拼回来的。

分片的完整闭环:发送端超长就切、途中每片独立转发、接收端按标识归组、按偏移排序拼回原样。

七、全篇总结

1. 公网是路由器拼出来的
  1. 国家 /8、省 /16、市 /20,一级一级切下去,前缀一路变长。
  2. 每一级路由器配两套 IP,WAN 对外、LAN 对内。
2. 私网地址在出口被换掉
  1. 私网地址只在局部唯一,重复的源地址回不了家。
  2. 报文每过一层出口就换成 WAN 口地址,到最外层只剩公网 IP,这套动作叫 NAT。
3. 转发就是逐级按位与
  1. 目的地址与掩码按位与,对上哪一行的目的网络就往哪走。
  2. 全不匹配走缺省路由,命中多条选最长前缀。
4. 超过 MTU 才分片,丢一片全丢
  1. 以太网 MTU 1500,超了就在网络层切。
  2. 分片越多,整包成功的概率越低。
5. MSS 从源头减少分片
  1. MSS = MTU − IP 报头 − TCP 报头 = 1460。
  2. 滑动窗口按段发送,本质是让中间每一跳都不必分片。
6. 三个字段撑起识别与组装
  1. 标识归组、MF 判首尾、片偏移排序校验缺口。
  2. 缺首片、缺尾片、缺中间片,三种情况各有判据。

八、文末面试题

8.1 推导题

1. 链路 MTU 1500 字节,IP 报头 20 字节、TCP 报头 20 字节,MSS 是多少?一次要发 5000 字节数据,至少切成几段?

答(推导):MSS = 1500 − 20 − 20 = 1460 字节。5000 字节按每段 1460 装,5000 ÷ 1460 得 3 余 620,所以要 4 段,前三段各 1460、最后一段 620。这里要注意区分:这是传输层按 MSS 切段,不是网络层分片,两者目的相同但层次不同。

2. 给一个 IP 报文的 MF 与片偏移取值,怎么判断它是完整报文、中间片还是最后一片?

答(推导):先看 MF 再看片偏移。MF 为 0 且片偏移为 0,是完整未分片的报文;MF 为 1,是还有后续的中间片,其中片偏移为 0 的那个就是第一片;MF 为 0 但片偏移不为 0,是最后一片。判断要点在于最后一片必须靠 MF 归零来标识,不能只看偏移。

3. 收到的分片片偏移依次是 0、185、370,各片数据长度都是 1480 字节,判断是否收齐。

答(推导):按"片偏移 + 自身数据长度 = 下一片片偏移"逐个验。第一片偏移 0 表示起点 0,加 1480 得 1480,除以 8 是 185,与第二片偏移吻合;第二片起点 1480,加 1480 得 2960,除以 8 是 370,与第三片吻合。三片首尾相接没有缺口,但还要看最后一片的 MF 是否为 0,只有尾片标识归零才能判定收齐。

8.2 真题

1. 一个 5960 字节的数据报(20 字节 IP 首部加 5940 字节数据),经过 MTU 为 1500 的链路,怎么分片?

答(转述):每片数据最多 1500 − 20 = 1480 字节,5940 ÷ 1480 约等于 4.01,向上取整得 5 片。前四片各带 1480 字节数据、总长 1500,第五片带 5940 − 4×1480 = 20 字节数据、总长 40。片偏移依次为 0、185、370、555、740,前四片 MF 为 1、最后一片 MF 为 0,DF 全为 0。

【真题·转述自 牛客:一个 5960 字节的数据报(其中 20 字节 IP 首部加上 5940 字节数据)】

2. 路由表里有 169.96.40.0/23 下一跳 176.1.1.1 走 S1、169.96.40.0/25 走 S2、169.96.40.0/27 走 S3、0.0.0.0/0 走 S4,目的地址 169.96.40.5 从哪个接口转发?

答(转述):前三条具体路由都能匹配上,按最长前缀匹配选前缀最长的 /27 那条,从 S3 转发给下一跳 176.3.3.3。判断方法是把目的地址与每条记录的掩码按位与,结果等于该条目的网络号就算命中,命中多条时前缀越长越优先。

【真题·转述自 牛客:若路由器收到一个目的地址为 169.96.40.5 的 IP 分组】

3. 路由表里 128.96.39.0/25 走 m0、128.96.39.128/25 走 m1、128.96.40.0/25 走 R2、192.4.153.0/26 走 R3,另有默认路由 R4,目的地址 128.96.40.151 走哪一条?

答(转述):目的地址 128.96.40.151 与 /25 掩码相与,末字节 151 与 128 相与得 128,结果是 128.96.40.128,与三条 /25 路由的目的网络 128.96.39.0、128.96.39.128、128.96.40.0 都对不上;再与 /26 掩码相与,末字节 153 与 192 相与得 128,结果是 192.4.153.128,也不匹配 192.4.153.0。既然没有命中项,就走默认路由 R4。

【真题·转述自 牛客:计算机网络网络层部分习题解答】

4. MTU 和 MSS 是什么关系,MSS 一般是多少?

答(转述):MTU 是链路层一次能承载的最大数据长度,MSS 是 TCP 一次向下交付的最大数据量。以太网 MTU 通常 1500 字节,TCP 与 IP 报头常规各 20 字节,所以 MSS = 1500 − 20 − 20 = 1460 字节。MSS 的作用就是让网络层尽量不需要分片,因为分片会增加丢包概率与额外开销。

【真题·转述自 牛客:后端高频面试方向 IP 协议】

5. TCP 握手时已经协商了 MSS,为什么实际传输中还会发生 IP 分片?

答(转述):MSS 只约束发送端与接收端协商出的这一档值,管不住中间路径。路径上不同链路的 MTU 可能更小,报文在中间路由器上仍可能被切开;应用层一次交付的数据过大,TCP 切段后配上报头依然超出路径 MTU 时也会触发。要进一步避免,得依靠路径 MTU 发现这类机制。

【真题·转述自 牛客:汇川嵌入式软件开发一面面经】

6. 分片到达接收方后,怎么判断有没有丢片?

答(转述):三件事一起看。有没有片偏移为 0 的首片,有没有 MF 为 0 的尾片,按片偏移升序排好后相邻两片是否首尾相接。三样都满足才算收齐,缺任何一样都拼不回原报文,整包只能丢弃。

【真题·转述自 牛客:计算机网络面试之网络层 IP 工作原理】


💬 结语: 公网不是一张平铺的网,它是一层一层切出来、一跳一跳走出来的;报文太大时,网络层还会替你把它拆开,再在对端拼回去。评论区聊聊,你第一次算片偏移时,有没有忘记那个除以 8。

相关推荐
Java成神之路-15 小时前
TCP Socket 与 UDP Socket
tcp/ip·计算机网络·udp
|_⊙2 天前
网络层协议 IP
服务器·网络·tcp/ip
沫璃染墨2 天前
从零入门计算机网络系列(十五):TCP可靠传输机制详解——从序号与确认应答到乱序处理
服务器·网络·c++·tcp/ip·tcp
流浪0012 天前
计算机网络篇20:网络层——IP 协议的定位与 IPv4 报头字段,从 20 字节首部到 TTL 防环
tcp/ip·计算机网络·ttl·网络层协议·ip报头
zhengfei6112 天前
CVE-2026-98432:Linux 内核 TCP 释放后重用漏洞,CVSS 9.8 但补丁覆盖极不均衡
linux·运维·tcp/ip
沫璃染墨3 天前
从零入门计算机网络系列(十四):TCP报文与字节流本质——从数据封装到报文边界
linux·服务器·网络·网络协议·tcp/ip·tcp
流浪0013 天前
计算机网络篇17:传输层——TCP 超时重传、三次握手与四次挥手,TIME_WAIT 为什么要等 2MSL
网络协议·tcp/ip·计算机网络·三次握手·四次挥手·超时重传
流浪0014 天前
计算机网络篇16:传输层——TCP 报头属性字段:16 位窗口大小撑起流量控制,六个标志位标识报文类型
网络协议·tcp/ip·计算机网络·urg紧急指针·tcp报头
从琳开始9894 天前
网络原理入门(二)------OSI七层模型?TCP/IP五层(四层)模型原来是这样的
java·网络·tcp/ip·java-ee·php