4566 字
23 分钟
网络:网际层

在 TCP/IP 四层模型中,网际层负责在不同网络之间传递数据,并通过 IP 地址和路由机制实现跨网络通信。

这一层最核心的概念包括 IP、IPv4、IPv6、IP 地址、子网、CIDR、路由、下一跳、ICMP 以及 ARP。理解这些概念之后,才能真正弄清楚数据包为什么知道“去哪里”、下一跳又是谁。

网际层是什么#

TCP/IP 四层模型可以简单表示为:

┌────────────────────┐
│ 应用层 │
├────────────────────┤
│ 传输层 │
├────────────────────┤
│ 网际层 │
├────────────────────┤
│ 网络接口层 │
└────────────────────┘

前一篇介绍了网络接口层,主要关注:

Ethernet
MAC
Frame
网卡
交换机
物理介质

而网际层进一步解决:

数据应该发往哪个网络,以及如何从当前网络到达目标网络。

可以简单理解为:

网络接口层
↓
负责当前链路上的传输
网际层
↓
负责跨网络寻址与转发

例如:

主机 A
192.168.1.10
│
▼
路由器
│
▼
网络 B
│
▼
主机 B
192.168.2.20

这里:

192.168.1.10
↓
源 IP
192.168.2.20
↓
目标 IP

网际层根据:

目标 IP
+
路由表

决定数据应该往哪里转发。


IP#

什么是 IP#

IP(Internet Protocol)是 TCP/IP 网络体系中的核心网际层协议。

它提供一种:

跨网络传输数据报的统一寻址和转发机制。

IP 的核心目标不是保证:

一定送达
一定按顺序到达
一定不重复

而是提供:

寻址
分组
转发

这些基本能力。

因此:

IP 本身并不提供可靠传输。

可靠传输等机制由更上层的协议负责,例如 TCP。


IP Packet#

网际层传输的基本数据单位通常称为:

IP Packet(IP 数据包)

例如:

应用数据
↓
传输层数据
↓
IP Packet
↓
Ethernet Frame

因此数据在协议栈中的封装关系可以理解成:

Application Data
↓
TCP Segment / UDP Datagram
↓
IP Packet
↓
Ethernet Frame

本文重点关注:

IP Packet

这一层。


IPv4#

IPv4 是什么#

IPv4 是目前仍然广泛使用的 Internet Protocol 版本。

IPv4 地址长度为:

32 bit

通常写成:

192.168.1.10

也就是四个十进制数字:

192 . 168 . 1 . 10

每一部分称为一个:

Octet(八位组)

每个八位组:

8 bit

因此:

4 × 8 bit
=
32 bit

IPv4 地址的二进制形式#

例如:

192.168.1.10

可以表示成:

11000000.10101000.00000001.00001010

虽然平时通常使用十进制表示,但理解二进制非常重要,因为:

子网掩码
CIDR
网络地址
广播地址

都与位运算密切相关。


IPv4 地址结构#

一个 IPv4 地址并不是简单的:

“一个数字”

在实际网络中,它通常可以拆分为:

网络部分
+
主机部分

例如:

192.168.1.10/24

可以理解成:

网络部分
192.168.1
主机部分
10

因此:

IP 地址
│
├── Network
└── Host

其中具体有多少位属于网络部分,由:

子网掩码
CIDR 前缀长度

决定。


子网掩码#

什么是 Subnet Mask#

IPv4 中经常看到:

255.255.255.0

这样的子网掩码。

它用于区分:

网络部分
主机部分

例如:

IP:
192.168.1.10
Mask:
255.255.255.0

转换成二进制:

IP
11000000.10101000.00000001.00001010
Mask
11111111.11111111.11111111.00000000

可以看到:

前 24 bit
↓
网络部分
后 8 bit
↓
主机部分

CIDR#

什么是 CIDR#

CIDR(Classless Inter-Domain Routing)使用:

/

后面的数字表示网络前缀长度。

例如:

192.168.1.10/24

其中:

/24

表示:

前 24 bit 属于网络前缀。

因此:

192.168.1.10/24

对应:

255.255.255.0

常见 CIDR#

例如:

/8
/16
/24
/25
/26
/27
/28
/30
/32

都可能在实际网络中出现。

其中:

/8

表示:

8 bit 网络前缀

而:

/24

表示:

24 bit 网络前缀

前缀越长:

网络部分越大
主机空间越小

前缀越短:

网络部分越小
主机空间越大

网络地址#

假设:

192.168.1.10/24

其网络部分是:

192.168.1

因此对应的网络地址是:

192.168.1.0

可以理解为:

192.168.1.0/24

代表这个子网本身。


广播地址#

对于 IPv4 广播型网络:

192.168.1.0/24

对应广播地址通常为:

192.168.1.255

因为:

前 24 bit
↓
网络部分
后 8 bit
↓
主机部分

将所有主机位设置为 1:

11111111

就是:

255

所以:

网络地址
192.168.1.0
广播地址
192.168.1.255

主机地址范围#

对于:

192.168.1.0/24

传统 IPv4 子网划分中:

网络地址
192.168.1.0
可用主机地址
192.168.1.1
~
192.168.1.254
广播地址
192.168.1.255

因此共有:

2^8 = 256

个地址。

通常有:

256
-
2
=
254

个传统意义上的可用主机地址。

不过现代 IPv4 网络还有:

/31
/32

等特殊使用方式,因此不能把:

“减 2”

当成所有 CIDR 前缀的绝对规则。


子网划分#

为什么需要子网#

如果一个网络包含大量主机:

Host 1
Host 2
Host 3
...
Host 5000

全部放在一个网段中可能并不合理。

可以进行子网划分:

大网络
│
├── 子网 A
├── 子网 B
├── 子网 C
└── 子网 D

这样可以:

控制地址范围
划分网络边界
减少广播域规模
便于路由
便于网络管理

子网划分示例#

假设:

192.168.1.0/24

需要划分成两个子网。

可以使用:

/25

于是:

192.168.1.0/25
192.168.1.128/25

第一个:

192.168.1.0
~
192.168.1.127

第二个:

192.168.1.128
~
192.168.1.255

可以理解为:

192.168.1.0/24
│
├── 192.168.1.0/25
│
└── 192.168.1.128/25

私有 IPv4 地址#

RFC 1918 定义了用于私有网络的 IPv4 地址空间:

10.0.0.0/8
172.16.0.0/12
192.168.0.0/16

这些地址通常用于:

家庭局域网
企业内网
数据中心内部网络

例如:

192.168.1.10

就是常见的私有 IPv4 地址。

私有地址本身不能作为公网 Internet 中的普通全局可路由地址使用。

RFC 1918 对这些地址空间进行了定义:

RFC 1918 — Address Allocation for Private Internets。


公有 IP 与私有 IP#

可以简单区分:

Private IP
↓
用于私有网络
Public IP
↓
可在 Internet 公共网络中进行全局寻址

例如家庭网络:

电脑
192.168.1.10
│
▼
路由器
│
▼
公网 IP
│
▼
Internet

这里:

192.168.1.10

是私有地址。

而路由器外部接口可能具有公网地址。

这也是后续学习:

NAT

的重要基础。


IPv4 首部#

一个 IPv4 Packet 可以简化理解为:

┌───────────────────────────┐
│ IPv4 Header │
├───────────────────────────┤
│ │
│ Payload │
│ │
└───────────────────────────┘

IPv4 首部包含很多字段,例如:

Version
IHL
Total Length
Identification
Flags
Fragment Offset
TTL
Protocol
Header Checksum
Source Address
Destination Address

其中比较重要的有:

Source Address
Destination Address
TTL
Protocol

Source Address#

表示:

数据包的源 IPv4 地址。

例如:

192.168.1.10

Destination Address#

表示:

数据包的目标 IPv4 地址。

例如:

8.8.8.8

于是:

Source
↓
192.168.1.10
Destination
↓
8.8.8.8

这构成了 IP 寻址的核心。


TTL#

TTL(Time To Live)用于限制 IPv4 数据包可以经过的路由跳数。

每经过一个路由器,TTL 通常会:

减 1

例如:

TTL = 64

经过一个三层转发设备后:

TTL = 63

如果最终变成:

0

数据包不能继续正常转发。

这样可以防止由于错误路由造成的数据包无限循环。


Protocol#

IPv4 首部中的:

Protocol

用于标识 Payload 中承载的上层协议。

例如:

TCP
UDP
ICMP

因此:

IP Packet
│
├── Protocol = TCP
│
└── Payload = TCP Segment

也就是说,IP 不需要理解 TCP 的具体内容,只需要知道:

Payload 是什么类型

即可交给对应的上层协议处理。


IPv6#

为什么需要 IPv6#

IPv4 地址只有:

32 bit

IPv6 则使用:

128 bit

因此可提供巨大的地址空间。

IPv6 地址通常写成十六进制,例如:

2001:db8::1

一个 IPv6 地址由:

128 bit

组成。


IPv6 地址表示#

例如完整形式:

2001:0db8:0000:0000:0000:0000:0000:0001

可以压缩成:

2001:db8::1

压缩规则允许:

连续的全 0 分组

使用:

::

表示。

因此:

2001:0db8:0000:0000:0000:0000:0000:0001

可以写成:

2001:db8::1

IPv6 地址和文本表示方法由 RFC 4291、RFC 5952 等标准定义。


IPv6 地址类型#

IPv6 中常见的地址类型包括:

Unicast
Multicast
Anycast

与 IPv4 广播不同:

IPv6 没有传统意义上的广播地址。

需要向多个主机发送时,IPv6 使用:

Multicast

等机制。


IPv6 首部#

IPv6 首部相比 IPv4 有明显不同。

可以简化表示:

┌───────────────────────────┐
│ IPv6 Header │
├───────────────────────────┤
│ │
│ Payload │
│ │
└───────────────────────────┘

核心字段包括:

Version
Traffic Class
Flow Label
Payload Length
Next Header
Hop Limit
Source Address
Destination Address

其中:

Hop Limit

可以理解成 IPv4 中:

TTL

类似的跳数限制机制。

而:

Next Header

承担类似于 IPv4 Protocol 字段的一部分作用,用于指示后续头部或上层协议。


IPv4 与 IPv6#

可以简单对比:

特性IPv4IPv6
地址长度32 bit128 bit
地址表示十进制点分十六进制冒号分隔
广播支持无传统广播
地址空间较小极大
地址发现ARP 等NDP
TTL 类字段TTLHop Limit
首部校验和IPv4 Header Checksum基本首部不提供同样的 Header Checksum

因此:

IPv4
↓
历史悠久,部署广泛
IPv6
↓
更大的地址空间

路由#

什么是 Routing#

有了 IP 地址之后,还需要解决一个问题:

数据包应该经过哪条路径?

这就是:

Routing(路由)

假设:

主机 A
192.168.1.10
│
▼
路由器 R1
│
▼
路由器 R2
│
▼
主机 B
192.168.3.20

从 A 的角度:

目标
192.168.3.20

并不在本地网络中。

于是 A 需要根据:

Routing Table

决定:

下一跳

路由表#

路由器以及主机本身都可能拥有路由表。

例如:

Destination Gateway Dev
192.168.1.0/24 on-link eth0
192.168.2.0/24 192.168.1.1 eth0
0.0.0.0/0 192.168.1.1 eth0

可以理解成:

目标网络
↓
下一跳
↓
出口接口

Linux 中可以使用:

Terminal window
ip route

查看路由表。

后续 Linux 网络管理文章中会详细介绍:

Terminal window
ip route

以及实际路由配置。

本文主要关注协议原理。


默认路由#

路由表中经常看到:

0.0.0.0/0

它表示:

匹配任意 IPv4 目标地址的默认路由。

例如:

0.0.0.0/0 via 192.168.1.1

表示:

如果没有更具体的路由
↓
把数据交给
192.168.1.1

因此可以简单理解为:

已知具体路径
↓
使用更具体路由
没有匹配
↓
使用默认路由

最长前缀匹配#

路由表可能同时存在:

10.0.0.0/8
10.1.0.0/16
10.1.2.0/24

如果目标是:

10.1.2.50

那么三个路由都可能匹配。

此时使用:

最长前缀匹配(Longest Prefix Match)

即选择:

/24

而不是:

/16

或者:

/8

因为:

/24

更具体。

可以理解为:

多个路由匹配
│
▼
比较前缀长度
│
▼
选择最长前缀

这正是 CIDR 和现代 IP 路由紧密结合的重要原因。


下一跳#

假设:

主机 A
192.168.1.10
目标 B
192.168.3.20

A 的路由表可能认为:

192.168.3.0/24
↓
下一跳 192.168.1.1

那么:

最终目标
↓
192.168.3.20
当前下一跳
↓
192.168.1.1

这两个概念不能混淆。

因此:

路由解决“下一步往哪里走”,而不是要求每一台设备提前知道完整的端到端路径。


ARP#

ARP 是什么#

网络接口层负责同一链路上的通信,常见概念包括:

Ethernet
MAC
Frame

现在再来看:

IP

就会遇到一个问题:

我知道下一跳 IP
↓
但不知道下一跳 MAC

IPv4 网络中,这就是:

ARP(Address Resolution Protocol)

所解决的问题。

RFC 826 对 ARP 的核心作用进行了定义:

将协议地址转换为本地网络地址。

例如:

192.168.1.1
↓
ARP
↓
AA:BB:CC:DD:EE:FF

因此:

IP 地址
↓
ARP
↓
MAC 地址

ARP Request#

假设:

