Old-School Networking / 2026 ・ No.04

古法网络入门

第4讲 IP 地址 ── 32 位的地址与“/24”,DHCP,还有 IPv6

发布

Wireshark 的界面。上方列表排着 DHCP Discover 2 个、路由器发出的 ARP 3 个、Offer 2 个、Request、ACK,选中的是第 9 个 ACK。详情里可以看到 Your (client) IP address: 10.0.1.177,以及 Option (51) IP Address Lease Time、Option (1) Subnet Mask (255.255.255.0) 等
没有地址的电脑通过 DHCP 获取地址。第 9 个 ACK 里写着地址 10.0.1.177、掩码、路由器、DNS 和 1 小时的租期(在笔者于云端搭建的练习用网络中,于 2026 年 10 月 24 日记录,用 Wireshark 4.2.2 打开后截图。界面保持英文。窗口上方的标题栏是为了说明而后加的)

第 3 讲的 MAC 地址是“到相邻设备”的收件人。从这一讲开始进入第 3 层,网络层。
前半讲 IP 地址本身。10.0.1.10 有多少位?“/24”表示什么?把掩码弄错一个会发生什么?我们实际弄错来确认。
后半讲获取地址的机制(DHCP)、地址不够用的故事,以及 IPv6。路由器如何指路,留到下一讲。

一

地址这一层

新井“/24”的意思是作业吧,我查了!……是子网掩码的,那个,什么。

古井对了一半。那如果写错成 /16,申请会怎样?

新井诶,只是范围大了一点,应该也能送到吧?

古井试试看。要犯错,在练习网络里犯最便宜。

全 12 讲路线图(当前位置:第 4 讲)

1 全景图 2 物理层 3 数据链路层 4 IP 地址 5 路由器 6 TCP 7 UDP・套接字 8 TLS 9 DNS 10 HTTP 11 开发者的网络 12 故障排查 当前位置 全景图 第1层 第2层 第3层 第4层 第5・6层 第7层 实战
  • IP 地址的构成 ── 32 位,网络号和机器号,/24 与掩码
  • 发送前的判断 ── 对方在同一网络吗?弄错会怎样(实测)
  • 特殊地址与 DHCP ── 私有、127、169.254。获取地址的四次往来(实测)
  • 地址耗尽与 IPv6 ── 2011 年库存耗尽的故事,以及 128 位的地址
二

IP 地址是 32 位

第 3 讲的 MAC 地址是“到相邻设备”的收件人,每经过一台路由器就被换掉。相对地,IP 地址是到最终对方的地址,途中不会改变。

IPv4 地址是 32 位(4 字节)。每 8 位一段分成 4 段,每段写成 0〜255 的十进制,再用“.”连起来,就是熟悉的 10.0.1.10。

10.0.1.10 就是 32 个 0 和 1

0 0 0 0 1 0 1 0 10 0a . 0 0 0 0 0 0 0 0 0 00 . 0 0 0 0 0 0 0 1 1 01 . 0 0 0 0 1 0 1 0 10 0a 网络号(24 位) 机器号 10.0.1.0/24 的同伴 8 位=256 种 十六进制 “10.0.1.10/24”的 /24,表示从前面数几位是网络号 地址=哪个网络里的哪台机器
Wireshark 的界面。打开第 1 讲申请的数据包,选中 Internet Protocol Version 4 详情里的 Source Address: 10.0.1.10。字节栏里 0a 00 01 0a 这 4 个字节变成蓝色
在第 1 讲申请的数据包里选中源 IP 地址。10.0.1.10 就是字节栏里的 0a 00 01 0a 这 4 个字节(紧接着的 0a 00 02 14 是目的地址 10.0.2.20)(在笔者于云端搭建的练习用网络中,于 2026 年 10 月 24 日记录,用 Wireshark 4.2.2 打开后截图。界面保持英文。窗口上方的标题栏是为了说明而后加的)

地址分成两部分。前面是网络号(哪个城镇),后面是机器号(几号门牌)。表示在哪里分开的就是“/24”这个数字,意思是从前面数 24 位是网络号。

# 第 1 讲电脑的地址
$ ip -4 addr show eth0
    inet 10.0.1.10/24 scope global eth0
# 写成二进制(/24=前 24 位是网络号,剩下 8 位是机器号)
address  00001010.00000000.00000001.00001010   10.0.1.10
mask     11111111.11111111.11111111.00000000   255.255.255.0
# 地址与掩码做 AND(两边都是 1 的位才是 1)=网络号
network  00001010.00000000.00000001.00000000   10.0.1.0
三

