← 网络基础学习第 25 / 55 章基础40 分钟

模块三 · 网络层:数据平面

IP 地址与子网划分

你会看 IP 地址,但说不清后面那个 /24 或 255.255.255.0 到底在干什么。

本章要解决的问题:你会看 IP 地址,但说不清后面那个 /24 或 255.255.255.0 到底在干什么。

本章的证据来源:captures/snapshot-20261012-220243.md(本机快照)
和 captures/lab_subnet_verify_output.txt(代码验证输出)。

先从一个例子理解概念

电脑看到目标地址,要先判断“对方在我直接连接的网络上吗,还是要先交给网关”。子网掩码就是这个判断的一部分。

网络层的地址:IPv4

IPv4是IP的一种版本,地址常写成四段数字,例如192.168.1.10。每段表示一个字节,整条地址共32个二进制位。

地址怎样分成两部分:网络前缀与主机部分

同一子网的地址具有共同的前面一段,叫网络前缀;后面的部分区分该范围中的地址。不是看起来前三段相同就永远同网段。

从哪一位分开:掩码与斜杠写法

子网掩码规定哪些位参与网络前缀判断。/24表示前24位是前缀,剩下8位在该范围内变化;对应掩码255.255.255.0。先理解“分界位置”,再算地址数量。

怎样比较:按位与

按位与(AND)逐位计算,两个输入都是1才得到1。IP与掩码做这个运算,可保留网络位并清零主机位;比较得到的前缀才是后面的计算依据。

下面再用这些概念看原理、命令和结果。规范与官方资料列在本章末尾,类比只帮助理解,不代替协议规则。

掩码只干一件事:把 32 位切成两段

一个 IPv4 地址是 32 位。它被掩码切成两段:

192  .  168  .  31  .  215
11000000 10101000 00011111 11010111     ← 32 位
└──────┬───────┘ └──────┬───────┘
     网络号部分        主机号部分

掩码告诉你从第几位切。/24 表示前 24 位是网络号,后 8 位是主机号。

判断两台主机是否在同一个网段,就是把各自的 IP 和掩码做按位与,比较结果:

192.168.31.215  AND  255.255.255.0  =  192.168.31.0
192.168.31.1    AND  255.255.255.0  =  192.168.31.0     ← 相同 → 同网段
192.168.32.10   AND  255.255.255.0  =  192.168.32.0     ← 不同 → 要过网关

就这么多。「子网划分」听起来玄,本质就是用掩码决定切在哪儿, 而切在哪儿决定了「谁能直接对话、谁必须经过路由器」。

为什么要有这个东西:如果全世界的设备都在一个网段里,每台机器发一个广播包, 全球所有设备都要处理一次。IP子网划分的是三层地址范围;二层广播域由桥接/VLAN等决定。通常让两者对应,单独改掩码不会把交换机广播域切开。

换算表(背几个就够)

前缀子网掩码总地址数可用主机数说明
/30255.255.255.25242点到点链路,刚好两个端点
/29255.255.255.24886
/28255.255.255.2401614
/27255.255.255.2243230
/26255.255.255.1926462
/25255.255.255.128128126
/24255.255.255.0256254家用网络最常见的
/23255.255.254.0512510
/22255.255.252.010241022
/21255.255.248.020482046
/20255.255.240.040964094本机 WSL 用的这个
/16255.255.0.06553665534本机 APIPA 用的这个
/12255.240.0.010485761048574私有段 172.16/12
/8255.0.0.01677721616777214私有段 10/8

为什么可用主机数要减 2:每个网段的第一个地址是网络号(标识这个网段本身), 最后一个是广播地址(发给网段内所有主机)。这两个都不能分配给设备。

实测:同一台机器上,四种前缀长度同时存在

先看实测数据(captures/lab_subnet_verify_output.txt 第一部分):

  接口             本机地址               前缀     子网掩码               网络号                可用主机数
  --------------------------------------------------------------------------
  WLAN           192.168.31.215     /24    255.255.255.0      192.168.31.0       254
                 广播地址 ->                   192.168.31.255     可用范围 192.168.31.1 ~ 192.168.31.254
  FlClash        198.18.0.1         /30    255.255.255.252    198.18.0.0         2
                 广播地址 ->                   198.18.0.3         可用范围 198.18.0.1 ~ 198.18.0.2
  vEthernet WSL  172.30.0.1         /20    255.255.240.0      172.30.0.0         4094
                 广播地址 ->                   172.30.15.255      可用范围 172.30.0.1 ~ 172.30.15.254
  蓝牙网络连接         169.254.215.100    /16    255.255.0.0        169.254.0.0        65534
                 广播地址 ->                   169.254.255.255    可用范围 169.254.0.1 ~ 169.254.255.254

