在 TCP/IP 四层模型中,网际层负责在不同网络之间传递数据,并通过 IP 地址和路由机制实现跨网络通信。
这一层最核心的概念包括 IP、IPv4、IPv6、IP 地址、子网、CIDR、路由、下一跳、ICMP 以及 ARP。理解这些概念之后,才能真正弄清楚数据包为什么知道“去哪里”、下一跳又是谁。
网际层是什么
TCP/IP 四层模型可以简单表示为:
┌────────────────────┐│ 应用层 │├────────────────────┤│ 传输层 │├────────────────────┤│ 网际层 │├────────────────────┤│ 网络接口层 │└────────────────────┘前一篇介绍了网络接口层,主要关注:
EthernetMACFrame网卡交换机物理介质而网际层进一步解决:
数据应该发往哪个网络,以及如何从当前网络到达目标网络。
可以简单理解为:
网络接口层↓负责当前链路上的传输
网际层↓负责跨网络寻址与转发例如:
主机 A192.168.1.10 │ ▼路由器 │ ▼网络 B │ ▼主机 B192.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 bitIPv4 地址的二进制形式
例如:
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转换成二进制:
IP11000000.10101000.00000001.00001010
Mask11111111.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 1Host 2Host 3...Host 5000全部放在一个网段中可能并不合理。
可以进行子网划分:
大网络 │ ├── 子网 A ├── 子网 B ├── 子网 C └── 子网 D这样可以:
控制地址范围划分网络边界减少广播域规模便于路由便于网络管理子网划分示例
假设:
192.168.1.0/24需要划分成两个子网。
可以使用:
/25于是:
192.168.1.0/25192.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 首部包含很多字段,例如:
VersionIHLTotal LengthIdentificationFlagsFragment OffsetTTLProtocolHeader ChecksumSource AddressDestination Address其中比较重要的有:
Source AddressDestination AddressTTLProtocolSource Address
表示:
数据包的源 IPv4 地址。
例如:
192.168.1.10Destination 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 中承载的上层协议。
例如:
TCPUDPICMP因此:
IP Packet │ ├── Protocol = TCP │ └── Payload = TCP Segment也就是说,IP 不需要理解 TCP 的具体内容,只需要知道:
Payload 是什么类型即可交给对应的上层协议处理。
IPv6
为什么需要 IPv6
IPv4 地址只有:
32 bitIPv6 则使用:
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::1IPv6 地址和文本表示方法由 RFC 4291、RFC 5952 等标准定义。
IPv6 地址类型
IPv6 中常见的地址类型包括:
UnicastMulticastAnycast与 IPv4 广播不同:
IPv6 没有传统意义上的广播地址。
需要向多个主机发送时,IPv6 使用:
Multicast等机制。
IPv6 首部
IPv6 首部相比 IPv4 有明显不同。
可以简化表示:
┌───────────────────────────┐│ IPv6 Header │├───────────────────────────┤│ ││ Payload ││ │└───────────────────────────┘核心字段包括:
VersionTraffic ClassFlow LabelPayload LengthNext HeaderHop LimitSource AddressDestination Address其中:
Hop Limit可以理解成 IPv4 中:
TTL类似的跳数限制机制。
而:
Next Header承担类似于 IPv4 Protocol 字段的一部分作用,用于指示后续头部或上层协议。
IPv4 与 IPv6
可以简单对比:
| 特性 | IPv4 | IPv6 |
|---|---|---|
| 地址长度 | 32 bit | 128 bit |
| 地址表示 | 十进制点分 | 十六进制冒号分隔 |
| 广播 | 支持 | 无传统广播 |
| 地址空间 | 较小 | 极大 |
| 地址发现 | ARP 等 | NDP |
| TTL 类字段 | TTL | Hop Limit |
| 首部校验和 | IPv4 Header Checksum | 基本首部不提供同样的 Header Checksum |
因此:
IPv4↓历史悠久,部署广泛
IPv6↓更大的地址空间路由
什么是 Routing
有了 IP 地址之后,还需要解决一个问题:
数据包应该经过哪条路径?
这就是:
Routing(路由)
假设:
主机 A192.168.1.10 │ ▼路由器 R1 │ ▼路由器 R2 │ ▼主机 B192.168.3.20从 A 的角度:
目标192.168.3.20并不在本地网络中。
于是 A 需要根据:
Routing Table决定:
下一跳路由表
路由器以及主机本身都可能拥有路由表。
例如:
Destination Gateway Dev192.168.1.0/24 on-link eth0192.168.2.0/24 192.168.1.1 eth00.0.0.0/0 192.168.1.1 eth0可以理解成:
目标网络 ↓下一跳 ↓出口接口Linux 中可以使用:
ip route查看路由表。
后续 Linux 网络管理文章中会详细介绍:
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/810.1.0.0/1610.1.2.0/24如果目标是:
10.1.2.50那么三个路由都可能匹配。
此时使用:
最长前缀匹配(Longest Prefix Match)
即选择:
/24而不是:
/16或者:
/8因为:
/24更具体。
可以理解为:
多个路由匹配 │ ▼比较前缀长度 │ ▼选择最长前缀这正是 CIDR 和现代 IP 路由紧密结合的重要原因。
下一跳
假设:
主机 A192.168.1.10
目标 B192.168.3.20A 的路由表可能认为:
192.168.3.0/24 ↓下一跳 192.168.1.1那么:
最终目标↓192.168.3.20
当前下一跳↓192.168.1.1这两个概念不能混淆。
因此:
路由解决“下一步往哪里走”,而不是要求每一台设备提前知道完整的端到端路径。
ARP
ARP 是什么
网络接口层负责同一链路上的通信,常见概念包括:
EthernetMACFrame现在再来看:
IP就会遇到一个问题:
我知道下一跳 IP↓但不知道下一跳 MACIPv4 网络中,这就是:
ARP(Address Resolution Protocol)
所解决的问题。
RFC 826 对 ARP 的核心作用进行了定义:
将协议地址转换为本地网络地址。
例如:
192.168.1.1 ↓ARP ↓AA:BB:CC:DD:EE:FF因此:
IP 地址 ↓ARP ↓MAC 地址ARP Request
假设:
AIP = 192.168.1.10MAC = AA:AA:AA:AA:AA:AA
BIP = 192.168.1.20MAC = BB:BB:BB:BB:BB:BBA 想知道:
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:BBA 得到:
IP → MAC的映射。
随后:
IP Packet↓Ethernet Frame↓Destination MAC = BB:BB:BB:BB:BB:BBARP Cache
主机不会每发送一个 IP Packet 就重新进行 ARP。
通常会暂时缓存:
IP↓MAC映射。
Linux 中可以使用:
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+路由关系的关键。
假设:
主机 A192.168.1.10/24
目标 B192.168.2.20A 看到:
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 FrameDst MAC = 网关 MAC发给路由器。
因此:
ARP 解析的是当前链路上的下一跳,而不是一定解析最终目标主机。
路由器如何转发 IP Packet
假设:
A192.168.1.10 │ ▼R1 │ ▼R2 │ ▼B192.168.3.20A 首先:
目标 = 192.168.3.20查自己的路由表:
下一跳 = R1然后:
ARP↓R1 MAC封装成:
Ethernet Frame发送给 R1。
R1 收到后:
剥离链路层封装 ↓读取 IP Packet ↓检查目标 IP ↓查路由表 ↓确定下一跳 ↓重新封装新的链路层帧 ↓发送也就是说:
A → R1R1 → R2R2 → B每一跳都可能重新进行:
链路层封装但 IP Packet 继续承担:
端到端目标IP 与 MAC 的关系
现在可以把:
IPMACARPEthernetRouting之间的关系串起来。
目标 IP │ ▼ 路由表 │ ▼ 下一跳 IP │ ▼ ARP │ ▼ 下一跳 MAC │ ▼ Ethernet Frame │ ▼ 发送因此:
IP↓三层寻址
MAC↓当前链路寻址
ARP↓IPv4 下一跳 IP → MAC
Ethernet↓当前链路上的帧传输
Routing↓决定下一跳ICMP
什么是 ICMP
ICMP(Internet Control Message Protocol)是与 IP 配套的重要控制协议。
它主要用于:
错误报告诊断网络控制信息而不是用来承载普通应用数据。
因此:
应用数据↓TCP / UDP而:
网络控制与诊断↓ICMPping
最熟悉的 ICMP 使用场景就是:
ping 192.168.1.1IPv4 中通常使用:
ICMP Echo RequestICMP Echo Reply过程可以简单理解为:
A │ │ Echo Request ▼B │ │ Echo Reply ▼A因此:
ping能够帮助判断目标是否能够在 IP 层面进行基本的连通性响应。
但:
ping 通并不意味着应用服务一定正常。
例如:
ICMP 可以通信并不代表:
TCP 80 一定开放HTTP 服务一定正常因为它们属于不同层次。
ICMP 错误消息
ICMP 还可以用于通知网络错误。
例如:
目标不可达TTL 超时等。
其中:
Destination UnreachableTime Exceeded都是常见的 ICMP 消息类型。
例如:
数据包 ↓经过多个路由器 ↓TTL 不断减少 ↓TTL = 0 ↓路由器丢弃数据包 ↓发送 ICMP Time Exceeded这也是:
traceroute等工具能够工作的基础之一。
IP 并不可靠
到这里可以进一步理解 IP 的设计思想。
IP 提供的是:
Best Effort即:
尽力而为的数据报服务。
它不保证:
一定到达一定按顺序到达一定只到达一次一定不会丢包例如:
Packet APacket BPacket C理论上可能出现:
BAC也可能:
AC因为:
B可能丢失。
因此可靠传输通常由:
TCP这样的传输层协议提供。
IPv4 分片
IPv4 数据包可能遇到:
MTU(Maximum Transmission Unit)
限制。
例如某条链路能够承载的最大 IP 数据包长度有限。
如果一个 IPv4 Packet 太大:
Packet │ ▼超过下一链路 MTU在满足条件时,IPv4 可以进行:
Fragmentation(分片)
可以简单理解成:
原始 Packet │ ▼┌────┬────┬────┐│ F1 │ F2 │ F3 │└────┴────┴────┘到达目的地后,再进行重组。
IPv4 首部中的:
IdentificationFlagsFragment Offset等字段与分片有关。
IPv6 与分片
IPv6 的分片机制与 IPv4 不同。
IPv6 路由器不会像 IPv4 那样在转发过程中随意对数据包进行分片。
如果需要分片,通常由发送端通过:
Fragment Extension Header进行处理。
因此:
IPv4↓路由器可能进行分片
IPv6↓通常由发送端处理分片这也是 IPv4 和 IPv6 设计上的重要区别之一。
网际层的完整通信模型
现在可以把前面的概念全部串起来。
假设:
主机 A192.168.1.10/24
目标 B192.168.3.20A 想向 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 负责跨网络寻址,路由负责决定下一跳,链路层负责当前这一跳的实际传输。
理解这一点之后,下一层的:
TCPUDP端口连接可靠传输就有了明确的基础。