“/”后的数字与掩码

/24 和“前 24 位是 1、其余是 0”的 32 位掩码表示同一件事。写成十进制是 255.255.255.0。以前通常写成掩码的形式,现在常用简短的“/24”(CIDR 表示法)。

“/”后的数字越大,网络越小

长度 蓝=网络 朱=机器 掩码 地址数 /8 255.0.0.0 16,777,216 /16 255.255.0.0 65,536 /24 255.255.255.0 256 /26 255.255.255.192 64 /30 255.255.255.252 4 /32 255.255.255.255 1

/24 的网络有 256 个地址,但能分配给机器的是 254 个。因为第一个(10.0.1.0)保留为表示网络本身的编号,最后一个(10.0.1.255)保留为发给该网络所有人的编号。/30 的 4 个地址里能用 2 个,常用于两台路由器之间用一根线相连。

POINT

“/24”=前 24 位是网络号=掩码 255.255.255.0。数字每增加 1,网络就缩小一半。

四

同一网络,还是外面

/24 真正起作用的是发送前的判断。电脑在发送数据包前,会用自己的掩码截取对方地址和自己的地址进行比较。相同,对方就在同一网络,用 ARP 询问对方的 MAC 直接发送。不同,就是外面,交给路由器(默认网关)。

发送前的岔路口

对方 AND 掩码 = 自己的网络? 相同 不同 直接发给对方 用 ARP 询问对方的 MAC 交给路由器 询问路由器的 MAC 发往 10.0.2.20 时 /24:10.0.2.0 ≠ 10.0.1.0 → 交给路由器(正确) /16:10.0.0.0 = 10.0.0.0 → 直接(到不了) 掩码弄错,就会在这个岔路口走错

回到开头的问题。在第 1 讲的练习网络中,把新井电脑的地址分别设为正确的 10.0.1.10/24 和错误的 10.0.1.10/16,向路由器另一侧的服务器(10.0.2.20)发 ping。

# 正确的 /24:10.0.2.20 是“外面的”,所以经由路由器(10.0.1.1)发出
$ ip addr add 10.0.1.10/24 dev eth0
$ ip route get 10.0.2.20
    10.0.2.20 via 10.0.1.1 dev eth0 src 10.0.1.10 uid 0
$ ping -c 3 10.0.2.20
    3 packets transmitted, 3 received, 0% packet loss
# 误设 /16:把 10.0.2.20 也判断为“同一网络”,不经路由器直接发送
$ ip addr add 10.0.1.10/16 dev eth0
$ ip route get 10.0.2.20
    10.0.2.20 dev eth0 src 10.0.1.10 uid 0
$ ping -c 3 10.0.2.20
    3 packets transmitted, 0 received, 100% packet loss
并排显示两个 Wireshark 数据包列表。上面是正确设为 /24 时,询问路由器 MAC 的 ARP 一问一答之后,ping 往返 3 次。下面是误设为 /16 时,只排着 3 个询问 10.0.2.20 的 MAC 的 ARP,没有回答
掩码弄错后,以为对方在“同一网络”,一直询问根本不在这里的对方的 MAC(在笔者于云端搭建的练习用网络中,于 2026 年 10 月 24 日记录,用 Wireshark 4.2.2 打开后截图。界面保持英文。窗口上方的标题栏是为了说明而后加的)

设成 /16 后,电脑把 10.0.2.20 判断为“同一网络”,想不经过路由器直接发送,于是向所有人询问它的 MAC。可是服务器在路由器的另一边,没人回答。问了 3 次,一个 ping 也没发出去(100% 失败)。掩码不是“大一点、小一点”的问题,而是改变了选路的方式本身。

新井范围大了反而送不到……

古井就像以为“隔壁镇的人也住同一个小区”,在门口一直大声喊。明明交给邮局就能送到。

五

特殊的地址

IPv4 地址中,有一些保留给特殊用途。放在第一个字节的数轴上是这样的。

具有特殊含义的地址

0 64 128 192 255 第一个字节的值(0〜255) 10.0.0.0/8 私有(家里、公司内部自由使用) 172.16.0.0/12 私有 192.168.0.0/16 私有(家用路由器多用) 100.64.0.0/10 运营商共享(CGNAT、Tailscale) 127.0.0.0/8 自己(环回) 169.254.0.0/16 没有 DHCP 时自动分配 224.0.0.0/4 组播(发给一组) 255.255.255.255 本网络的所有人