现在逐个拆开,重点看路由表和 ARP 表怎么印证这些计算。

1.3.1 /24 —— 你的无线网

本机   192.168.31.215/24   →  网络号 192.168.31.0,广播 192.168.31.255
可用范围 192.168.31.1 ~ 192.168.31.254(254 个)

打开 captures/snapshot-20261012-220243.md 的第 5 节(完整路由表),能找到三条:

192.168.31.0/24      0.0.0.0   WLAN   Local      ← 整个网段是直连的
192.168.31.215/32    0.0.0.0   WLAN   Local      ← 本机自己的地址
192.168.31.255/32    0.0.0.0   WLAN   Local      ← 广播地址

再看第 6 节(ARP 表):

Interface: 192.168.31.215 --- 0x11
  192.168.31.1          a4-39-b3-0b-ab-19     dynamic   ← 网关,有真实 MAC
  192.168.31.51         e8-51-77-27-5a-9a     dynamic   ← 局域网里另一台设备
  192.168.31.248        fa-aa-ff-92-e6-3f     dynamic   ← 又一台
  192.168.31.255        ff-ff-ff-ff-ff-ff     static    ← 广播地址的"MAC"

三件事对上了:

  1. 计算出的广播地址 192.168.31.255,在路由表里是一条 /32 主机路由,在 ARP 表里的 MAC 是 ff-ff-ff-ff-ff-ff —— 全 1 就是二层广播地址。
  2. 网关 192.168.31.1 有真实 MAC,说明它在同一网段,可以直接用 ARP 找到它。
  3. 你的机器是 .215,所以 .1~.214 和 .216~.254 才是"邻居"。

→ 掩码算出来的范围,和系统实际行为完全一致。这就是验证的方法。

1.3.2 /30 —— 只有两个可用地址的网段

FlClash 198.18.0.1/30  →  网络号 198.18.0.0,广播 198.18.0.3
可用只有两个:198.18.0.1 和 198.18.0.2

路由表第 5 节:

198.18.0.0/30      0.0.0.0   FlClash   Local
198.18.0.1/32      0.0.0.0   FlClash   Local
198.18.0.3/32      0.0.0.0   FlClash   Local

ARP 表:

Interface: 198.18.0.1 --- 0x10
  198.18.0.1                            dynamic
  198.18.0.2                            dynamic
  198.18.0.3                            static

注意 198.18.0.x 这几行的 MAC 地址是空的。为什么?

因为这是块 TUN 虚拟网卡(代理软件建的),它工作在 IP 层,根本没有二层, 自然没有 MAC 地址。ARP 表里留了几行空记录,是 Windows 协议栈的惯性行为。

/30 的实用意义:常规IPv4子网去掉网络号和广播后恰有两个主机地址。 但它不是无条件的最小可用网段:RFC 3021允许点到点链路使用/31,两端都可用;/32用于单地址配置与主机路由。 这是点到点链路(比如 VPN 隧道)的经典配置。

1.3.3 /20 —— 最容易算错的那个

vEthernet (WSL)  172.30.0.1/20  →  网络号 172.30.0.0,广播 172.30.15.255
可用范围 172.30.0.1 ~ 172.30.15.254(4094 个)

关键点:第三段不是 0~255,而是 0~15。

因为 /20 只给了第三段 4 位、第四段 8 位当主机号(4+8=12 位), 而第三段的高 4 位属于网络号。所以第三段每 16 个地址就换一个网段。

验证(lab_subnet_verify_output.txt 第三部分):

  172.30.14.213    在网段内,可用
  172.30.15.255    在网段内,但它是广播地址(不能给主机用)
  172.30.15.254    在网段内,可用
  172.30.16.1      在网段外 —— 它属于下一个 /20 网段 172.30.16.0/20

ARP 表提供了漂亮的旁证:

Interface: 172.30.0.1 --- 0x22
  172.30.14.213         00-15-5d-fb-2f-0a     dynamic   ← 有真实 MAC,是真主机
  172.30.15.255         ff-ff-ff-ff-ff-ff     static    ← 广播,MAC 全 1

