2TCP/IP详解(卷1:协议)

Internet地址

IP地址

IP地址子网掩码CIDR

🎯 AI 时代的学习建议:不要只读理论。理解这一章的设计动机(为什么需要这个概念?)和边界条件(什么情况下会失效?)。当 AI 生成的代码涉及这些概念时,你能判断它是否用对了场景。AI 能帮你总结内容,但无法替代你亲手阅读、思考、建立直觉的过程。

第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.1

2.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() 进行转换:

c
#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),分类依据是地址最高位的模式:

类别最高位模式地址范围网络部分主机部分每网络主机数
A00.0.0.0-127.255.255.2558位24位16,777,214
B10128.0.0.0-191.255.255.25516位16位65,534
C110192.0.0.0-223.255.255.25524位8位254
D1110224.0.0.0-239.255.255.255多播地址——
E11110240.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 → 接口C

2.5 特殊IP地址

2.5.1 私有地址

RFC 1918定义了三个私有地址块,这些地址不会在Internet上路由,可以在任何组织内部自由使用:

地址块前缀地址范围可用地址数
10.0.0.0/8/810.0.0.0 - 10.255.255.25516,777,216
172.16.0.0/12/12172.16.0.0 - 172.31.255.2551,048,576
192.168.0.0/16/16192.168.0.0 - 192.168.255.25565,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/4D类多播地址
240.0.0.0/4E类保留地址

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:50003

2.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.227

3.2 案例二:使用tcpdump观察NAT转换

bash
# 在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工具辅助计算

bash
# 安装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地址和子网掩码,计算每个接口所在子网的网络地址和广播地址。

2/13Inte
0%