目录
- 一、网络层
- [二、IP 协议格式](#二、IP 协议格式)
-
- [2.1 IP 报头字段](#2.1 IP 报头字段)
- [2.2 IP 报文分片与组装](#2.2 IP 报文分片与组装)
- 三、子网划分
-
- [3.1 为什么要子网划分?](#3.1 为什么要子网划分?)
- [3.2 怎么子网划分?](#3.2 怎么子网划分?)
- [3.3 子网掩码](#3.3 子网掩码)
- 四、私有IP和公网IP
-
- [4.1 私有 IP](#4.1 私有 IP)
- [4.2 公网 IP](#4.2 公网 IP)
- [4.3 一张图理解](#4.3 一张图理解)
- 五、理解公网
-
- [5.1 运营商](#5.1 运营商)
- [5.2 公网](#5.2 公网)
- [5.3 NAT技术](#5.3 NAT技术)
- 六、路由
一、网络层
网络层是计算机网络体系结构的第三层(OSI七层模型和TCP/IP 五层协议)。

网络层主要为了实现异构网络,统一互联 ,并为数据包在源主机和目的主机之间选择最佳的传输路径。
二、IP 协议格式
IP 协议是网络层最重要的协议,负责将数据包跨网络从主机A 传输到主机B。

IP 协议如何完成数据传输,就必须弄懂IP 的协议格式。

c
struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u8 ihl:4, /* 首部长度,单位4字节,最小5 */
version:4; /* IP版本,IPv4为4 */
#elif defined (__BIG_ENDIAN_BITFIELD)
__u8 version:4, /* IP版本 */
ihl:4; /* 首部长度 */
#else
#error "Please fix <asm/byteorder.h>"
#endif
__u8 tos; /* 服务类型 (Type of Service) */
__be16 tot_len; /* 总长度 (整个IP包长度,字节) */
__be16 id; /* 标识符,用于分片重组 */
__be16 frag_off; /* 分片偏移和标志 (DF, MF等) */
__u8 ttl; /* 生存时间 (Time To Live) */
__u8 protocol; /* 上层协议 (如TCP=6, UDP=17) */
__be16 check; /* 首部校验和 */
__be32 saddr; /* 源IP地址 */
__be32 daddr; /* 目的IP地址 */
/* 选项字段开始,长度可变,由ihl决定 */
};
2.1 IP 报头字段
(1)4位版本
指明IP 协议的版本:IPv4 与 IPv6。4即IPv4,6即IPv6。
(2)4位首部长度
IP 协议与TCP 协议的报头部分相同,由定长的20字节和选项组成。报头长度 = 4位首部长度 * 4(4位代表0 ~ 15,即 0 ~ 60,定长为20,则报头大小 20,60)。
(3)8位服务类型
(4)16位总长度
IP 报文的大小。
(5)8位生存时间
网络的拓扑结构已经非常复杂了,如果路由器的路由表配置错误或者发生回环,一个IP 数据包就可能会在几个路由器之间来回"循环 "打转。
这些无法到达目的地的报文会一直在网络中占用带宽和路由器资源,最终导致网络拥塞崩溃。所以,设置一个生存时间,一旦时间耗尽,路由器就会将数据包丢掉。
(6)8位协议
标识上层的协议类型:TCP ,UDP等,告诉目的主机的网络层,这个IP 数据包的"有效载荷"部分装的是什么上层协议的数据,从而交由哪个协议模块处理。
(7)16位首部校验和
检测IP 数据报首部在网络传输过程中是否发生了错误(如比特位翻转,数据损坏)。
(8)32位 源/目的IP
标识发送端和接收端。
IP 协议如何完成报头和有效载荷的分离和分用?
- 分离:4位首部长度。
- 分用:8位协议。
2.2 IP 报文分片与组装
还剩下中间三个字段,用于IP 报文的分片与组装。为什么要对IP报文进行分片呢?
数据链路层规定:IP 报文长度不能超过1500字节(MTU)。
当IP 报文长度超过1500字节,网络层就需要对报文分片。属于该报文的16位标识字段相同,即未来接收端根据16位标识就能判断哪些分片属于一个报文。
三位标志:
- 第一位保留(保留的意思是现在不用,但是还没想好说不定以后要用到)。
- 第二位置为1表示禁止分片,这时候如果报文长度超过MTU,IP模块就会丢弃报文。
- 第三位
MF标志:表示"更多分片",如果分片了的话,最后一个分片置为0,其他是1。类似于一个结束标记。
13位片偏移 :标识当前分片的有效载荷在原始未分片IP 数据包有效载荷中的相对起始位置,即计算片偏移时,不考虑IP 报头长度。
片偏移的单位是8字节,因为IP 报文的最大长度为16位( 2^16 - 1 = 65536字节),而片偏移只有13位,所以让13位片偏移乘以8表示实际偏移量。
假设一台主机需要发送 3800 字节的数据载荷,加上 20 字节固定 IP 报头,总长为 3820 字节。通过 MTU = 1500 字节的以太网链路(最大可承载数据载荷为 1500 - 20 = 1480 字节)时,分片过程如下:
| 分片序号 | 有效载荷范围 | 载荷长度 | MF标志 | 片偏移 |
|---|---|---|---|---|
| 分片1 | 0~1479 | 1480 | 1 | 0/8=0 |
| 分片2 | 1480~2959 | 1480 | 1 | 1480/8=185 |
| 分片3 | 2960~3799 | 840 | 0 | 2960/8=370 |
(1)怎么判断报文分片了?
如果接收到的IP 报文MF = 1,即表明该报文后面还有分片,即该报文是分片;即使MF = 0,片偏移不为零也可以判断是分片。
(2)如何组装?
首先,根据16位标识判断分片是否属于同一个报文;然后,根据MF + 片偏移排序拼接(按顺序放到接收缓冲区)。
(3)分片多了好吗?
显然,分片多了,丢包概率增加(如果接收方发现分片丢了,就会将其他分片丢掉,发送方收不到ACK,就会超时重传整个报文)。
现在就理解了,为什么在滑动窗口中要将数据划分位一段一段发送,即控制TCP报文长度不超过1500 - 20(IP报头无选项)= 1480字节。
三、子网划分
3.1 为什么要子网划分?
先讲一个故事:张三捡到一个钱包,钱包里只有一个只能看清楚学号的学生证,怎么快速把钱包还给失主。
背景:学校设计了学号(院号+专业号+班级),所以通过学号可以找到快速定位到每一个学生。

张三捡到钱包,把这个人的学号发送到自己的院群,学生会主席发现学号开头是06,肯定不是本学院的,所以学生会主席把学号转发到校群,机械学院学生会主席发现这是自己学院的,于是将学号转发到自己学院,李四立马发现是自己的钱包找到了。
如果没有将学号按照学院+专业+班级这样设计,而是对每个学生进行依次编号,那么张三再要把钱包还给李四,就需要找人一个一个的问:"你的学号是不是06321"。
张三和李四就像两台主机,主机A想把报文交给主机B。IP 让主机A能够找到主机B,子网划分就类似于划分学院,带上唯一编号,这样在进行查找时就能够更快的淘汰其他主机,缩小查找范围,大大提高了查找的效率。
3.2 怎么子网划分?
IP 由网络号和主机号构成。
- 同一个子网中网络号相同,不同子网的网络号不同。
- 同一个子网中主机号不同,不同子网的主机号可能相同。

子网划分是本质就是在32位IP 中划分网络号。
通过合理设置主机号和网络号,就可以保证在相互连接的网络中,每台主机的IP地址都不相同。那么问题来了,手动管理子网内的IP,是一个相当麻烦的事情。
- 有一种技术叫做DHCP,能够自动的给子网内新增主机节点分配IP地址,避免了手动管理IP的不便。
- 一般的路由器都带有DHCP功能。因此路由器也可以看做一个DHCP服务器。
那么对于不同的子网,如何互相连通呢?
由路由器进行连接,所以一个路由器至少有两个IP:
- WAN 口IP:即外网IP,面向运营商。
- LAN 口IP:即内网IP,面向局域网。
3.3 子网掩码
过去曾经提出一种划分网络号和主机号的方案,把所有IP 地址分为五类,如下图所示。

随着Internet的飞速发展,这种划分方案的局限性很快显现出来,大多数组织都申请B类网络地址,导致B类地址很快就分配完了,而A类却浪费了大量地址。
- 例如, 申请了一个B类地址,理论上一个子网内能允许6万5千多个主机,A类地址的子网内的主机数更多。
- 然而实际网络架设中,不会存在一个子网内有这么多的情况。因此大量的IP地址都被浪费掉了。
所以,引入了子网掩码。
- 子网掩码是一个正整数,前一部分全1,后一部分全零;
- 子网掩码与IP 按位与之后得到网络号;

通过子网掩码就可以灵活的控制网络号,避免了浪费IP。当子网主机较多就可以设置子网掩码小一点,反之就可以将子网掩码设置大一点。
子网掩码能不能解决IP不足的问题?
子网掩码本质是提高了IP的利用率,所以可以缓解IP不足的压力,但不能增加IP的数量。
四、私有IP和公网IP
公网 IP 是互联网上的"全球唯一身份证",用于在公网上标识一台设备;而 私有 IP(内网 IP)是局域网内部使用的"私有编号",专门用于局域网内部设备之间的通信。
4.1 私有 IP
为了避免 IPv4 地址过快枯竭,RFC 1918 规范专门划出了三段地址作为私有 IP 地址空间。任何组织和个人都可以无须申请、免费在局域网内部使用这些网段:
-
A 类私有地址:10.0.0.0 ~ 10.255.255.255 (掩码 /8,常用于大型企业网、云厂商 VPC 内部网络)
-
B 类私有地址:172.16.0.0 ~ 172.31.255.255 (掩码 /12,常用于中型企业或 Docker 容器网络)
-
C 类私有地址:192.168.0.0 ~ 192.168.255.255 (掩码 /16,最常见于家庭及小型办公室路由器)
主要特点:
-
可重复使用 :不同局域网(例如你家和邻居家)可以同时使用同一个私有 IP(如 192.168.1.100),彼此独立互不干扰 ,所以通过这种方式就可以解决IP 不足的问题。
-
公网不可直接路由:互联网上的骨干路由器会自动丢弃源或目的地址为私有 IP 的数据包,外部设备无法直接访问局域网内的私有 IP。
-
免费且本地管理:由本地路由器通过 DHCP 协议自动分配,不收取费用。
4.2 公网 IP
除了私有地址段以及特定用途的保留地址(如环回地址 127.0.0.1、链路本地地址 169.254.x.x)外,其余的合法 IPv4 地址都属于公网 IP。
主要特点:
-
全球唯一:在同一个时间点,全球互联网中绝不会有两台设备拥有相同的公网 IP。
-
公网直接可达:只要拥有公网 IP 并在对应的端口上监听,互联网上的任意设备均可以直接发起连接。
-
统一规划与收费:由国际机构(IANA/APNIC)统一分配给宽带运营商(ISP)或云服务商,用户通过按月/按年付费来获取(如家用宽带分配的动态公网 IP,或云服务器租用的固定公网 IP)。
4.3 一张图理解

- 路由器连接内网与外网,LAN 口IP 对内,WAN 口IP 对外。
- 路由过程中,子网IP 不能出现在公网上,所以在内网转发时会将子网IP替换位路由器的WAN 口IP(NAT 技术)。
- 我们在日常中接触到的都是子网IP,即路由器分配的IP。
- 报文经过出入口路由器转发之后进入公网。
五、理解公网
5.1 运营商
运营商负责铺设,维护覆盖全球的通信网络,并为个人与企业提供数据传输通道。
以物流系统为例:运营商不仅修筑高速公路(骨干光缆)和村村通道路(小区光纤/基站),还负责调度与转运每一个"数据包裹",确保它们准确送达。
运营商层级结构:

以运营商网络与用户个人网络的分界点划分私网与公网:
- 公网:包括骨干网、城域网以及接入网(运营商侧)。这是由运营商建设、维护并向公众提供开放数据传输能力的公共互联网。公网上的节点使用全球唯一的公网 IP 地址进行路由和通信。
- 私网(局域网):即用户自建的内部网络,如家用路由器,公司内网。
以家用路由器为例:
-
路由器的 WAN 口以外(外网): 连接运营商基站、OLT 光纤节点、城域网及骨干网,属于公网。
-
路由器的 LAN 口以内(内网): 连接手机、电脑、电视等终端设备,属于私网(通常分配 192.168.X.X 或 10.X.X.X 这类私网 IP,通过 NAT 地址转换技术共享一个公网 IP 上网)。

假如今天你要发送应该请求到抖音的服务器,源IP为192.168.1.201(子网掩码前24位为1),目的IP 为122.77.241.3(子网掩码前24位为1)。
路由器在进行路由时,目的IP 按位与子网掩码得到网络号为 122.77.241,自己所在内网网络号为192.168.1,对比发现不同,则直接通过家用路由器转发给出入口路由器(运营商),同时将源IP 替换为路由器WAN 口IP(NAT);然后出入口路由器再次NAT,并将请求在公网路由到抖音服务器。
5.2 公网
公网即运营商建设、维护并向公众提供开放数据传输能力的公共互联网。公网上的节点使用全球唯一的公网 IP 地址进行路由和通信。
拥有公网IP 的设备可以直接跨地域进行通信,因为公网上的主干路由器维护这完整的公网路由表。

5.3 NAT技术
NAT(网络地址转化)技术:在内网访问外网时替换的是 IP 报头的源 IP 地址(SNAT),而在外网返回响应数据时,替换对应目的 IP 地址(DNAT)。
同一个内网中不同的局域网中的主机最终在转发到外网时,都用的是出入口路由器的WAN 口IP,所以,即使IP 相同也没事。即NAT 是解决IP地址不够用的手段之一,是路由器的一个重要功能。
在绝大多数常见的网络环境中,NAT 还包含了传输层端口号的修改(称为NAPT 网络地址端口转换)。
今天西安的一个客户端(内网IP192.168.1.200:54321)与河北的服务器(公网IP 122.77.241.88:80)建立连接并通信:
客户端发送请求到服务端:
c
[西安客户端] Source: 192.168.1.200:54321 | Destination: 122.77.241.88:80
│ (经过西安家用路由器 SNAT)
▼
[运营商内网] Source: 10.1.1.2:60001 | Destination: 122.77.241.88:80
│ (经过西安运营商路由器 SNAT)
▼
[城域网/骨干网] Source: 122.77.241.4:40001 | Destination: 122.77.241.88:80
│ (骨干网 5.1.0.1 -> 5.5.0.1 路由转发,IP 保持不变)
▼
[河北出口网关] Source: 122.77.241.4:40001 | Destination: 122.77.241.88:80
│ (经过河北出口路由器 DNAT)
▼
[河北服务器] Source: 122.77.241.4:40001 | Destination: 192.168.1.100:80
响应包反向回传客户端:
cpp
服务器发包:源: 192.168.1.100:80 目的: 122.77.241.4:40001
河北出口 SNAT:转换为 源: 122.77.241.88:80 目的: 122.77.241.4:40001
公网路由回传:从河北(5.5.0.1)通过骨干网路由回西安出口(122.77.241.4)
西安两级 DNAT:反向还原为 10.1.1.2:60001 -> 192.168.1.200:54321,最终送达西安客户端
- 每次先将目的IP 和子网掩码进行按位与得到网络号,确定下一跳应该到哪个网段;
- 经过路由器路由时如果IP 报头源IP为内网IP则替换为WAN 口IP,通常也会替换TCP/UDP 报头的端口号,同时建立映射关系(NAT 映射表)。

- NATAT路由器将源地址从
10.0.0.10替换成全局的IP202.244.174.37; - NATAT路由器收到外部的数据时, 又会把目标IP从
202.244.174.37替换回10.0.0.10; - 在NATAT路由器内部,有一张自动生成的,用于地址转换的表;
- 当
10.0.0.10第一次向163.221.120.9发送数据时就会生成表中的映射关系;
NAPT IP/Port转换:
如果局域网内,有多个主机都访问同一个外网服务器,那么对于服务器返回的数据中,目的IP都是相同的。此时NAT路由器不能判定将这个数据包转发给哪个局域网的主机?
NAPT就可以解决这个问题,使用 IP + port 来建立这个关联关系(NAPT 映射表)。

六、路由
路由:在复杂的网络结构中,找出一条通往终点的路线。

路由器连接两个局域网,路由就是从局部到跨网络通信,每个路由器都会维护一张路由表,根据 IP报头的目的 IP 按位与 子网掩码得到目的网段的网络号,然后查路由表决定下一跳到哪个网段,依次类推,找到找到目的主机。
- 路由表可以使用route命令查看;
- 如果目的IP命中了路由表, 就直接转发即可;
- 路由表中的每一行,主要由下一跳地址和发送接口两部分组成,当目的地址与路由表中其它行都不匹配时,就按缺省路由条目规定的接口发送到下一跳地址。

Interface(出接口)
含义: 路由器是依靠哪个物理或逻辑网卡(接口)把数据包发送出去的。
-
eth0 (WAN):路由器的外网口(广域网接口)。
-
vlan10 (LAN):路由器的内网口(局域网接口),通过 VLAN 虚拟出来的接口。
-
lo:本地环回接口(Loopback),数据包只会绕回到设备自身。
最后一项即缺省路由。
到这里网络层的讲解就结束了!
目前我们已经知道如何通过 IP进行路由,而怎么把报文交给路由器,以及目的主机,就需要数据链路层出手,下一篇我们就彻底弄清楚报文如何被送达目的主机。