.14.213 落在范围内,有真 MAC;.15.255 恰好在范围的最末端,是广播,MAC 全 1。 代码算出来的边界和系统实际行为又对上了。

1.3.4 /16 与 169.254.x.x —— DHCP 失败长什么样

蓝牙网络连接  169.254.215.100/16  →  网络号 169.254.0.0,广播 169.254.255.255

169.254.0.0/16 是 RFC 3927 规定的链路本地地址段(APIPA)。 规则很简单:如果一台机器开着 DHCP 但拿不到地址,就自己从这一段里随机挑一个。

本机有 6 个接口是 169.254.x.x:

接口地址
以太网169.254.163.90
本地连接169.254.114.105
本地连接* 9169.254.177.27
本地连接* 10169.254.119.78
Heysocks169.254.37.161
蓝牙网络连接169.254.215.100

169.254/16是有效的链路本地地址。 在Windows启用DHCP的接口上,它常提示没有获得DHCP地址;但也可能是配置或历史状态,不能由地址单独确定失败原因,更不能代表其他网卡或IPv6也不能通信。

这也解释了一个常见困惑:为什么这些接口明明没网,却看起来配置齐全? 因为 APIPA 把地址配好了 —— 能通局域网,但不能跨路由器, 而且没有默认网关。看第 3 节,这 6 个接口确实一条默认路由都没贡献。

心算法:块大小(不用计算器)

考试和排障时最实用的一招:

块大小 = 256 - (掩码中"那个关键段"的值)
网络号 = IP 对应段的值 - (该值 mod 块大小)
广播   = 网络号 + 块大小 - 1

关键段指掩码里既不是 255 也不是 0 的那一段。掩码全是 255 和 0 时, 关键段就是第一个为 0 的段(块大小 256)。

拿本机三个真实例子走一遍:

① 192.168.31.215/24
   掩码 255.255.255.0 → 关键段是第 4 段,值 0 → 块大小 = 256 - 0 = 256
   网络号:215 - (215 mod 256) = 215 - 215 = 0  → 192.168.31.0     ✔
   广播  :0 + 256 - 1 = 255                    → 192.168.31.255   ✔

② 172.30.0.1/20
   掩码 255.255.240.0 → 关键段是第 3 段,值 240 → 块大小 = 256 - 240 = 16
   网络号:0 - (0 mod 16) = 0                   → 172.30.0.0       ✔
   广播  :第 3 段 0 + 16 - 1 = 15,第 4 段全体 255 → 172.30.15.255  ✔

③ 198.18.0.1/30
   掩码 255.255.255.252 → 关键段第 4 段,值 252 → 块大小 = 256 - 252 = 4
   网络号:1 - (1 mod 4) = 1 - 1 = 0            → 198.18.0.0       ✔
   广播  :0 + 4 - 1 = 3                        → 198.18.0.3       ✔

三个都和代码算出来的完全一致。心算完,再用脚本验一遍,这才是可靠的流程。

动手:跑一遍验证脚本

示例powershell
python labs\lab_subnet_verify.py

这个脚本做三件事:

  1. 用 ipaddress 模块算出每个接口的网络号、掩码、广播、可用范围
  2. 拿 ARP 表交叉验证:每个邻居是不是真的落在同一个网段里
  3. 专门验证 /20 的边界断点

第二部分输出(节选):

  192.168.31.1       dynamic  网关        同网段=是     普通主机
  192.168.31.255     static   广播地址     同网段=是     广播?
  198.18.0.3         static   广播地址     同网段=是     广播?
  172.30.14.213      dynamic  WSL 侧主机   同网段=是     普通主机

这一步的意义:手算掩码很容易错,而且错了往往不自知(因为你不会去验证)。 让程序算、再和系统实际行为对照,对不上就说明算错了。

练一练

不看下文,先算这几个,再用脚本验证:

