军用网络的第一条需求不是「快」,是「打不烂」。 这条需求直接决定了「去中心化」这个结构选择。
第一章讲完了网络的原理与零件,第二章回到历史:TCP/IP 是怎么来的。 这一节只讲一个因果链:需求 → 拓扑 → 协议。
一、需求决定形态
冷战背景下的通信需求,和今天完全不同:
| 需求 | 含义 | 排除掉的方案 |
|---|---|---|
| 抗摧毁 | 部分节点被毁,剩下的还能通 | 中心交换机 |
| 无中心 | 没有一个「必须存在」的节点 | 星型结构 |
| 可自治 | 每段能自己决定怎么走 | 集中式路由 |
第一行是核心:传统的电话网是「中心交换」的,中心一炸,全网瘫痪。 所以军方要的不是「更结实的中心」,而是「根本没有中心」。 第二行看起来只是描述,其实是设计约束:它把「星型」这个最省线的方案直接排除掉了。 因为星型的中心就是那个「不能存在」的东西。 第三行催生了「路由」这个概念:既然没有中心告诉你怎么走,那每一段就得自己判断。 这就是「每个路由器自己维护路由表」的由来——它不是技术进步,是需求逼出来的。
二、两种拓扑,坏一个节点
把「打不烂」落到图上,就是连通性:
| 拓扑 | 链路数 | 全好时最大连通块 | 坏最坏那个之后 |
|---|---|---|---|
| 星型 4 端 1 中心 | 4 | 5 | 1 |
| 网状 5 点全连 | 10 | 5 | 4 |
星型坏掉中心,最大连通块从 5 掉到 1:四个端点互相彻底失联。 网状坏掉任一点,剩下 4 个点仍然全连。 这就是「打不烂」在数学上的样子:没有单点。 注意这里用的判据不是「有没有断线」,而是「最大连通块还有多大」—— 这才是衡量「抗摧毁」的正确指标。
三、代价与折中
网状不是免费的:
| 节点数 | 全连要几条链路 | 每点两条路的方案 |
|---|---|---|
| 5 | 10 | 5 |
| 10 | 45 | 10 |
| 100 | 4950 | 100 |
第二列按 n(n−1)/2 涨,是平方级:100 个节点全连要 4950 条链路, 没有哪个工程能承担这个成本。 所以真正的军用网络不会全连。 第三列那个「每点两条路」是实际做法:环形、网格、双归属,都只保证「任一点有两条以上出口」。 这样单点故障不会切断任何一对通信,而链路数只按点数线性增长。 这条「冗余要够、但不能过量」的思路,贯穿了后面所有网络设计: 数据中心的双上联、运营商的多线接入、DNS 的多台服务器,本质都是「每点两条路」。
四、动手 Demo:中心化网络与网状网络,坏一个节点会怎样
拿两种拓扑各试一次:随机坏掉一个节点,看剩下的还通不通。 判据是「最大连通块」的大小,不是「有没有断线」。
def comps(n, edges):
g = {i: set() for i in range(n)}
for a, b in edges:
g[a].add(b)
g[b].add(a)
seen, sizes = set(), []
for s in range(n):
if s in seen:
continue
q, c = [s], 0
seen.add(s)
while q:
v = q.pop()
c += 1
for w in g[v]:
if w not in seen:
seen.add(w)
q.append(w)
sizes.append(c)
return sorted(sizes, reverse=True)
star = [(0, i) for i in range(1, 5)]
mesh = [(a, b) for a in range(5) for b in range(a + 1, 5)]
for tag, edges in (('星型', star), ('网状', mesh)):
before = comps(5, edges)[0]
worst = min(comps(5, [e for e in edges if i not in e])[0]
for i in range(5))
print('%s 链路 %d 全好 %d 最坏 %d'
% (tag, len(edges), before, worst))
实跑输出:
--------------------------------------------------------------------
中心化网络与网状网络,坏一个节点会怎样
--------------------------------------------------------------------
**军用网络的第一条需求不是「快」,是「打不烂」。**下面拿两种拓扑各试一次:随机坏掉一个节点,
看剩下的还通不通。
拓扑 链路数 全好时最大连通块 坏最坏那个之后
--------------------------------------------------------------------
星型 4 端 1 中心 4 5 1
网状 5 点全连 10 5 4
**星型坏掉中心,最大连通块从 5 掉到 1**:**四个端点互相彻底失联。**
**网状坏掉任一点,剩下 4 个点仍然全连**——**这就是「打不烂」在数学上的样子:没有单点。**
**代价也很清楚**:**五个点的网状要 10 条链路,星型只要 4 条。**
**链路数按 n(n−1)/2 涨,所以真正的军用网络不会全连**,
而是「部分冗余」——**每个节点至少两条路,就够了。**
星型 4 条链路、网状 10 条,这是 n(n−1)/2 = 10 的直接结果。
「最坏」那一列是对每个节点各试一次坏的、取最小值:
星型最坏是 1(坏中心),网状最坏是 4(坏任一点)。
所以网状没有单点,星型有。
这段代码里 comps 用的是广度优先:从一个点出发能走到的所有点算一块,
把所有块的大小排个序,最大的那个就是「最大连通块」。
网络里把这个指标叫「连通度」,它是衡量冗余的标准工具。
30 秒实验
- 把星型换成「环型」(5 个点连成一圈,5 条链路),算它的最坏连通块。
- 给网状删掉一条边,看最坏连通块会不会变——这就是「冗余到底够不够」的判据。
- 想一下:你家宽带其实是「几点的什么拓扑」?断哪一根线会让你彻底断网?
常见误区
- 以为军用网络追求的是「快」。 当年追求的是「不断」,速率是后来才成为主要矛盾的。
- 以为「没有中心」等于「没有结构」。 互联网没有唯一中心,但有层级,骨干层就那几条, 断了影响很大。
- 以为冗余越多越好。 全连是平方级成本,实际做法是「每点两条路」,够用就行。
自测三问(点开对答案)
1. 军用需求为什么直接排除了星型拓扑? —— **因为星型的中心就是那个「不能存在」的节点**:中心一毁,全网瘫痪。所以要求「无中心」。 2. 衡量「抗摧毁」的正确指标是什么? —— **最大连通块的大小**,不是「有没有断线」。断一根线但所有点还能互通,就不算被摧毁。 3. 为什么实际网络不用「全连」,而用「每点两条路」? —— **全连的链路数是 n(n−1)/2,平方级,成本承受不了。**每点两条路已经是线性成本, 且能保证单点故障不断任何一对通信。下一节讲这套思路怎么落地:ARPANET 的诞生。
- ☐ (本节完,下一节 2.1.2 ARPANET的诞生)