📚 第四章 IP协议
📄 一句话概括

同一个 IP 地址,前面几位是「哪个网络」,后面几位是「网络里的哪台」。 分界线在哪,历史上靠「分类」,现在靠「掩码」。

📝 本节和前面几节的关系

4.3.1 讲「32 位怎么写」,这一节讲「这 32 位怎么分工」。 「网络部分」就是路由表能聚合的前提(4.2.2 讲的最长前缀)。

一、分界线在哪

三类地址的分法:

类别 网络位 主机位 每网主机 网段数
A 类 8 位 24 位 16777214 128 个 /8
B 类 16 位 16 位 65534 16384 个 /16
C 类 24 位 8 位 254 2097152 个 /24

第一行那个「24 位主机」就是 A 类的问题所在:一个网络一千六百万台,谁拿了都用不完, 而「网段数」只有 128 个——所以 A 类地址既浪费、又不够分。 第三行正好相反:一个 C 类只装 254 台,网段数有两百多万个, 所以「小网络」够用,「大网络」只能靠拼。 这就是「分类地址」的两头不讨好。

二、为什么要减 2

「主机位全 0」和「全 1」是两个特殊值:

主机位 含义 能不能给主机
全 0 代表「这个网络本身」 不能
全 1 代表「这个网络里所有主机」 不能
其他 一台具体主机 能

第一行是「网络地址」:路由表里写的 192.168.3.0/24 就是这个, 它表示「整段网络」,不是「某台机器」。 第二行是「广播地址」(4.3.4 细讲)。 所以「254 台」这个数不是随便定的:256 个地址里扣掉两个特殊值,剩 254。 同理 /28 是 16 减 2 得 14,/30 是 4 减 2 得 2。 一个例外要说清:/31 只有 2 个地址,减 2 之后是 0,所以传统上「不能用来接主机」。 但 RFC 3021 允许「点对点链路两端各用一个」, 因为它不需要广播地址——所以「减 2」是习惯,不是铁律。

三、分类的毛病

把三类占的空间加起来,能看出问题的性质:

类别 覆盖比例 问题
A 类 50% 网段太少、每段太大
B 类 25% 中间档,最先耗尽
C 类 12.5% 每段太小、段数太多

第一行 50% 的地址空间只切成 128 块,所以「一个机构拿一个 A 类」的制度很快就退不下去了。 第二行的 B 类是最先耗尽的——因为它「不大不小」,正好适合大多数机构申请, 1994 年前后 B 类地址就用完了。 这就是两套补丁的由来:子网划分(把一个类再切细)解决「C 类太小」, CIDR(彻底不管类别)解决「A 类太大」。 两者都在做同一件事:把「分界线」从「类别决定」改成「掩码决定」。 所以今天说「网络部分和主机部分」时,已经默认是「掩码划的」,不是「类别定的」。 「A 类地址」这个词现在只在两种场合还活着: 说「10.0.0.0/8 是 A 类私有段」,以及「默认掩码」这个历史习惯。

四、动手 Demo:网络部分和主机部分怎么分

三类地址的网络位、主机位、每网主机数与网段数摆在一起。 注意第五列:A 类只有 128 个网段,C 类有两百多万个。

for cls, netbits, blocks in (('A 类', 8, 128), ('B 类', 16, 16384),
                             ('C 类', 24, 2097152)):
    hostbits = 32 - netbits
    n = blocks * 2 ** hostbits
    print('%-5s 网络 %2d 位 主机 %2d 位 每网 %8d 台 占 %.1f%%'
          % (cls, netbits, hostbits, 2 ** hostbits - 2,
             100.0 * n / 2 ** 32))

实跑输出:

--------------------------------------------------------------------
网络部分和主机部分怎么分
--------------------------------------------------------------------
**同一个 IP 地址,前面的位是「哪个网络」,后面是「网络里的哪台」。**
**分界线在哪,历史上靠「分类」,现在靠「掩码」。**

  类别     网络位     主机位     每网主机数     网络个数
  -------------------------------------------------------------
  A 类     8 位       24 位      16777214       128 个 /8
  B 类     16 位      16 位      65534          16384 个 /16
  C 类     24 位      8 位       254            2097152 个 /24

**第四列那个「减 2」是必须的**:**全 0 是网络地址(代表「这个网络本身」),全 1 是广播地址**,
**两个都不能分给主机。**
**所以 /24 的「256 个地址」实际只能装 254 台。**

**第五列是「这类地址占了多少个网段」,不是「能装多少台」**:
**A 类首比特是 0,所以理论上占 2 的 7 次方共 128 个 /8。**
**B 类是 2 的 14 次方共 16384 个 /16;C 类是 2 的 21 次方共 2097152 个 /24。**

**算一下三类各覆盖多少地址**:
**A 类:128 个网乘 16777216,得 2.15e+09 个地址,占 50.0%**
**B 类:16384 个网乘 65536,得 1.07e+09 个地址,占 25.0%**
**C 类:2097152 个网乘 256,得 5.37e+08 个地址,占 12.5%**

**三个百分比加起来正好 87.5%**,**剩下的 12.5% 是 D 类多播和 E 类保留各占 6.25%。**
**所以「分类」把一个 32 位的空间切得干干净净,一点不剩。**

**A 类的「一个网络装 1677 万台」是分类地址最大的毛病**:
**拿到一个 A 类的机构,实际用不到百分之一,其余全浪费。**
**所以后来才有子网划分和 CIDR**——**本质都是「把分界线挪一挪,别让类别决定一切」。**

「网络部分」存在的唯一理由就是「聚合」:因为同一个网络里的所有主机,路由表只需要一条。 所以「主机位」越长,能聚合的粒度越细、表越大。 「网络位」和「主机位」的比例,本质上是「路由表大小」和「网段内主机数」的取舍。 一个反直觉的事实:「网络位越多,路由表越大」——因为网段更多了。 所以「划分子网」不是免费的:每多切一刀,就多一条路由。 这就是为什么「子网不能乱切」——切太细会让路由器的表膨胀。 顺带说清「为什么主机数总是 2 的幂减 2」:因为主机位是二进制,所以可能的组合一定是 2 的幂。 「减 2」之后就不是 2 的幂了——所以「254」这个数看着别扭,但它是对的。

30 秒实验

  1. 算一下:一个 /26 的网段能接多少台主机?
  2. 想一下:为什么「划分子网」会让路由表变大?
  3. 想一下:/31 为什么可以「不减 2」?

常见误区

  1. 以为「256 个地址能接 256 台」。 能接 254 台,网络地址和广播地址各占一个。
  2. 以为「网络部分越长越好」。 路由表会膨胀,所以切分要有节制。
  3. 以为「减 2 是硬规定」。 /31 就不用减(RFC 3021),点对点链路两端各一个。
自测三问(点开对答案) 1. /24 的网段能接多少台主机? —— **254 台**(256 减掉网络地址和广播地址)。 2. 网络地址和广播地址分别是什么? —— **主机位全 0 是网络地址,全 1 是广播地址**,两个都不能给主机。 3. 分类地址最大的毛病是什么? —— **A 类太大(一段一千六百万台)、C 类太小(只 254 台)**,两头都不合用。

下一节看五类地址的「首位模式」。

相关笔记