文章目录
-
- 网络层与IP协议详解:从地址到路由的完整指南
- 一、网络层的作用
-
- [1.1 什么是网络层](#1.1 什么是网络层)
- [1.2 网络层vs数据链路层](#1.2 网络层vs数据链路层)
- [1.3 基本概念](#1.3 基本概念)
-
- [1. 主机(Host)](#1. 主机(Host))
- [2. 路由器(Router)](#2. 路由器(Router))
- [3. 节点(Node)](#3. 节点(Node))
- 二、IP协议报文格式
-
- [2.1 IP报文的整体结构](#2.1 IP报文的整体结构)
- [2.2 IP首部详解](#2.2 IP首部详解)
-
- [1. 4位版本号(Version)](#1. 4位版本号(Version))
- [2. 4位首部长度(Header Length)](#2. 4位首部长度(Header Length))
- [3. 8位服务类型(Type Of Service, TOS)](#3. 8位服务类型(Type Of Service, TOS))
- [4. 16位总长度(Total Length)](#4. 16位总长度(Total Length))
- [5. 16位标识(Identification)](#5. 16位标识(Identification))
- [6. 3位标志字段(Flags)](#6. 3位标志字段(Flags))
- [7. 13位分片偏移(Fragment Offset)](#7. 13位分片偏移(Fragment Offset))
- [8. 8位生存时间(Time To Live, TTL)](#8. 8位生存时间(Time To Live, TTL))
- [9. 8位协议(Protocol)](#9. 8位协议(Protocol))
- [10. 16位首部校验和(Header Checksum)](#10. 16位首部校验和(Header Checksum))
- [11. 32位源地址和32位目标地址](#11. 32位源地址和32位目标地址)
- [12. 选项字段(Options)](#12. 选项字段(Options))
- 三、IP地址与子网划分
- 四、特殊的IP地址
-
- [4.1 网络地址](#4.1 网络地址)
- [4.2 广播地址](#4.2 广播地址)
- [4.3 本机回环地址](#4.3 本机回环地址)
- [4.4 0.0.0.0](#4.4 0.0.0.0)
- 五、私有IP和公网IP
-
- [5.1 IP地址数量限制](#5.1 IP地址数量限制)
- [5.2 私有IP地址](#5.2 私有IP地址)
- [5.3 公网IP地址](#5.3 公网IP地址)
- [5.4 路由器的双IP配置](#5.4 路由器的双IP配置)
- 六、NAT技术
-
- [6.1 什么是NAT](#6.1 什么是NAT)
- [6.2 NAT的工作原理](#6.2 NAT的工作原理)
-
- [1. 数据包发送过程](#1. 数据包发送过程)
- [2. NAT表](#2. NAT表)
- [6.3 NAT的类型](#6.3 NAT的类型)
-
- [1. 静态NAT](#1. 静态NAT)
- [2. 动态NAT](#2. 动态NAT)
- [3. NAPT(最常见)](#3. NAPT(最常见))
- [6.4 NAT的问题](#6.4 NAT的问题)
-
- [1. 无法从外网主动访问内网](#1. 无法从外网主动访问内网)
- [2. 破坏了端到端原则](#2. 破坏了端到端原则)
- [3. 协议兼容性问题](#3. 协议兼容性问题)
- 七、路由机制
-
- [7.1 路由的核心思想](#7.1 路由的核心思想)
- [7.2 路由表](#7.2 路由表)
- [7.3 路由匹配过程](#7.3 路由匹配过程)
- [7.4 最长前缀匹配](#7.4 最长前缀匹配)
- [7.5 路由表的Flags字段](#7.5 路由表的Flags字段)
- 八、路由表的生成
-
- [8.1 静态路由](#8.1 静态路由)
- [8.2 动态路由](#8.2 动态路由)
-
- [1. RIP (Routing Information Protocol)](#1. RIP (Routing Information Protocol))
- [2. OSPF (Open Shortest Path First)](#2. OSPF (Open Shortest Path First))
- [3. BGP (Border Gateway Protocol)](#3. BGP (Border Gateway Protocol))
- [8.3 路由算法(选学)](#8.3 路由算法(选学))
- 九、本篇总结
-
- [9.1 核心要点](#9.1 核心要点)
- [9.2 容易混淆的点](#9.2 容易混淆的点)
- [9.3 实际应用](#9.3 实际应用)
网络层与IP协议详解:从地址到路由的完整指南
💬 开篇:前面几篇我们学习了传输层的TCP和UDP,它们负责端到端的数据传输。但在复杂的互联网环境中,数据如何从一台主机传到另一台主机?两台相距万里的电脑如何找到对方?这就是网络层的职责。网络层最核心的协议是IP协议,它定义了互联网中每台设备的"地址",就像现实世界中的邮政编码和门牌号。这一篇会详细讲解IP协议的报文格式、IP地址的划分、子网掩码、路由机制,以及NAT技术。理解了网络层,你就理解了互联网是如何组织和运作的。
👍 点赞、收藏与分享:这篇会把IP协议和路由机制讲透,包括子网划分、CIDR、公网IP和私有IP、NAT技术、路由表等核心内容。如果对你有帮助,请点赞收藏!
🚀 循序渐进:从网络层的作用讲起,到IP报文格式,到IP地址和子网划分,到特殊IP地址,到路由机制,一步步掌握网络层的核心知识。
一、网络层的作用
1.1 什么是网络层
网络层的核心任务:
bash
在复杂的网络环境中,找到一条从源主机到目标主机的路径
类比:快递系统
bash
寄快递:
1. 你写上收件地址(目标IP地址)
2. 快递公司把包裹从北京送到上海(路由)
3. 中间可能经过多个分拣中心(路由器)
4. 最终送到收件人手中
网络层:
1. 应用程序指定目标IP地址
2. IP协议把数据包从源主机送到目标主机
3. 中间可能经过多个路由器
4. 最终到达目标应用程序
1.2 网络层vs数据链路层
对比:
| 特性 | 数据链路层 | 网络层 |
|---|---|---|
| 作用范围 | 同一链路/同一局域网内传输(相邻节点) | 跨网络传输(端到端的逐跳转发) |
| 地址类型 | MAC 地址(物理地址) | IP 地址(逻辑地址) |
| 核心设备 | 交换机 | 路由器 |
| 寻址方式 | 基于 MAC 的二层转发 | 基于 IP 的三层路由/转发(Hop by Hop) |
| 典型协议 | 以太网、Wi-Fi | IPv4/IPv6、ICMP |
例子:
bash
场景:你在北京,要给上海的朋友发一个数据包
数据链路层:
* 只能在你家的局域网内传输
* 从你的电脑传到家里的路由器(MAC地址寻址)
* 传输距离:几米到几百米
网络层:
* 跨越多个网络传输
* 从北京的路由器 → 中间若干路由器 → 上海的路由器(IP地址寻址)
* 传输距离:几千公里
1.3 基本概念
1. 主机(Host)
定义:配有IP地址,但不进行路由控制的设备。
例子:
- 你的电脑
- 你的手机
- 服务器
- 打印机(如果有IP地址)
特点:
bash
只发送和接收数据包
不转发数据包
2. 路由器(Router)
定义:既配有IP地址,又能进行路由控制的设备。
作用:
bash
连接不同的网络
转发数据包
选择最佳路径
类比:
bash
路由器就像快递的分拣中心
收到包裹后,根据目的地决定发往哪个方向
3. 节点(Node)
定义:主机和路由器的统称。
为什么需要这个概念:
bash
在讲解网络层时,很多时候不需要区分主机和路由器
统一叫"节点"更方便
二、IP协议报文格式
2.1 IP报文的整体结构
IP报文 = IP首部 + IP数据
bash
┌──────────────────────────────────────────────────────────┐
│ IP首部(20-60字节) │
├──────────────────────────────────────────────────────────┤
│ IP数据(可变长度) │
└──────────────────────────────────────────────────────────┘
IP首部的长度:
bash
最小长度:20字节(没有选项)
最大长度:60字节(有选项)

2.2 IP首部详解
1. 4位版本号(Version)
bash
┌──────┐
│ 版本 │
└──────┘
作用:指定IP协议的版本。
取值:
bash
IPv4:4
IPv6:6
2. 4位首部长度(Header Length)
bash
┌──────┐
│ 长度 │
└──────┘
含义:IP首部有多少个32位字(4字节)。
计算:
bash
IP首部长度 = 字段值 × 4 字节
例如:字段值=5 → IP首部长度=20字节(最小)
例如:字段值=15 → IP首部长度=60字节(最大)
为什么是4位:
bash
4位最大值=15
15 × 4 = 60字节(IP首部最大长度)
3. 8位服务类型(Type Of Service, TOS)
bash
┌──────────────────────┐
│ 服务类型(8位) │
└──────────────────────┘
3位优先权 + 4位TOS + 1位保留
结构:
bash
3位优先权字段(已弃用)
4位TOS字段
1位保留字段(必须为0)
4位TOS的含义:
bash
最小延时(Minimize Delay)
最大吞吐量(Maximize Throughput)
最高可靠性(Maximize Reliability)
最小成本(Minimize Cost)
重要:这四者相互冲突,只能选择一个。
应用场景:
bash
SSH/Telnet:最小延时重要(交互式应用)
FTP:最大吞吐量重要(文件传输)
邮件:最高可靠性重要
现状:
bash
现代网络中,TOS字段逐渐被DSCP字段替代
但很多路由器仍然支持TOS
- 历史上称 TOS;现在更常说 DS 字段
- 结构:DSCP 6bit + ECN 2bit
- DSCP 用于 QoS 分类,ECN 用于显式拥塞通知(不靠丢包)
4. 16位总长度(Total Length)
bash
┌──────────────────────┐
│ 总长度(16位) │
└──────────────────────┘
含义:IP数据报整体占多少个字节(首部 + 数据)。
最大值:
bash
16位最大值 = 65535字节 = 64KB
实际限制:
bash
以太网的MTU(Maximum Transmission Unit)通常是1500字节
所以IP数据报通常不会超过1500字节
超过的话会被分片
5. 16位标识(Identification)
bash
┌──────────────────────┐
│ 标识(16位) │
└──────────────────────┘
作用:唯一标识主机发送的每一个IP报文。
用途:
bash
如果IP报文在数据链路层被分片了
那么每一个分片的标识字段都是相同的
接收方可以根据标识字段重组分片
例子:
bash
发送一个5000字节的IP报文,数据4980
MTU=1500字节,需要分片
分片1:标识=12345,长度=1500,数据1480
分片2:标识=12345,长度=1500,数据1480
分片3:标识=12345,长度=1500,数据1480
分片4:标识=12345,长度=560,数据540
接收方收到这4个分片后,根据标识12345重组
6. 3位标志字段(Flags)
bash
┌──────┬──────┬──────┐
│ 保留 │ DF │ MF │
└──────┴──────┴──────┘
三个标志位:
| 位 | 名称 | 含义 |
|---|---|---|
| 第1位 | 保留 | 保留(目前不用,但可能以后用) |
| 第2位 | DF(Don't Fragment) | 禁止分片 |
| 第3位 | MF(More Fragments) | 更多分片 |
DF标志:
bash
DF=1:禁止分片
如果报文长度超过MTU,IP模块会丢弃报文,并返回ICMP错误
DF=0:允许分片
MF标志:
bash
MF=1:后面还有更多分片
MF=0:这是最后一个分片
用于标识分片的结束
例子:
bash
分片1:MF=1(还有更多分片)
分片2:MF=1(还有更多分片)
分片3:MF=1(还有更多分片)
分片4:MF=0(这是最后一个分片)
7. 13位分片偏移(Fragment Offset)
bash
┌──────────────────────────┐
│ 分片偏移(13位) │
└──────────────────────────┘
含义:当前分片相对于原始IP报文开始处的偏移量。
单位:8字节
计算:
bash
实际偏移的字节数 = 分片偏移字段值 × 8
为什么是8字节:
bash
13位最大值 = 8191
8191 × 8 = 65528字节
接近IP报文的最大长度65535字节
重要:除了最后一个分片外,其他分片的长度必须是8的整数倍。
例子:
bash
原始报文:5000字节
MTU=1500字节,需要分片
分片1:
* 偏移=0(0×8=0)
* 数据长度=1480字节(1480是8的整数倍)
* IP首部=20字节
* 总长度=1500字节
分片2:
* 偏移=185(185×8=1480)
* 数据长度=1480字节
* 总长度=1500字节
分片3:
* 偏移=370(370×8=2960)
* 数据长度=1480字节
* 总长度=1500字节
分片4(最后一个):
* 偏移=555(555×8=4440)
* 数据长度=560字节(不需要是8的整数倍)
* 总长度=580字节
8. 8位生存时间(Time To Live, TTL)
bash
┌──────────────┐
│ TTL(8位) │
└──────────────┘
含义:数据报到达目的地的最大跳数。
初始值:
bash
通常是64或128
不同的操作系统有不同的默认值:
* Linux:64
* Windows:128
递减规则:
bash
每经过一个路由器,TTL -= 1
如果TTL减到0还没到达目的地,路由器会丢弃这个数据包
并返回ICMP超时错误给发送方
作用:防止路由循环。
例子(路由循环):
bash
路由器A:收到数据包,转发给路由器B
路由器B:收到数据包,转发给路由器C
路由器C:收到数据包,转发给路由器A
路由器A:收到数据包,转发给路由器B
...(无限循环)
有了TTL机制:
数据包的TTL逐渐减小
TTL=0时,路由器丢弃数据包,循环终止
应用:
bash
traceroute命令就是利用TTL来探测路由路径的
发送TTL=1的数据包,第一个路由器返回超时错误
发送TTL=2的数据包,第二个路由器返回超时错误
...
依次获得路由路径
9. 8位协议(Protocol)
bash
┌──────────────┐
│ 协议(8位) │
└──────────────┘
作用:标识上层协议的类型。
常见协议号:
| 协议号 | 协议名称 |
|---|---|
| 1 | ICMP |
| 2 | IGMP |
| 6 | TCP |
| 17 | UDP |
| 89 | OSPF |
用途:
bash
接收方根据协议字段,把IP数据包交给相应的上层协议处理
例子:
bash
协议字段=6 → 交给TCP处理
协议字段=17 → 交给UDP处理
协议字段=1 → 交给ICMP处理
10. 16位首部校验和(Header Checksum)
bash
┌──────────────────────┐
│ 校验和(16位) │
└──────────────────────┘
作用:检测IP首部是否损坏。
校验范围:只校验IP首部,不校验数据部分。
算法:
bash
1. 把首部按16位分组
2. 把所有分组相加(使用反码加法)
3. 把结果取反
4. 得到的就是校验和
接收方的校验:
bash
1. 把首部(包括校验和字段)按16位分组
2. 把所有分组相加
3. 如果结果是全1(0xFFFF),说明校验通过
4. 否则,说明首部损坏,丢弃数据包
重要:
bash
如果校验和出错,IP层直接丢弃数据包
不通知上层协议
不发送任何错误消息
11. 32位源地址和32位目标地址
bash
┌────────────────────────────────────┐
│ 源IP地址(32位) │
├────────────────────────────────────┤
│ 目标IP地址(32位) │
└────────────────────────────────────┘
含义:
bash
源地址:发送方的IP地址
目标地址:接收方的IP地址
格式:
bash
32位 = 4个字节
通常用点分十进制表示:192.168.1.1
12. 选项字段(Options)
bash
┌──────────────────────────────────┐
│ 选项(可变长度,0-40字节) │
└──────────────────────────────────┘
常见选项:
bash
记录路由(Record Route):记录数据包经过的路由器
源路由(Source Routing):发送方指定路由路径
时间戳(Timestamp):记录经过路由器的时间
现状:
bash
选项字段很少使用
大多数IP数据包没有选项(首部长度=20字节)
三、IP地址与子网划分
3.1 IP地址的结构
IP地址 = 网络号 + 主机号
bash
┌─────────────┬─────────────┐
│ 网络号 │ 主机号 │
└─────────────┴─────────────┘
网络号:
bash
标识这台主机属于哪个网络(子网)
同一子网内的所有主机,网络号相同
主机号:
bash
标识主机在子网内的编号
同一子网内的所有主机,主机号不同
类比:门牌号
bash
网络号 = 小区名称(阳光小区)
主机号 = 门牌号(1号楼101室)
完整地址 = 阳光小区1号楼101室
3.2 传统的分类编址
历史:过去曾经把IP地址分为A、B、C、D、E五类。
A类地址
bash
0.0.0.0 到 127.255.255.255
格式:
┌───┬──────────────────────────────┐
│ 0 │ 网络号(7位) │
├───┴────────────┬─────────────────┤
│ 主机号(24位) │
└──────────────────────────────────┘
网络数量:2^7 = 128个
每个网络的主机数:2^24 ≈ 1677万
特点:
bash
第一个字节:0-127
网络号:7位
主机号:24位
适合大型网络(但实际很少有这么大的网络)
B类地址
bash
128.0.0.0 到 191.255.255.255
格式:
┌────┬─────────────────────────────┐
│ 10 │ 网络号(14位) │
├────┴────────────┬────────────────┤
│ 主机号(16位) │
└──────────────────────────────────┘
网络数量:2^14 = 16384个
每个网络的主机数:2^16 = 65536个
特点:
bash
第一个字节:128-191
网络号:14位
主机号:16位
适合中型网络
C类地址
bash
192.0.0.0 到 223.255.255.255
格式:
┌─────┬────────────────────────────┐
│ 110 │ 网络号(21位) │
├─────┴────────────┬───────────────┤
│ 主机号(8位) │ │
└──────────────────────────────────┘
网络数量:2^21 ≈ 209万个
每个网络的主机数:2^8 = 256个
特点:
bash
第一个字节:192-223
网络号:21位
主机号:8位
适合小型网络
D类地址(多播)
bash
224.0.0.0 到 239.255.255.255
格式:
┌──────┬─────────────────────────────┐
│ 1110 │ 多播组ID(28位) │
└──────┴─────────────────────────────┘
用途:
bash
多播(Multicast)
一对多通信
E类地址(保留)
bash
E 类(保留/实验):240.0.0.0 -- 255.255.255.255(240/4)
格式:
┌──────┬─────────────────────────────┐
│ 1111 │ 保留(28位) │
└──────┴─────────────────────────────┘
用途:
bash
保留,用于实验和未来扩展
3.3 分类编址的问题
问题1:地址浪费
bash
例子:
某公司需要1000个IP地址
* C类地址:只能提供256个IP,不够
* B类地址:能提供65536个IP,但浪费了64000多个
结果:只能申请B类地址,浪费大量IP
问题2:B类地址很快分配完
bash
大多数组织都申请B类地址
B类地址很快就分配完了
而A类地址却有很多浪费
问题3:路由表膨胀
bash
C类地址数量太多(209万个)
每个C类网络都需要一个路由表项
路由表变得非常大,路由器压力大
3.4 CIDR(无类别域间路由)
CIDR(Classless Inter-Domain Routing):
bash
为了解决分类编址的问题
引入了新的IP地址划分方案
核心思想:
bash
不再用A、B、C类来划分
使用子网掩码来灵活划分网络号和主机号
1. 子网掩码(Subnet Mask)
定义:
bash
32位的二进制数
用于区分IP地址的网络号和主机号
格式:
bash
连续的1 + 连续的0
例如:11111111.11111111.11111111.00000000
点分十进制:255.255.255.0
规则:
bash
1对应网络号
0对应主机号
如何使用:
bash
IP地址 AND 子网掩码 = 网络号
例子:
bash
IP地址:192.168.1.100
子网掩码:255.255.255.0
二进制:
IP: 11000000.10101000.00000001.01100100
掩码: 11111111.11111111.11111111.00000000
AND: 11000000.10101000.00000001.00000000
网络号:192.168.1.0
主机号:100
2. CIDR表示法
格式:
bash
IP地址/网络号位数
例如:192.168.1.100/24
含义:
bash
192.168.1.100/24 表示:
* IP地址是192.168.1.100
* 前24位是网络号
* 后8位是主机号
* 子网掩码是255.255.255.0
常见的CIDR表示:
| CIDR | 子网掩码 | 网络号位数 | 主机号位数 | 主机数量 |
|---|---|---|---|---|
| /8 | 255.0.0.0 | 8 | 24 | 16,777,216 |
| /16 | 255.255.0.0 | 16 | 16 | 65,536 |
| /24 | 255.255.255.0 | 24 | 8 | 256 |
| /25 | 255.255.255.128 | 25 | 7 | 128 |
| /26 | 255.255.255.192 | 26 | 6 | 64 |
| /27 | 255.255.255.224 | 27 | 5 | 32 |
| /28 | 255.255.255.240 | 28 | 4 | 16 |
| /29 | 255.255.255.248 | 29 | 3 | 8 |
| /30 | 255.255.255.252 | 30 | 2 | 4 |
3. 子网的地址范围
计算方法:
bash
1. 网络号:IP地址 AND 子网掩码
2. 第一个IP:网络号
3. 最后一个IP:网络号 + (2^主机号位数 - 1)
例子:
bash
IP地址:192.168.1.100/24
网络号:192.168.1.0
主机号位数:8位
主机数量:2^8 = 256
地址范围:192.168.1.0 - 192.168.1.255
第一个可用IP:192.168.1.1(192.168.1.0是网络号,不能分配)
最后一个可用IP:192.168.1.254(192.168.1.255是广播地址,不能分配)
可用主机数:256 - 2 = 254
例子2:
bash
IP地址:10.0.0.50/26
网络号:10.0.0.0(前26位)
实际上是:10.0.0.0(前24位)+ 00(前2位)= 10.0.0.0
等等,让我们仔细计算:
IP: 00001010.00000000.00000000.00110010
掩码: 11111111.11111111.11111111.11000000
AND: 00001010.00000000.00000000.00000000
网络号:10.0.0.0
主机号位数:6位
主机数量:2^6 = 64
地址范围:10.0.0.0 - 10.0.0.63
可用主机:10.0.0.1 - 10.0.0.62(共62个)
3.5 子网划分实例
场景:公司有一个B类地址172.16.0.0/16,需要划分成多个子网。
需求:
bash
研发部:需要100台主机
销售部:需要50台主机
财务部:需要20台主机
划分方案:
研发部:
bash
需要100台主机 → 需要至少7位主机号(2^7=128)
子网掩码:/25(25位网络号 + 7位主机号)
分配:172.16.0.0/25
地址范围:172.16.0.0 - 172.16.0.127
可用主机:172.16.0.1 - 172.16.0.126(126个)
销售部:
bash
需要50台主机 → 需要至少6位主机号(2^6=64)
子网掩码:/26
分配:172.16.0.128/26
地址范围:172.16.0.128 - 172.16.0.191
可用主机:172.16.0.129 - 172.16.0.190(62个)
财务部:
bash
需要20台主机 → 需要至少5位主机号(2^5=32)
子网掩码:/27
分配:172.16.0.192/27
地址范围:172.16.0.192 - 172.16.0.223
可用主机:172.16.0.193 - 172.16.0.222(30个)
四、特殊的IP地址
4.1 网络地址
定义:主机号全为0的IP地址。
含义:代表整个网络(子网)。
例子:
bash
192.168.1.0/24 → 网络地址是192.168.1.0
表示192.168.1.0-192.168.1.255这个子网
用途:
bash
在路由表中表示目标网络
不能分配给主机
4.2 广播地址
定义:主机号全为1的IP地址。
含义:向子网内所有主机发送数据。
例子:
bash
192.168.1.255/24 → 广播地址
向192.168.1.0/24子网内所有主机广播
用途:
bash
ARP协议:寻找IP对应的MAC地址
DHCP:主机获取IP地址
不能分配给主机
4.3 本机回环地址
范围:127.0.0.0 - 127.255.255.255
常用:127.0.0.1
含义:
bash
代表本机
数据包不会发送到网络上
在本机内部"绕回"(loopback)
用途:
bash
测试本机的网络程序
例如:
* 启动服务器监听127.0.0.1:8080
* 客户端连接127.0.0.1:8080
* 数据包不经过网络,在本机内部传输
优势:
bash
速度快(不经过网卡)
不受网络状况影响
适合测试和开发
4.4 0.0.0.0
含义:
bash
在不同的上下文中有不同的含义
作为源地址:
bash
表示"本机"
DHCP客户端在获取IP地址前,使用0.0.0.0作为源地址
作为目的地址:
bash
0.0.0.0/0 表示默认路由(匹配任意目的网络);
在服务器编程中:
bash
监听0.0.0.0表示监听所有网卡的IP地址
例如:
* 监听127.0.0.1 → 只接受本机连接
* 监听192.168.1.100 → 只接受发往这个IP的连接
* 监听0.0.0.0 → 接受所有IP的连接
五、私有IP和公网IP
5.1 IP地址数量限制
问题:
bash
IPv4地址:32位 = 2^32 ≈ 43亿个
但是:
* 全球人口:80亿
* 全球设备:远超80亿(每人多个设备)
* 特殊IP地址占用了一部分
IP地址不够用!
解决方案:
bash
1. 动态分配IP地址(DHCP)
2. 私有IP + NAT
3. IPv6(根本解决方案,但普及缓慢)
5.2 私有IP地址
RFC 1918规定的私有IP地址范围:
| 范围 | CIDR表示 | 网络数量 | 主机数量 |
|---|---|---|---|
| 10.0.0.0 - 10.255.255.255 | 10.0.0.0/8 | 1个 | 16,777,216 |
| 172.16.0.0 - 172.31.255.255 | 172.16.0.0/12 | 16个 | 1,048,576 |
| 192.168.0.0 - 192.168.255.255 | 192.168.0.0/16 | 256个 | 65,536 |
特点:
bash
只能在局域网内使用
不能在互联网上路由
可以重复使用(不同的局域网可以用相同的私有IP)
例子:
bash
你家的路由器:192.168.1.1
你朋友家的路由器:192.168.1.1
这两个IP地址相同,但在不同的局域网,不冲突
5.3 公网IP地址
定义:
bash
除了私有IP范围之外的所有IP地址
也称为全局IP地址或外网IP地址
特点:
bash
全球唯一
可以在互联网上路由
需要向ISP(互联网服务提供商)申请
例子:
bash
百度的IP:180.101.49.11(公网IP)
你家路由器的WAN口IP:可能是公网IP,也可能是运营商的私有IP
5.4 路由器的双IP配置
路由器的两个IP地址:
1. LAN口IP(局域网IP)
bash
面向局域网内部
通常是私有IP
例如:192.168.1.1
2. WAN口IP(广域网IP)
bash
面向互联网
可能是公网IP,也可能是上级路由器的私有IP
网络拓扑:
bash
互联网
|
| WAN口IP(公网IP或运营商私有IP)
┌─┴──────────┐
│ 路由器 │
└─┬──────────┘
| LAN口IP(192.168.1.1)
|
├─ 电脑1(192.168.1.100)
├─ 电脑2(192.168.1.101)
└─ 手机(192.168.1.102)
层级结构:
bash
家庭网络(内网):
电脑/手机 192.168.1.x
|
家用路由器 LAN:192.168.1.1
家用路由器 WAN:运营商分配的地址(可能是公网IP,也可能是运营商私网IP)
运营商网络(可能存在 CGNAT):
10.0.0.0/8 或 100.64.0.0/10(运营商私网)
|
出口网关(公网IP)
|
互联网
六、NAT技术
6.1 什么是NAT
NAT(Network Address Translation,网络地址转换):
bash
将私有IP地址转换为公网IP地址
使多台使用私有IP的主机共享一个公网IP
类比:公司的前台
bash
公司内部(私有IP):
* 员工A:分机1001
* 员工B:分机1002
* 员工C:分机1003
公司对外(公网IP):
* 只有一个总机号码:010-12345678
外部打电话给员工A:
1. 拨打010-12345678(总机)
2. 前台转接到分机1001(员工A)
员工A打电话给外部:
1. 从分机1001拨出
2. 前台把来电显示改为010-12345678
3. 外部看到的号码是010-12345678,而不是分机号
6.2 NAT的工作原理
1. 数据包发送过程
场景:
bash
内网主机:192.168.1.100
访问外网服务器:180.101.49.11(百度)
路由器WAN口IP:202.10.1.1(公网IP)
Step 1:主机发送数据包
bash
源IP:192.168.1.100
源端口:54321
目标IP:180.101.49.11
目标端口:80
主机 → 路由器
Step 2:路由器进行NAT转换
bash
路由器检查NAT表:
* 发现192.168.1.100:54321没有对应的映射
* 创建新映射:192.168.1.100:54321 → 202.10.1.1:60000
修改数据包:
源IP:202.10.1.1(替换为WAN口IP)
源端口:60000(替换为映射端口)
目标IP:180.101.49.11(不变)
目标端口:80(不变)
路由器 → 互联网
Step 3:服务器回复
bash
源IP:180.101.49.11
源端口:80
目标IP:202.10.1.1(路由器的WAN口IP)
目标端口:60000
互联网 → 路由器
Step 4:路由器反向NAT转换
bash
路由器检查NAT表:
* 找到60000对应的映射:202.10.1.1:60000 → 192.168.1.100:54321
修改数据包:
源IP:180.101.49.11(不变)
源端口:80(不变)
目标IP:192.168.1.100(替换为内网IP)
目标端口:54321(替换为原端口)
路由器 → 主机
2. NAT表
| NAT表的IP | 内网端口 | 外网IP | 外网端口 | 协议 |
|---|---|---|---|---|
| 192.168.1.100 | 54321 | 202.10.1.1 | 60000 | TCP |
| 192.168.1.101 | 54322 | 202.10.1.1 | 60001 | TCP |
| 192.168.1.102 | 54323 | 202.10.1.1 | 60002 | UDP |
超时清除:
bash
如果一段时间内没有数据传输
NAT表项会被删除
释放端口号
6.3 NAT的类型
1. 静态NAT
定义:
bash
一个内网IP固定映射到一个公网IP
一对一映射
例子:
bash
内网IP:192.168.1.100 → 公网IP:202.10.1.100
内网IP:192.168.1.101 → 公网IP:202.10.1.101
优点:
bash
内网主机可以被外网直接访问
缺点:
bash
需要多个公网IP
成本高
2. 动态NAT
定义:
bash
多个内网IP共享多个公网IP
动态分配
例子:
bash
内网IP池:192.168.1.1-192.168.1.254(254个)
公网IP池:202.10.1.1-202.10.1.10(10个)
同时最多10个内网主机访问外网
3. NAPT(最常见)
NAPT(Network Address Port Translation):
bash
也叫PAT(Port Address Translation)
多个内网IP共享一个公网IP
通过端口号区分不同的连接
这就是家用路由器使用的NAT类型。
优势:
bash
只需要一个公网IP
成本低
6.4 NAT的问题
1. 无法从外网主动访问内网
问题:
bash
内网主机没有公网IP
外网无法直接访问内网主机
影响:
bash
内网运行的服务器无法被外网访问
P2P应用受限
解决方法:
bash
1. 端口映射(Port Forwarding)
2. UPnP(自动配置端口映射)
3. 使用公网服务器中转
2. 破坏了端到端原则
端到端原则:
bash
两台主机直接通信
中间设备只负责转发
NAT违反了这个原则:
bash
路由器修改了数据包的IP地址和端口号
3. 协议兼容性问题
某些协议不兼容NAT:
bash
FTP的主动模式(服务器主动连接客户端)
SIP(VoIP协议)
IPSec(VPN协议)
原因:
bash
这些协议在数据部分包含IP地址
NAT只修改IP首部,不修改数据部分
导致地址不匹配
七、路由机制
7.1 路由的核心思想
路由:在复杂的网络中,找出一条通往目标的路径。
类比:唐僧问路
bash
唐僧要去西天取经:
唐僧:"请问西天怎么走?"
村民甲:"我不知道西天在哪,但往西走会到下一个村子"
唐僧走到下一个村子
唐僧:"请问西天怎么走?"
村民乙:"我也不知道,但继续往西走"
...
最终到达西天
数据包的传输:
数据包:"我要去180.101.49.11"
路由器A:"我不知道确切路径,但我知道该发给路由器B"
数据包到达路由器B
数据包:"我要去180.101.49.11"
路由器B:"发给路由器C"
...
最终到达目标
核心:
bash
数据包的传输是逐跳(Hop by Hop)的"问路"过程
每个路由器只需要知道"下一跳"发往哪里
不需要知道完整的路径
7.2 路由表
定义:
bash
每个路由器和主机都维护一个路由表
记录"发往某个目标网络,应该从哪个接口发出,下一跳是谁"
查看路由表:
bash
# Linux/Mac
route -n
# 或
ip route
# Windows
route print
路由表示例:
bash
Destination Gateway Genmask Iface
0.0.0.0 192.168.1.1 0.0.0.0 eth0
192.168.1.0 0.0.0.0 255.255.255.0 eth0
192.168.10.0 0.0.0.0 255.255.255.0 eth1
字段含义:
| 字段 | 含义 |
|---|---|
| Destination | 目标网络地址 |
| Gateway | 下一跳路由器的IP地址 |
| Genmask | 子网掩码 |
| Iface | 发送接口 |
7.3 路由匹配过程
规则:
bash
1. 用目标IP和每一行的Genmask做AND运算
2. 看结果是否等于Destination
3. 如果匹配,就从该行的Iface发出,下一跳是Gateway
4. 如果多行匹配,选择最长前缀匹配(Most Specific Match)
例子1:直接投递
bash
路由表:
Destination Gateway Genmask Iface
192.168.56.0 0.0.0.0 255.255.255.0 eth1
目标IP:192.168.56.3
匹配过程:
192.168.56.3 AND 255.255.255.0 = 192.168.56.0 ✓
结果:
从eth1接口发出
Gateway=0.0.0.0表示目标主机与本机直接相连
直接发送给192.168.56.3,不需要经过路由器
例子2:经过路由器
bash
路由表:
Destination Gateway Genmask Iface
192.168.10.0 192.168.10.1 255.255.255.0 eth0
目标IP:192.168.10.5
匹配过程:
192.168.10.5 AND 255.255.255.0 = 192.168.10.0 ✓
结果:
从eth0接口发出
下一跳是192.168.10.1(路由器)
先发给192.168.10.1,由它继续转发
例子3:默认路由
bash
路由表:
Destination Gateway Genmask Iface
0.0.0.0 192.168.1.1 0.0.0.0 eth0
目标IP:202.10.1.2
匹配过程:
前面的路由表项都不匹配
匹配默认路由:
202.10.1.2 AND 0.0.0.0 = 0.0.0.0 ✓
结果:
从eth0接口发出
下一跳是192.168.1.1(网关)
发给网关,由网关继续路由
7.4 最长前缀匹配
问题:如果多条路由表项都匹配,选哪个?
答案:选择最长前缀匹配(Most Specific Match)。
原理:
bash
网络号位数越多(子网掩码越长)
匹配越精确
优先级越高
例子:
bash
路由表:
Destination Gateway Genmask Iface
192.168.1.0 0.0.0.0 255.255.255.0 eth1 (/24)
192.168.0.0 192.168.1.1 255.255.0.0 eth0 (/16)
目标IP:192.168.1.100
两条都匹配:
192.168.1.100 AND 255.255.255.0 = 192.168.1.0 ✓ (匹配长度:24位)
192.168.1.100 AND 255.255.0.0 = 192.168.0.0 ✓ (匹配长度:16位)
选择最长匹配:
第一条(24位 > 16位)
从eth1发出,直接投递
为什么需要最长匹配:
bash
越具体的路由优先级越高
例如:
- 192.168.1.0/24:专门为192.168.1.0这个子网设置的路由
- 192.168.0.0/16:为整个192.168.0.0大网段设置的路由
显然192.168.1.0/24更具体,应该优先使用
7.5 路由表的Flags字段
常见标志:
| Flag | 含义 |
|---|---|
| U | Up,路由表项有效 |
| G | Gateway,需要经过网关(路由器) |
| H | Host,目标是单个主机(而不是网络) |
| D | Dynamically,动态路由 |
| M | Modified,被修改过 |
例子:
bash
Destination Gateway Flags Iface
192.168.1.0 0.0.0.0 U eth0
0.0.0.0 192.168.1.1 UG eth0
第一条:U标志
- 路由有效
- 没有G标志,说明目标网络直接相连
第二条:UG标志
- 路由有效
- G标志,说明需要经过网关192.168.1.1
八、路由表的生成
8.1 静态路由
定义:
bash
网络管理员手动配置路由表
添加静态路由:
bash
# Linux
ip route add 192.168.2.0/24 via 192.168.1.1
# 含义:
# 发往192.168.2.0/24网络的数据包
# 下一跳是192.168.1.1
优点:
bash
简单可控
适合小型网络
缺点:
bash
配置繁琐
网络拓扑变化时需要手动更新
不适合大型网络
8.2 动态路由
定义:
bash
路由器之间自动交换路由信息
自动生成和更新路由表
常见动态路由协议:
1. RIP (Routing Information Protocol)
原理:距离向量算法(Distance Vector)
核心思想:
bash
每个路由器定期广播自己的路由表
其他路由器收到后,更新自己的路由表
距离度量:
bash
跳数(Hop Count)
最大15跳,16跳表示不可达
优点:
简单易实现
缺点:
bash
收敛慢(网络变化后,需要较长时间同步)
跳数限制(最多15跳)
不适合大型网络
2. OSPF (Open Shortest Path First)
原理:链路状态算法(Link State)
核心思想:
bash
每个路由器了解整个网络的拓扑
使用Dijkstra算法计算最短路径
距离度量:
bash
链路代价(Cost)
通常与带宽成反比
优点:
bash
收敛快
没有跳数限制
适合大型网络
缺点:
bash
复杂
占用较多CPU和内存
3. BGP (Border Gateway Protocol)
用途:互联网骨干网的路由协议
特点:
bash
用于不同自治系统(AS)之间的路由
考虑策略、政治、经济因素
不只是最短路径
8.3 路由算法(选学)
距离向量算法:
bash
每个节点维护到所有其他节点的距离
定期与邻居交换距离信息
根据邻居的距离信息更新自己的距离
例如:
节点A到节点C的距离 = min(
A到B的距离 + B到C的距离,
A到D的距离 + D到C的距离,
...
)
链路状态算法:
bash
每个节点了解整个网络拓扑
使用Dijkstra最短路径算法计算路由
步骤:
1. 每个节点广播自己的邻居信息
2. 所有节点收集信息,构建完整的网络拓扑图
3. 每个节点用Dijkstra算法计算到所有其他节点的最短路径
4. 生成路由表
九、本篇总结
9.1 核心要点
网络层的作用:
- 在复杂网络中找到从源主机到目标主机的路径
- 核心协议是IP协议
- 核心设备是路由器
IP报文格式:
- 首部20-60字节
- 重要字段:版本号、首部长度、总长度、标识、标志、分片偏移、TTL、协议、校验和、源地址、目标地址
- TTL防止路由循环
- 分片机制允许大数据包通过小MTU网络
IP地址和子网划分:
- IP地址 = 网络号 + 主机号
- CIDR取代了传统的分类编址
- 子网掩码灵活划分网络号和主机号
- CIDR表示法:IP地址/网络号位数
特殊IP地址:
- 网络地址:主机号全0
- 广播地址:主机号全1
- 回环地址:127.0.0.1
- 0.0.0.0:表示本机或任意地址
私有IP和NAT:
- 私有IP:10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
- NAT将私有IP转换为公网IP
- 家用路由器使用NAPT(PAT)
- 多台内网主机共享一个公网IP
路由机制:
- 路由是逐跳的"问路"过程
- 路由表记录目标网络、网关、接口
- 匹配规则:最长前缀匹配
- 默认路由:目标是0.0.0.0/0
- 静态路由:手动配置
- 动态路由:自动生成(RIP、OSPF、BGP)
9.2 容易混淆的点
-
网络号 vs 网络地址:
- 网络号:IP地址的一部分(前若干位)
- 网络地址:主机号全0的完整IP地址
-
子网掩码 vs CIDR前缀长度:
- 子网掩码:255.255.255.0
- CIDR前缀长度:/24
- 两者等价,只是表示方法不同
-
网关 vs 路由器:
- 网关:默认路由的下一跳地址
- 路由器:连接不同网络的设备
- 网关通常就是路由器的IP地址
-
私有IP vs 公网IP:
- 私有IP:只能在局域网使用,可以重复
- 公网IP:全球唯一,可以在互联网路由
-
直接投递 vs 间接投递:
- 直接投递:目标主机与本机在同一子网,直接发送
- 间接投递:目标主机在其他网络,需要经过路由器
9.3 实际应用
场景1:家庭网络
bash
ISP(公网IP)
|
家用路由器(WAN: 公网IP, LAN: 192.168.1.1)
|
├─ 电脑(192.168.1.100)
├─ 手机(192.168.1.101)
└─ 平板(192.168.1.102)
所有设备共享一个公网IP
使用NAT技术
场景2:公司网络
bash
公司路由器(公网IP)
|
├─ 研发部子网(172.16.1.0/24)
├─ 销售部子网(172.16.2.0/24)
└─ 财务部子网(172.16.3.0/24)
不同部门使用不同的子网
使用静态路由或动态路由
场景3:互联网
bash
全球的路由器通过BGP交换路由信息
每个路由器维护一个庞大的路由表
数据包逐跳转发,最终到达目标
💬 总结:网络层是互联网的基础,IP协议定义了每台设备的地址,路由机制让数据包能够跨越全球到达目标。理解了IP地址的结构、子网划分、NAT技术、路由表的工作原理,你就理解了互联网是如何组织和运作的。网络层虽然复杂,但核心思想很简单:给每台设备一个地址(IP地址),然后逐跳"问路"找到通往目标的路径(路由)。下一篇我们会学习数据链路层,看看数据包如何在同一局域网内传输,以及ARP协议如何把IP地址转换为MAC地址。
👍 点赞、收藏与分享:如果这篇帮你理解了网络层和IP协议,请点赞收藏!网络编程,从理解网络层开始!