最重要的是私有地址(10.0.0.0/8、172.16.0.0/12、192.168.0.0/16)。在家里或公司内部,不用向任何人申请就能自由使用。代价是不能直接在互联网上使用。本系列的 10.0.1.10 也是私有地址。家用路由器在出去时把它换成自己的全球地址(NAT),把许多机器藏在一个地址后面(第 5 讲)。

以 127 开头的地址是自己。127.0.0.1 最有名,但因为是 /8,只要以 127 开头就都是自己。

# 以 127 开头的地址,全都是“自己”
$ ping -c 1 127.42.42.42
    64 bytes from 127.42.42.42: icmp_seq=1 ttl=64 time=0.285 ms
$ ip addr show lo
    inet 127.0.0.1/8 scope host lo

如果自己的电脑上出现了以 169.254 开头的地址,说明没能从 DHCP 获取地址(见下一章)。100.64.0.0/10 是运营商在用户之间共享用的地址,Tailscale 那篇文章里见到的 100.x.y.z 也在这个范围内。

六

DHCP:获取地址

只要连上家里的 Wi-Fi,电脑就会有地址。分配地址的是路由器里的 DHCP 服务器。我给练习网络的路由器加上 DHCP,记录了没有地址的电脑获取地址的过程(封面照片)。

# 在没有地址的电脑上运行 dhclient 的记录(地址通过 DHCP 获取)
$ dhclient -v eth0
    DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 3 (xid=0xcc0bcf66)
    DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 5 (xid=0xcc0bcf66)
    DHCPOFFER of 10.0.1.177 from 10.0.1.1
    DHCPREQUEST for 10.0.1.177 on eth0 to 255.255.255.255 port 67 (xid=0x66cf0bcc)
    DHCPACK of 10.0.1.177 from 10.0.1.1 (xid=0xcc0bcf66)
    bound to 10.0.1.177 -- renewal in 1714 seconds.
# 收到的 ACK 里写着的内容(来自 Wireshark 的详情)
    Your (client) IP address: 10.0.1.177
    Subnet Mask:              255.255.255.0
    Router:                   10.0.1.1
    Domain Name Server:       10.0.1.1
    IP Address Lease Time:    1 hour (3600)
    Renewal Time Value:       30 minutes (1800)

实测:确定地址前的四次往来(以及等待时间)

新井的电脑(无地址) 路由器(DHCP) Discover 请给我地址(发给所有人) 0.000s Discover 请给我地址(发给所有人) 2.704s Offer 10.0.1.177 怎么样? 3.005s Request 我要这个 3.005s ACK 给你(1 小时) 3.006s 分配前对 10.0.1.177 ARP 3 次 确认没有机器在用

往来是“Discover(请给我)→ Offer(这个怎么样?)→ Request(我要这个)→ ACK(给你)”四个。没有地址的电脑既不知道自己的地址也不知道对方的,所以用源 0.0.0.0、目的 255.255.255.255(发给所有人)来喊。

有意思的是,确定地址花了约 3 秒。路由器在分配 10.0.1.177 之前,用 ARP 确认了 3 次有没有机器在用这个地址。其间电脑以为没有回应,又发了一次 Discover,所以收到了 2 个 Offer。

得到的地址有期限(租约)。这次是 1 小时,过了一半的 30 分钟(实际的 dhclient 加了随机偏差,是 1,714 秒)就会请求“续租”。电脑合着盖子让租约过期的话,地址可能会分给别的机器。

七

地址不够用

32 位能做出的地址是 232=约 43 亿个。比地球人口还少,而且还有特殊地址,以及早年的大块分配。

IP 地址年表

1981 IPv4 规范(RFC 791) 1996 私有地址(RFC 1918) 1998 IPv6 规范(RFC 2460) 2011 2/3 IANA、4/15 APNIC 库存耗尽 2012 World IPv6 Launch 2026 访问 Google 的约一半是 IPv6

全球地址总管 IANA 的库存在 2011 年 2 月 3 日耗尽。包括日本在内的亚太地区 APNIC,也在同年 4 月 15 日结束了常规分配。互联网之所以还在运转,是因为家庭和公司使用私有地址和 NAT,让许多机器共用一个全球地址。而根本的解决方案是 IPv6。

八

IPv6

IPv6 地址是 128 位。能做出的数量是 2128,不是 IPv4 的 4 倍,而是 296 倍。因为很长,所以每 16 位一组分成 8 组,用十六进制书写,并把连续的 0 缩写。

IPv6 地址的形式