4 题 · 先自己答,再展开对照

  1. 10.0.5.77/22 的网络号和广播地址?
    /22 → 掩码 255.255.252.0,关键段第 3 段,块大小 = 256-252 = 4。
    网络号:5 - (5 mod 4) = 5 - 1 = 4 → 10.0.4.0;广播 → 第 3 段 4+4-1 = 7,第 4 段 255 → 10.0.7.255。
  2. 192.168.100.200/26 里能放多少台主机?可用范围?
    /26 → 掩码 255.255.255.192,块大小 = 256-192 = 64。总地址 64 个,可用 62 台。
    网络号:200 - (200 mod 64) = 200 - 8 = 192 → 192.168.100.192;广播 → 192+64-1 = 255 →
    可用范围 192.168.100.193 ~ 192.168.100.254。
  3. 判断:172.16.10.5/21 和 172.16.15.200/21 同网段吗?
    /21 → 掩码 255.255.248.0,块大小 = 256-248 = 8。
    10 mod 8 = 2 → 网络号 172.16.8.0;15 mod 8 = 7 → 网络号 172.16.8.0。
    同网段(范围是 172.16.8.0 ~ 172.16.15.255)。注意:这里"第三段相同"的直觉会骗人 ——
    10 和 15 看着不同,但都在 8~15 这一块里。
  4. 判断:192.168.1.10/24 和 192.168.1.10/25 是同一个网段吗?
    不是。/24 的网络号是 192.168.1.0(范围 .0~.255);/25 的关键段是第 4 段、
    值 128、块大小 128,网络号 = 1.10 的 10 mod 128 = 10 → 192.168.1.0,
    范围 .0~.127。地址相同但掩码不同 → 可用范围不同 → 广播地址不同(.255 vs .127)。
    网络里两边掩码不一致是经典故障源。

常见错误

错误 1:把子网掩码的每一段当成独立数字

255.255.240.0 里的 240 不是"240 台主机"。第三段的块大小是 256-240 = 16, 第三段只能取 0, 16, 32, 48, ...。

错误 2:以为"IP 前三段一样就是同网段"

双方采用相同/24掩码时,前三字节相同即可判断同前缀;相同/20或/22下也不会因此跨子网。反例应是/25或/26:例如192.168.1.10/25与192.168.1.200/25前三字节相同却分属两个子网。 永远按掩码算,别看地址长相。

错误 3:忽略两台主机掩码不一致

同网段判断是双方各自用掩码算。如果 A 是 /24、B 是 /25, A 认为 B 在同网段,B 可能认为 A 需要过网关 —— 通信就会单向失败。 排障时必须两边都查掩码。

错误 4(程序员的坑):字节序

这是本次实测中真实踩到的。想在 PowerShell 里把前缀长度转成掩码:

示例powershell
# 错误写法
$bits = [uint32]([math]::Pow(2,32) - [math]::Pow(2,32 - 30))
([IPAddress]$bits).ToString()
# 输出 252.255.255.255   ← 完全错了,字节序颠倒

正确写法:

示例powershell
$bits  = [uint32]([math]::Pow(2,32) - [math]::Pow(2, 32 - $prefixLength))
$bytes = [BitConverter]::GetBytes($bits)    # 得到小端字节序
[array]::Reverse($bytes)                    # 翻成网络序
([IPAddress]$bytes).ToString()              # /30 -> 255.255.255.252  ✔

根因:网络字节序是大端,而 x86 是小端。IPAddress 的数值构造重载 按小端解释,于是 8 位数翻转了。这个坑在写任何协议解析代码时都会遇到 —— IP/TCP/UDP等协议的多字节整数字段按网络字节序;应用载荷的编码由其协议定义,并非所有数据都大端,所有 ntohs / htonl 就是为了处理这件事。

本章小结

结论状态
掩码决定网络号/主机号的分界,判断同网段靠按位与原理
常规IPv4子网主机数通常为总数减2;/31点到点与/32另论有条件计算
本机同时存在 /16、/20、/24、/30 四种前缀实测
掩码算出的网络号/广播,与路由表和 ARP 表完全吻合实测
6 个接口处于 169.254/16,说明 DHCP 未成功实测
/20 的第三段以 16 为步长,172.30.15.255 是广播实测
00-15-5D 属于 Hyper-V判断(未查 OUI 库)

下一章:这些地址要真正通信,还需要 TCP 把连接建起来。 TCP章节记录本地连接状态实验;仅凭状态表无法逐包观察线上握手,真正观察报文需要抓包。

参考资料与适用范围

修订核对日期:2026-10-13。规则按所列协议与实现范围理解;文中的原始命令输出是历史观察,不表示本次重新实测。跨版本、代理/隧道及不同捕获位置需要另行核对。

正文源自 m3-02-IP地址与子网划分.md · 共 9 节 · 4 道自测题