人人都能学编程
English 开始学习
核心 · 计算机网络第 1 课 / 共 6 课免费阅读

IP 地址与子网 · 计算机网络

几十亿台电脑里,一台电脑怎么找到另一台?

课程目录

为什么需要它

网络上每台设备都有一个 IP 地址,每台云服务器、每条防火墙规则、每个 Docker 网络,都是用 10.0.0.0/16 这样的地址和范围来配置的。读得懂这些,你一眼就能看出两台机器能不能直接通信,也能看出一条规则为什么匹配或不匹配。

直觉理解

一个 IPv4 地址是 32 位,写成四个 0 到 255 之间的数:192.168.1.20。

它分成两部分,就像街道和门牌号:

  • 网络部分(街道):在哪个网络上
  • 主机部分(门牌号):这个网络上的哪台设备

/24 表示前面多少位是网络部分:这里是前 24 位(192.168.1),剩下 8 位,所以有 2⁸ = 256 个地址。同一个网络里的设备直接通信;否则数据包要经过路由器(默认网关)。

有些范围是私有的(10.x、172.16–31.x、192.168.x):用在家里、办公室和云里,不能从互联网直接访问。

定义

CIDR 前缀

The /n after an address: the first n bits name the network. /24 = 256 addresses, /16 = 65,536, /32 = exactly one address.
地址后面的 /n:前 n 位表示网络。/24 = 256 个地址,/16 = 65,536 个,/32 = 正好一个地址。

默认网关

The router a device sends packets to when the destination is outside its own network.
当目的地不在自己的网络里时,设备把数据包发给的那个路由器。

示例

地址只是数字

动手试试

Python 的 ipaddress 模块替你处理这些位运算。

import ipaddress

net = ipaddress.ip_network("192.168.1.0/24")
print(net.num_addresses)
print(ipaddress.ip_address("192.168.1.20") in net)
print(ipaddress.ip_address("192.168.2.20") in net)
print(ipaddress.ip_address("10.0.0.5").is_private)
逐步执行
  1. L432 − 24 = 8 位主机位:2⁸。256
  2. L5前 24 位相同:同一个网络。True
  3. L6第三个数不同:另一个网络,要经过路由器。False
  4. L710.x 是私有地址段。True

手工计算

动手试试

/24 掩码保留前三个数。比较它们,就知道两个地址是不是同一个网络。

def to_bits(ip):
    return "".join(format(int(part), "08b") for part in ip.split("."))

print(to_bits("192.168.1.20"))
a, b = to_bits("192.168.1.20"), to_bits("192.168.1.99")
print(a[:24] == b[:24])
逐步执行
  1. L2每个数变成 8 位二进制。
  2. L432 位:192 是 11000000,168 是 10101000,依此类推。11000000101010000000000100010100
  3. L6前 24 位相同:同一个 /24 网络。True

常见错误

防火墙里写 0.0.0.0/0

/0 表示网络位为零:互联网上的所有地址。允许 0.0.0.0/0 访问 SSH,就是对全世界开放。

数字越大,网络越小

/28 比 /24 小:网络位越多,主机位越少(16 个地址对 256 个)。

小测验

1. 这段代码会输出什么?

import ipaddress
print(ipaddress.ip_network("10.0.0.0/28").num_addresses)
  1. A
    16
  2. B
    28
  3. C
    256
查看答案

答案:A

32 − 28 = 4 位主机位:2⁴ = 16。

2. 你的笔记本是 192.168.1.20/24。它不经过路由器能直接访问哪个地址?

  1. A192.168.1.200
  2. B192.168.10.2
  3. C8.8.8.8
查看答案

答案:A

只有 192.168.1.x 的前 24 位相同。

动手练习

3 道练习,分三层:先预测程序的输出,再按新需求改程序,最后从零写一个。代码在浏览器里运行,提交马上判题。

  1. 预测输出读懂范围

    准确写出这段程序的输出。

  2. 改需求比较网络,不是字符串

    same_network(a, b) 应该判断两个 IPv4 地址是否在同一个 /24 里。它比较的是前 10 个字符,对 10.0.0.1 和 10.0.0.200 等很多情况都是错的。改成比较前三个数。

  3. 从零写匹配哪条规则?

    写函数 route(ip, table),table 是 (网络, 名字) 对组成的列表,比如 ("10.0.0.0/8", "office")。返回匹配的网络中前缀最长(最具体)的那个的名字;都不匹配时返回 "internet"。用 ipaddress 模块。

在互动课里练这一课

打开互动课,这些例子都能直接改、直接运行,练习题提交马上判题。免费开始,不用注册。

本课术语

术语中文英文定义
IP addressIP 地址A number that identifies a device on a network, such as 192.168.1.20.
Subnet子网A range of addresses sharing the same network prefix, such as 10.0.1.0/24.
Router路由器A device that forwards packets between networks.