IP 地址分类与子网掩码
你有没有想过:当你配置电脑网络时,为什么要填「IP 地址」「子网掩码」「默认网关」这三个东西?
很多程序员知道「IP 地址就是设备的门牌号」,但问到子网掩码,就一脸茫然了。这篇文章帮你彻底理解它们。
IP 地址的本质
IP 地址是分配给网络设备的逻辑地址,用于在网络层标识设备、实现路由选择。IPv4 地址是 32 位,用点分十进制表示:
11000000.10101000.00000001.00000001
↓
192.168.1.132 位意味着只有约 42 亿个地址——在互联网爆发式增长的年代,这远远不够,于是有了 IPv6(128 位)。但今天我们主要讨论 IPv4。
IP 地址分类
早期 IPv4 地址被分成五类(Class A-E):
┌────┬─────────────────────────────┬──────────────────────┬────────────┐
│ 类别 │ 地址范围 │ 网络数 │ 主机数 │
├────┼─────────────────────────────┼──────────────────────┼────────────┤
│ A │ 0.0.0.0 - 127.255.255.255│ 2^7 - 2 = 126 │ 2^24 - 2 │
│ B │ 128.0.0.0 - 191.255.255.255│ 2^14 = 16384 │ 2^16 - 2 │
│ C │ 192.0.0.0 - 223.255.255.255│ 2^21 = 2097152 │ 2^8 - 2 │
│ D │ 224.0.0.0 - 239.255.255.255│ 多播地址 │ 不可用 │
│ E │ 240.0.0.0 - 255.255.255.255│ 保留(研究/实验) │ 不可用 │
└────┴─────────────────────────────┴──────────────────────┴────────────┘各类地址详解
A 类地址:第一位固定为 0
0xxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx
↑
固定为 0- 网络号:8 位(第一位固定,实际可用 7 位)
- 主机号:24 位
- 第一个八位组范围:0-127(但 0 和 127 有特殊用途)
- 典型代表:
10.0.0.0(大型企业、政府机构)
B 类地址:前两位固定为 10
10xxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx
↑↑
固定为 10- 网络号:16 位(但前两位固定,实际可用 14 位)
- 主机号:16 位
- 第一个八位组范围:128-191
- 典型代表:
172.16.0.0到172.31.255.255(教育网、政务网)
C 类地址:前三位固定为 110
110xxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx
↑↑↑
固定为 110- 网络号:24 位(但前三位固定,实际可用 21 位)
- 主机号:8 位
- 第一个八位组范围:192-223
- 典型代表:
192.168.0.0(私有网络,家庭/公司局域网)
特殊 IP 地址
0.0.0.0 :「本网络」地址,表示当前主机
255.255.255.255:受限广播地址,仅在本地网络广播
127.0.0.1 :本地回环地址(loopback),本机测试
x.x.x.0 :网络地址(主机号全为 0,表示整个网络)
x.x.x.255 :广播地址(主机号全为 1,发送给整个网络)私有地址(保留地址)
以下地址段不在公网上路由,仅用于私有网络:
10.0.0.0 - 10.255.255.255 (1 个 A 类网络)
172.16.0.0 - 172.31.255.255 (16 个 B 类网络)
192.168.0.0 - 192.168.255.255 (256 个 C 类网络)这就是为什么你家、公司、咖啡馆的 IP 地址大多都是 192.168.x.x。
子网掩码:划分子网的关键
为什么需要子网掩码?
在分类地址时代,网络号和主机号的界限是固定的:
- A 类:网络号 8 位,主机号 24 位
- B 类:网络号 16 位,主机号 16 位
- C 类:网络号 24 位,主机号 8 位
但这太死板了。比如一个 B 类网络有 65534 台主机,太大了!于是出现了子网划分——把主机号的一部分「借」出来作为子网号。
子网掩码的定义
子网掩码(Subnet Mask)用于指示 IP 地址中哪些位是网络位(包括子网位),哪些位是主机位。
规则:子网掩码中,1 对应 IP 地址的网络位,0 对应主机位。
IP 地址: 192.168.1.100 (11000000.10101000.00000001.01100100)
子网掩码: 255.255.255.0 (11111111.11111111.11111111.00000000)
↓
网络地址: 192.168.1.0 (11000000.10101000.00000001.00000000)
主机地址范围: 192.168.1.1 - 192.168.1.254(主机位不能全 0 全 1)子网掩码的表示方法
点分十进制: 255.255.255.0
CIDR 表示法: /24 (表示前 24 位是网络位)/24 是最常用的 CIDR 记法,它简洁地表示了子网掩码。
常见的 CIDR 表示
| CIDR | 子网掩码 | 可用主机数 | 相当于 |
|---|---|---|---|
| /30 | 255.255.255.252 | 2 | 点对点链路 |
| /28 | 255.255.255.240 | 14 | 小型子网 |
| /27 | 255.255.255.224 | 30 | 小型子网 |
| /26 | 255.255.255.192 | 62 | 中小型子网 |
| /25 | 255.255.255.128 | 126 | 中型子网 |
| /24 | 255.255.255.0 | 254 | 标准 C 类 |
| /16 | 255.255.0.0 | 65534 | 标准 B 类 |
| /8 | 255.0.0.0 | 16777214 | 标准 A 类 |
子网划分实例
假设你有一个 192.168.1.0/24 网络,需要划分给 4 个部门:
原始网络: 192.168.1.0/24
子网掩码: 255.255.255.0
主机范围: 192.168.1.0 - 192.168.1.255(256 个地址)
借 2 位做子网:
子网掩码: 255.255.255.192 (/26)
每个子网: 64 个地址(62 可用)
子网 1: 192.168.1.0/26 → 192.168.1.1 - 192.168.1.62
子网 2: 192.168.1.64/26 → 192.168.1.65 - 192.168.1.126
子网 3: 192.168.1.128/26 → 192.168.1.129 - 192.168.1.190
子网 4: 192.168.1.192/26 → 192.168.1.193 - 192.168.1.254子网掩码的作用
1. 判断两个 IP 是否在同一网段
java
public class SubnetCalculator {
public static boolean isSameSubnet(String ip1, String ip2, String mask) {
long[] ips = parseIps(ip1, ip2, mask);
// 网络地址相同,则在同一网段
return (ips[0] & ips[2]) == (ips[1] & ips[2]);
}
private static long[] parseIps(String ip1, String ip2, String mask) {
return new long[]{
ipToLong(ip1),
ipToLong(ip2),
ipToLong(mask)
};
}
public static long ipToLong(String ip) {
String[] parts = ip.split("\\.");
long result = 0;
for (int i = 0; i < 4; i++) {
result |= (Long.parseLong(parts[i]) << (8 * (3 - i)));
}
return result;
}
public static void main(String[] args) {
// 192.168.1.10 和 192.168.1.20 在同一网段吗?
System.out.println(isSameSubnet(
"192.168.1.10",
"192.168.1.20",
"255.255.255.0"
)); // true
// 192.168.1.10 和 192.168.2.20 在同一网段吗?
System.out.println(isSameSubnet(
"192.168.1.10",
"192.168.2.20",
"255.255.255.0"
)); // false
}
}2. 计算网络地址和广播地址
python
def calculate_network(ip, mask_cidr):
"""计算网络地址和广播地址"""
ip_int = sum(int(octet) << (8 * (3 - i)) for i, octet in enumerate(ip.split('.')))
mask_int = (0xFFFFFFFF << (32 - mask_cidr)) & 0xFFFFFFFF
network_int = ip_int & mask_int
broadcast_int = network_int | (~mask_int & 0xFFFFFFFF)
def int_to_ip(x):
return '.'.join(str((x >> (8 * i)) & 0xFF) for i in range(4))
return int_to_ip(network_int), int_to_ip(broadcast_int)
# 示例
network, broadcast = calculate_network('192.168.1.100', 26)
print(f"网络地址: {network}") # 192.168.1.64
print(f"广播地址: {broadcast}") # 192.168.1.127变长子网掩码(VLSM)
实际网络中,不同部门需要的 IP 数量不同——服务器可能需要 /28,部门可能需要 /26。
VLSM(Variable Length Subnet Mask)允许同一网络使用不同长度的子网掩码:
公司网络 192.168.1.0/24 划分:
服务器区: 192.168.1.0/28 (16 地址,14 可用)
财务部: 192.168.1.16/28 (16 地址,14 可用)
技术部: 192.168.1.32/27 (32 地址,30 可用)
市场部: 192.168.1.64/27 (32 地址,30 可用)
其他部门: 192.168.1.96/27 (32 地址,30 可用)
剩余地址: 192.168.1.128/25 (保留)面试追问方向
- IP 地址的分类是怎样的?私有地址有哪些?
- 子网掩码的作用是什么?为什么要划分子网?
- 如何判断两个 IP 地址是否在同一网段?
- 什么是 CIDR?和传统的分类网络有什么区别?
- 什么是 VLSM?
- 为什么主机号不能全为 0 或全为 1?
- 网络地址和广播地址的作用分别是什么?