2001 : 0db8 : 0000 : 0000 : 0000 : 0000 : 0000 : 0001 网络(通常 64 位) 机器号(64 位) 由运营商分配 可以自己生成 128 位=16 位 × 8(十六进制) 2001:db8::1 连续的 0 写成 ::,开头的 0 省略 2001:db8:: 是为举例保留的地址。和 IPv4 的 4 字节不同,有 16 字节

写这篇文章用的云端 Linux 没有 IPv6 功能,所以这里用 Python 的 ipaddress 计算来确认。

>>> import ipaddress
# 连续的 0 缩写成 ::,开头的 0 省略
>>> ipaddress.ip_address('2001:0db8:0000:0000:0000:0000:0000:0001').compressed
'2001:db8::1'
# 地址的数量
>>> 2 ** 128
340282366920938463463374607431768211456
>>> 2 ** 32
4294967296
# 用第 3 讲的 MAC 生成的链路本地地址(EUI-64:插入 ff:fe,翻转本地位)
>>> def eui64(mac):
...     b = bytes.fromhex(mac.replace(':', ''))
...     iid = bytes([b[0] ^ 0x02]) + b[1:3] + b'\xff\xfe' + b[3:]
...     return 'fe80::' + ':'.join(iid[i:i+2].hex() for i in range(0, 8, 2))
...
>>> ipaddress.ip_address(eui64('02:00:00:00:01:10'))
IPv6Address('fe80::ff:fe00:110')

在 IPv6 中,机器可以自己生成地址。前 64 位是路由器告知的网络号,后 64 位是自己生成的编号。以前是用第 3 讲的 MAC 地址生成的(上面的 EUI-64,第 3 讲的本地位在这里被翻转),但那样机器会被追踪,所以现在的操作系统通常使用随机编号。以 fe80:: 开头的地址是只在同一网络内使用的链路本地地址,IPv6 设备一定都有。

普及虽然缓慢,但稳步前进。访问 Google 的连接中使用 IPv6 的比例,在 2026 年 4 月首次达到约一半。现在很多家庭里 IPv4 和 IPv6 同时运行(双栈),哪个能用就选哪个。做服务器的一方,别忘了确认 IPv6 也在监听(第 7 讲)。

九

在自己的电脑上确认

想查什么MacWindowsLinux
自己的地址和掩码ifconfigipconfigip addr
默认网关netstat -rnroute printip route
DHCP 得到的内容ipconfig getpacket en0ipconfig /allnmcli -f DHCP4 device show
IPv6 能否到达ping6ping -6ping -6

在家里的电脑上看 ipconfig 或 ifconfig,通常会看到以 192.168 或 10 开头的地址(私有)和以 fe80:: 开头的地址。如果是以 169.254 开头,说明没能从 DHCP 获取地址。先检查路由器的电源和网线(第 2 讲)。

结 — 一页总结与下一讲

  1. IP 地址是到最终对方的地址。IPv4 是 32 位,10.0.1.10 就是 0a 00 01 0a 这 4 个字节。
  2. “/24”表示前 24 位是网络号=掩码 255.255.255.0。/24 有 256 个地址,可用 254 个。
  3. 发送前用掩码截取后比较,相同就直接发,不同就交给路由器。
  4. 误设成 /16,会一直询问路由器另一边对方的 MAC,ping 100% 失败。
  5. 私有(10、172.16、192.168),自己(127),DHCP 失败的标志(169.254)。
  6. DHCP 是 Discover、Offer、Request、ACK。实测因为路由器的确认,花了约 3 秒。租期 1 小时。
  7. IPv4 库存在 2011 年耗尽。IPv6 是 128 位,访问 Google 的连接约一半已是 IPv6。

新井知道是“外面”就交给路由器……那路由器又是怎么决定下一站的?

古井路由器有一张指路的表。下一讲讲这张表、利用 TTL 查路径的 traceroute,以及家用路由器的真面目。

参考

记录来自笔者在云端 Linux(Ubuntu 24.04)上用网络命名空间搭建的练习网络,于 2026 年 10 月 24 日抓取。DHCP 使用路由器角色的 dnsmasq(租期 1 小时)和 dhclient(isc-dhcp-client 4.4.3),其余与第 1 讲相同。表中的数字都是从这些记录和当时命令的输出读出的实际数值。该环境的内核没有 IPv6,所以 IPv6 的例子是用 Python 的 ipaddress 计算的。地址耗尽的日期依据 JPNIC,IPv6 的比例依据 APNIC Blog(Google 的统计,2026 年 4 月)。登场人物均为虚构。

古法网络入门 第4讲 — IP 地址 / 2026.10

← 返回文章列表