第2章:Internet地址(Internet Addresses)
IP地址
一、导读
1.1 本章学习目标
第2章深入讲解IP地址——TCP/IP协议族中最基本的寻址机制。如果说第1章让你认识了协议栈的整体架构,那么本章则让你理解网络层的核心概念:如何用地址标识Internet上的每一台主机。IP地址的设计直接影响了网络的路由效率、地址分配策略和安全模型。
本章的核心学习目标包括:
- 掌握IPv4地址的结构和表示方法:32位整数、点分十进制、网络字节序
- 理解IP地址的分类体系:A/B/C/D/E五类地址的划分依据和地址范围
- 深入理解子网掩码的作用:如何区分网络部分和主机部分,如何进行子网划分
- 掌握CIDR(无类域间路由)的原理:为什么引入CIDR,如何用前缀长度表示地址块
- 认识特殊IP地址的用途:私有地址、环回地址、广播地址、多播地址
- 理解NAT(网络地址转换)的工作原理:如何解决IPv4地址不足的问题
1.2 为什么本章如此重要
IP地址是网络通信的基石。每一个网络操作——无论是浏览网页、发送邮件还是远程登录——都涉及IP地址的使用。不理解IP地址,就无法理解路由、子网划分、防火墙规则、VPN配置等几乎所有网络概念。
更重要的是,IP地址的设计反映了Internet的扩展历程。从最初的分类编址到CIDR,从公有地址到私有地址+NAT,每一次演进都是对"地址空间不足"这一核心问题的回应。理解这些历史背景,有助于你理解为什么今天的网络是这样配置的,以及为什么IPv6是必然的解决方案。
在实际工作中,IP地址的配置错误是最常见的网络故障原因之一。子网掩码设置错误、网关地址不正确、IP地址冲突——这些问题都需要扎实的IP地址知识才能快速诊断和解决。
1.3 核心问题引导
在阅读本章时,请带着以下问题思考:
为什么IPv4地址是32位的?这个长度够用吗?如果不够,为什么不直接改为64位而是128位?
子网掩码 255.255.255.0 到底意味着什么?它和网络前缀 /24 是什么关系?
为什么 192.168.x.x 地址可以在任何局域网中使用而不会冲突?这些地址如何访问Internet?
CIDR解决了什么问题?它比传统的分类编址好在哪里?
NAT是如何让多台设备共享一个公有IP地址的?它对端到端通信有什么影响?
当你在命令行输入 ping 8.8.8.8 时,系统如何判断目标是否在同一子网?
二、核心概念详解
2.1 IPv4地址的基本结构
IPv4地址是一个32位的整数,通常用点分十进制(dotted decimal)表示法书写。将32位分为4组,每组8位(一个字节),转换为十进制数(0-255),用点号分隔。
二进制:11000000 10101000 00000001 00000001
十进制: 192 168 1 1
表示: 192.168.1.12.1.1 网络部分与主机部分
每个IP地址由两部分组成:网络部分(network prefix)和主机部分(host number)。
- 网络部分标识主机所在的网络,同一网络中的所有主机共享相同的网络部分
- 主机部分标识网络中的具体主机,同一网络中的每台主机有唯一的主机部分
IP地址: 192.168.1.100
└───┬───┘ └──┬──┘
网络部分 主机部分如何区分网络部分和主机部分?这取决于子网掩码。
2.1.2 字节序问题
在网络编程中,必须注意字节序(byte order)问题:
- 网络字节序(Network Byte Order):大端序(big-endian),高位字节在前
- 主机字节序(Host Byte Order):取决于CPU架构,x86是小端序
IP地址在网络传输和协议头部中始终使用网络字节序。在C语言编程中,需要使用 htonl()/ntohl() 进行转换:
#include <arpa/inet.h>
// 点分十进制 → 网络字节序
struct in_addr addr;
inet_pton(AF_INET, "192.168.1.1", &addr);
// addr.s_addr 现在是网络字节序的32位整数
// 网络字节序 → 点分十进制
char buf[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &addr, buf, sizeof(buf));
// buf 现在是 "192.168.1.1"2.2 传统分类编址
IPv4地址最初被分为五类(A/B/C/D/E),分类依据是地址最高位的模式:
| 类别 | 最高位模式 | 地址范围 | 网络部分 | 主机部分 | 每网络主机数 |
|---|---|---|---|---|---|
| A | 0 | 0.0.0.0-127.255.255.255 | 8位 | 24位 | 16,777,214 |
| B | 10 | 128.0.0.0-191.255.255.255 | 16位 | 16位 | 65,534 |
| C | 110 | 192.0.0.0-223.255.255.255 | 24位 | 8位 | 254 |
| D | 1110 | 224.0.0.0-239.255.255.255 | 多播地址 | — | — |
| E | 11110 | 240.0.0.0-255.255.255.255 | 保留 | — | — |
2.2.1 分类编址的问题
分类编址存在严重的地址浪费问题:
- A类地址可以容纳1600万台主机,但大多数组织根本不需要这么多
- C类地址只能容纳254台主机,但很多组织需要多于254台少于65534台
- B类地址恰好介于两者之间,但B类地址在1990年代初就已经分配殆尽
例如,一个有500台主机的组织:C类地址不够(254台),必须申请一个B类地址(65534台),浪费了65000多个地址。
这个问题直接催生了CIDR(无类域间路由)的引入。
2.3 子网掩码
子网掩码(subnet mask)是一个32位的整数,与IP地址逐位进行AND运算,提取出网络部分。
IP地址: 192.168.1.100 11000000.10101000.00000001.01100100
子网掩码: 255.255.255.0 11111111.11111111.11111111.00000000
AND结果: 192.168.1.0 11000000.10101000.00000001.00000000
↑ 这就是网络地址2.3.1 子网划分
子网划分(subnetting)是从主机部分借位来创建更多子网的过程。
示例:将 192.168.1.0/24 划分为4个子网
原始掩码:255.255.255.0(/24),主机部分8位
借2位:255.255.255.192(/26),主机部分6位
子网0: 192.168.1.0/26 主机范围: 192.168.1.1 - 192.168.1.62 广播: 192.168.1.63
子网1: 192.168.1.64/26 主机范围: 192.168.1.65 - 192.168.1.126 广播: 192.168.1.127
子网2: 192.168.1.128/26 主机范围: 192.168.1.129 - 192.168.1.190 广播: 192.168.1.191
子网3: 192.168.1.192/26 主机范围: 192.168.1.193 - 192.168.1.254 广播: 192.168.1.255每个子网可以容纳 2^6 - 2 = 62 台主机(减去网络地址和广播地址)。
2.3.2 子网掩码的表示方法
子网掩码有两种常见的表示方法:
- 点分十进制:
255.255.255.0 - 前缀长度:
/24(表示前24位是网络部分)
前缀长度表示法更简洁,也更常用。/24 等价于 255.255.255.0,/16 等价于 255.255.0.0,/8 等价于 255.0.0.0。
2.4 CIDR(无类域间路由)
CIDR(Classless Inter-Domain Routing)在1993年引入,彻底改变了IP地址的分配方式。
2.4.1 CIDR的核心思想
CIDR抛弃了固定的A/B/C类划分,允许任意长度的网络前缀。一个IP地址块用 地址/前缀长度 表示:
192.168.0.0/16 表示 192.168.0.0 - 192.168.255.255(65536个地址)
10.0.0.0/8 表示 10.0.0.0 - 10.255.255.255(16777216个地址)
172.16.0.0/12 表示 172.16.0.0 - 172.31.255.255(1048576个地址)2.4.2 路由聚合
CIDR最重要的特性是路由聚合(route aggregation),也称为路由汇总(route summarization)。
假设一个ISP分配了以下地址块给四个客户:
客户A: 200.10.24.0/26
客户B: 200.10.24.64/26
客户C: 200.10.24.128/26
客户D: 200.10.24.192/26在上游路由器的路由表中,这四条路由可以聚合为一条:
200.10.24.0/24这大大减少了全球路由表的规模。在CIDR之前,每个A/B/C类网络都需要一条独立的路由条目,全球路由表膨胀到了不可管理的程度。
2.4.3 最长前缀匹配
CIDR引入了最长前缀匹配(longest prefix match)的路由查找规则。当路由表中有多个条目匹配目的IP时,选择前缀最长(最具体)的那个。
路由表:
10.0.0.0/8 → 接口A(默认路由)
10.1.0.0/16 → 接口B(部门路由)
10.1.1.0/24 → 接口C(子网路由)
目的IP: 10.1.1.50
匹配: 三条都匹配,选择最长的 /24 → 接口C2.5 特殊IP地址
2.5.1 私有地址
RFC 1918定义了三个私有地址块,这些地址不会在Internet上路由,可以在任何组织内部自由使用:
| 地址块 | 前缀 | 地址范围 | 可用地址数 |
|---|---|---|---|
| 10.0.0.0/8 | /8 | 10.0.0.0 - 10.255.255.255 | 16,777,216 |
| 172.16.0.0/12 | /12 | 172.16.0.0 - 172.31.255.255 | 1,048,576 |
| 192.168.0.0/16 | /16 | 192.168.0.0 - 192.168.255.255 | 65,536 |
私有地址是解决IPv4地址不足的关键手段之一。通过NAT,多个使用私有地址的设备可以共享一个公有IP地址访问Internet。
2.5.2 其他特殊地址
| 地址 | 用途 |
|---|---|
| 0.0.0.0 | 本网络(启动时使用)/ 默认路由 |
| 127.0.0.0/8 | 环回地址(127.0.0.1最常用) |
| 255.255.255.255 | 受限广播地址 |
| 169.254.0.0/16 | 链路本地地址(APIPA,DHCP失败时使用) |
| 224.0.0.0/4 | D类多播地址 |
| 240.0.0.0/4 | E类保留地址 |
2.5.3 环回地址
127.0.0.0/8 整个地址块都是环回地址。发送到环回地址的数据报不会离开主机,而是直接在协议栈内部环回到接收端。127.0.0.1 是最常用的环回地址,通常命名为 localhost。
环回地址的用途:
- 测试本机的TCP/IP协议栈是否正常工作
- 本机进程间通信
- 开发测试
2.6 NAT(网络地址转换)
NAT(Network Address Translation)是解决IPv4地址不足的最重要手段。它允许使用私有地址的内部网络通过一个(或少数几个)公有IP地址访问Internet。
2.6.1 基本NAT工作原理
内部网络 NAT路由器 Internet
192.168.1.100 ──→ NAT转换 ──→ 203.0.113.1:5000 ──→ 目标服务器
192.168.1.101 ──→ NAT转换 ──→ 203.0.113.1:5001 ──→ 目标服务器
192.168.1.102 ──→ NAT转换 ──→ 203.0.113.1:5002 ──→ 目标服务器NAT路由器维护一个转换表,记录内部地址和外部地址的映射关系:
NAT转换表:
内部地址 外部地址 目的地址
192.168.1.100:3000 → 203.0.113.1:5000 → 93.184.216.34:80
192.168.1.101:3001 → 203.0.113.1:5001 → 93.184.216.34:80当外部响应到达NAT路由器时,路由器根据转换表将目的端口映射回内部地址。
2.6.2 NAPT(网络地址端口转换)
最常见的NAT形式是NAPT(也称为PAT或IP伪装)。它不仅转换IP地址,还转换端口号,使得多个内部设备可以共享一个公有IP地址:
内部主机A (192.168.1.100:4000) ─┐
内部主机B (192.168.1.101:4000) ─┼──→ NAT ──→ 203.0.113.1:50001 ──→ 服务器
内部主机C (192.168.1.102:4000) ─┘ 203.0.113.1:50002
203.0.113.1:500032.6.3 NAT的问题
NAT虽然解决了地址不足的问题,但也带来了一些负面影响:
- 破坏端到端原则:外部主机无法主动发起与内部主机的连接
- 增加复杂性:某些协议(如FTP、SIP)在数据中嵌入了IP地址,NAT需要特殊处理(ALG)
- 影响P2P应用:P2P通信需要特殊的NAT穿透技术(STUN、TURN、ICE)
三、实战案例
3.1 案例一:子网划分计算
场景:某公司获得地址块 172.16.10.0/24,需要划分为以下子网:
- 研发部:100台主机
- 市场部:50台主机
- 行政部:25台主机
- 点对点链路:2台主机
计算过程:
研发部需要100台 → 需要7位主机位(2^7-2=126) → /25
子网: 172.16.10.0/25
范围: 172.16.10.1 - 172.16.10.126
广播: 172.16.10.127
市场部需要50台 → 需要6位主机位(2^6-2=62) → /26
子网: 172.16.10.128/26
范围: 172.16.10.129 - 172.16.10.190
广播: 172.16.10.191
行政部需要25台 → 需要5位主机位(2^5-2=30) → /27
子网: 172.16.10.192/27
范围: 172.16.10.193 - 172.16.10.222
广播: 172.16.10.223
点对点链路需要2台 → 需要2位主机位(2^2-2=2) → /30
子网: 172.16.10.224/30
范围: 172.16.10.225 - 172.16.10.226
广播: 172.16.10.2273.2 案例二:使用tcpdump观察NAT转换
# 在NAT路由器内部接口抓包
sudo tcpdump -i eth1 -nn 'tcp port 80'
# 输出:192.168.1.100.4000 > 93.184.216.34.80: Flags [S]
# 在NAT路由器外部接口抓包
sudo tcpdump -i eth0 -nn 'tcp port 80'
# 输出:203.0.113.1.5000 > 93.184.216.34.80: Flags [S]对比两个接口的抓包结果,可以清楚看到NAT将源地址从 192.168.1.100:4000 转换为 203.0.113.1:5000。
3.3 案例三:使用ipcalc工具辅助计算
# 安装ipcalc
sudo apt install ipcalc
# 计算子网信息
ipcalc 192.168.1.100/24
# Address: 192.168.1.100 11000000.10101000.00000001.01100100
# Netmask: 255.255.255.0 = 24 11111111.11111111.11111111.00000000
# Wildcard: 0.0.0.255 00000000.00000000.00000000.11111111
# Network: 192.168.1.0/24 11000000.10101000.00000001.00000000
# Broadcast: 192.168.1.255 11000000.10101000.00000001.11111111
# HostMin: 192.168.1.1
# HostMax: 192.168.1.254
# Hosts/Net: 254四、常见误区与难点
4.1 误区一:"子网掩码必须是连续的1和0"
在CIDR之前,某些实现确实要求子网掩码是连续的1后面跟连续的0。但CIDR引入了可变长子网掩码(VLSM),允许非连续的掩码(虽然实践中几乎总是使用连续掩码)。现代路由协议(如OSPF、BGP)都支持VLSM。
4.2 误区二:"私有地址不能访问Internet"
私有地址本身确实不能在Internet上路由,但通过NAT,使用私有地址的设备可以透明地访问Internet。用户感知不到NAT的存在——他们以为自己在"直接"访问Internet。
4.3 难点:理解路由聚合和最长前缀匹配
这两个概念是CIDR的核心。路由聚合减少了路由表的规模,最长前缀匹配保证了路由的精确性。理解它们需要实践——建议用实际的路由表配置来练习。
五、本章小结
第2章深入讲解了IP地址的核心概念:
IPv4地址是32位整数,用点分十进制表示。每个地址由网络部分和主机部分组成,子网掩码用于区分这两部分。
分类编址(A/B/C/D/E)由于地址浪费严重已被CIDR取代。CIDR允许任意长度的前缀,支持路由聚合,大大减少了路由表规模。
子网划分是从主机部分借位创建更多子网的过程,需要精确计算每个子网的网络地址、广播地址和可用主机范围。
私有地址(10.0.0.0/8、172.16.0.0/12、192.168.0.0/16)配合NAT技术,是解决IPv4地址不足的关键手段。
特殊地址各有用途:环回地址用于本机测试,广播地址用于一对所有通信,链路本地地址用于DHCP失败时的自动配置。
IP地址的设计是Internet工程的核心技能。无论是配置路由器、设置防火墙规则,还是编写网络程序,扎实的IP地址知识都是必不可少的。
六、思考与练习
思考题
如果让你设计一个IP地址方案,你会如何平衡"地址空间的利用率"和"路由表的规模"?CIDR是如何解决这个矛盾的?
NAT破坏了端到端原则。有人认为这是Internet最大的设计缺陷之一,你同意吗?IPv6能否彻底解决这个问题?
为什么环回地址是整个 127.0.0.0/8 地址块,而不仅仅是 127.0.0.1?这个设计有什么好处?
在一个使用 192.168.0.0/16 的大型网络中,如何设计子网划分方案以支持不同规模的部门?
练习题
给定IP地址 172.16.5.130 和子网掩码 255.255.254.0,计算网络地址、广播地址和可用主机范围。
将 10.0.0.0/8 划分为至少50个子网,每个子网至少支持200台主机。给出子网掩码和前三个子网的地址范围。
使用tcpdump和ifconfig/if命令,查看本机所有网络接口的IP地址和子网掩码,计算每个接口所在子网的网络地址和广播地址。