A
IP = 192.168.1.10
MAC = AA:AA:AA:AA:AA:AA
B
IP = 192.168.1.20
MAC = BB:BB:BB:BB:BB:BB

A 想知道:

192.168.1.20

对应的 MAC。

A 发送 ARP Request:

谁是 192.168.1.20?

由于目标 MAC 尚未知,请求通常发送到:

ff:ff:ff:ff:ff:ff

也就是 Ethernet 广播地址。


ARP Reply#

B 收到 ARP Request 后发现:

Target IP
=
192.168.1.20

正是自己。

于是返回:

192.168.1.20
↓
BB:BB:BB:BB:BB:BB

A 得到:

IP → MAC

的映射。

随后:

IP Packet
↓
Ethernet Frame
↓
Destination MAC = BB:BB:BB:BB:BB:BB

ARP Cache#

主机不会每发送一个 IP Packet 就重新进行 ARP。

通常会暂时缓存:

IP
↓
MAC

映射。

Linux 中可以使用:

Terminal window
ip neigh

查看邻居信息。

例如:

192.168.1.1 dev eth0 lladdr aa:bb:cc:dd:ee:ff REACHABLE

这里表示:

192.168.1.1
↓
aa:bb:cc:dd:ee:ff

为什么远程目标不是直接 ARP#

这是理解:

ARP
+
路由

关系的关键。

假设:

主机 A
192.168.1.10/24
目标 B
192.168.2.20

A 看到:

192.168.2.20

不属于:

192.168.1.0/24

因此它不会直接:

ARP 192.168.2.20

而是:

目标 IP
↓
查路由
↓
找到下一跳
192.168.1.1
↓
ARP
↓
192.168.1.1 的 MAC

然后:

Ethernet Frame
Dst MAC = 网关 MAC

发给路由器。

因此:

ARP 解析的是当前链路上的下一跳,而不是一定解析最终目标主机。


路由器如何转发 IP Packet#

假设:

A
192.168.1.10
│
▼
R1
│
▼
R2
│
▼
B
192.168.3.20

A 首先:

目标 = 192.168.3.20

查自己的路由表:

下一跳 = R1

然后:

ARP
↓
R1 MAC

封装成:

Ethernet Frame

发送给 R1。

R1 收到后:

剥离链路层封装
↓
读取 IP Packet
↓
检查目标 IP
↓
查路由表
↓
确定下一跳
↓
重新封装新的链路层帧
↓
发送

也就是说:

A → R1
R1 → R2
R2 → B

每一跳都可能重新进行:

链路层封装

但 IP Packet 继续承担:

端到端目标

IP 与 MAC 的关系#

现在可以把:

IP
MAC
ARP
Ethernet
Routing

之间的关系串起来。

目标 IP
│
▼
路由表
│
▼
下一跳 IP
│
▼
ARP
│
▼
下一跳 MAC
│
▼
Ethernet Frame
│
▼
发送

因此:

IP
↓
三层寻址
MAC
↓
当前链路寻址
ARP
↓
IPv4 下一跳 IP → MAC
Ethernet
↓
当前链路上的帧传输
Routing
↓
决定下一跳

ICMP#

什么是 ICMP#

ICMP(Internet Control Message Protocol)是与 IP 配套的重要控制协议。

它主要用于:

错误报告
诊断
网络控制信息

而不是用来承载普通应用数据。

因此:

应用数据
↓
TCP / UDP

而:

网络控制与诊断
↓
ICMP

ping#

最熟悉的 ICMP 使用场景就是:

Terminal window
ping 192.168.1.1

IPv4 中通常使用:

ICMP Echo Request
ICMP Echo Reply

过程可以简单理解为:

A
│
│ Echo Request
▼
B
│
│ Echo Reply
▼
A

因此:

ping 能够帮助判断目标是否能够在 IP 层面进行基本的连通性响应。

但:

ping 通并不意味着应用服务一定正常。

例如:

ICMP 可以通信

并不代表:

TCP 80 一定开放
HTTP 服务一定正常

因为它们属于不同层次。


ICMP 错误消息#

ICMP 还可以用于通知网络错误。

例如:

目标不可达
TTL 超时

等。

其中:

Destination Unreachable
Time Exceeded

都是常见的 ICMP 消息类型。

例如:

数据包
↓
经过多个路由器
↓
TTL 不断减少
↓
TTL = 0
↓
路由器丢弃数据包
↓
发送 ICMP Time Exceeded

这也是:

Terminal window
traceroute

等工具能够工作的基础之一。


IP 并不可靠#

到这里可以进一步理解 IP 的设计思想。

IP 提供的是:

Best Effort

即:

尽力而为的数据报服务。

它不保证:

一定到达
一定按顺序到达
一定只到达一次
一定不会丢包

例如:

Packet A
Packet B
Packet C

理论上可能出现:

B
A
C

也可能:

A
C

因为:

B

可能丢失。

因此可靠传输通常由:

TCP

这样的传输层协议提供。


IPv4 分片#

IPv4 数据包可能遇到:

MTU(Maximum Transmission Unit)

限制。

例如某条链路能够承载的最大 IP 数据包长度有限。

如果一个 IPv4 Packet 太大:

Packet
│
▼
超过下一链路 MTU

在满足条件时,IPv4 可以进行:

Fragmentation(分片)

可以简单理解成:

原始 Packet
│
▼
┌────┬────┬────┐
│ F1 │ F2 │ F3 │
└────┴────┴────┘

到达目的地后,再进行重组。

IPv4 首部中的:

Identification
Flags
Fragment Offset

等字段与分片有关。


IPv6 与分片#

IPv6 的分片机制与 IPv4 不同。

IPv6 路由器不会像 IPv4 那样在转发过程中随意对数据包进行分片。

如果需要分片,通常由发送端通过:

Fragment Extension Header

进行处理。

因此:

IPv4
↓
路由器可能进行分片
IPv6
↓
通常由发送端处理分片

这也是 IPv4 和 IPv6 设计上的重要区别之一。


网际层的完整通信模型#

现在可以把前面的概念全部串起来。

假设:

主机 A
192.168.1.10/24
目标 B
192.168.3.20

A 想向 B 发送数据。

完整过程可以简化为:

应用数据
│
▼
传输层数据
│
▼
IPv4 Packet
│
│ Destination = 192.168.3.20
▼
查询路由表
│
▼
发现目标不在本地网络
│
▼
选择下一跳
│
▼
例如 192.168.1.1
│
▼
ARP 查询
│
▼
得到网关 MAC
│
▼
Ethernet Frame
│
▼
交换机
│
▼
路由器
│
▼
重新进行路由判断
│
▼
下一跳
│
▼
……
│
▼
目标网络
│
▼
主机 B

这里真正值得注意的是:

Ethernet
↓
负责一跳
IP
↓
负责跨网络寻址
Routing
↓
决定下一跳
ARP
↓
IPv4 下一跳 IP → MAC
ICMP
↓
网络控制与诊断

网络接口层与网际层#

现在可以把前两层放在一起理解。

┌──────────────────────────────┐
│ 网际层 │
│ │
│ IP / IPv4 / IPv6 │
│ Routing / ICMP │
│ │
└──────────────┬───────────────┘
│
▼
┌──────────────────────────────┐
│ 网络接口层 │
│ │
│ Ethernet / MAC / Frame │
│ NIC / 双绞线 / 光纤 / Wi-Fi │
│ │
└──────────────────────────────┘

可以从两个问题来理解:

网际层
↓
“数据应该去哪个网络、哪个 IP?”
网络接口层
↓
“这一跳应该通过哪个链路、哪个接口发送?”

这也是:

IP

和:

MAC

最核心的区别。


网际层的整体模型#

最后可以将这一层浓缩成:

网际层
│
┌─────────────────┼─────────────────┐
│ │ │
▼ ▼ ▼
IP Routing ICMP
│ │ │
┌────┴────┐ │ 诊断 / 控制
│ │ │
IPv4 IPv6 │
│ │ │
│ 128 bit │
32 bit │
│ │
└──────────┬─────────────┘
│
▼
IP Packet
│
▼
下一跳 IP / 路由
│
▼
ARP
│
▼
下一跳 MAC
│
▼
Ethernet Frame
│
▼
网络接口层

因此,网际层最核心的一条逻辑链可以浓缩成:

目标 IP
↓
判断是否本地网络
↓
查路由表
↓
确定下一跳
↓
IPv4 场景下通过 ARP 获取下一跳 MAC
↓
交给网络接口层
↓
发送 Ethernet Frame

而在跨网络通信中:

IP Packet
↓
Router
↓
重新查路由
↓
下一跳
↓
重新封装链路层帧
↓
继续转发

因此:

IP 负责跨网络寻址,路由负责决定下一跳,链路层负责当前这一跳的实际传输。

理解这一点之后,下一层的:

TCP
UDP
端口
连接
可靠传输

就有了明确的基础。

外部参考#

网络:网际层
https://tamakara.top/posts/学习笔记/网络网际层/
作者
魂辛カラ
发布于
2026-09-13
许可协议
CC BY-NC-SA 4.0