# 第 15 章 体系结构与分层


> 本章是第四篇的地基：先讲"为什么分层、代价是什么"，再把一次 HTTP 请求的封装与解封装、MTU/MSS/分片、ARP、NAT、性能指标一次讲透。

## 学习目标

读完本章，你应当能够：

1. 推导一次 HTTP 请求从应用层到物理层的完整封装与解封装，并指出交换机、路由器、NAT 各自解封到哪一层；
2. 计算给定 MTU 下的 `MSS`，判断一次超长发送会走 TCP 分段还是 IP 分片，并解释片偏移为什么以 8 字节为单位；
3. 解释路径 MTU 发现（PMTUD）的黑洞问题与"DF 置位 + ICMP 被丢"的因果链，给出两种工程对策；
4. 从 ARP 缓存可被伪造出发，说明免费 ARP 与 ARP 欺骗的关系，并回答"有了 IP 为什么还要 MAC"；
5. 画出 NAPT 的端口映射表，判断四种 NAT 类型下打洞是否可行，说明 STUN/TURN/ICE 各自的职责；
6. 论证拥塞控制为什么必须端到端，并对照 ATM ABR 与 ECN 说明"标记而不决策"这一折中；
7. 用带宽时延积（BDP）解释长肥管道（LFN）为什么必须开窗口扩大因子，并做吞吐上界估算。

### 前置知识检查

| 你需要知道 | 在哪一节补齐 |
|---|---|
| 以太网帧结构、MAC 地址、交换机自学习（本科已学） | 本章 15.3、15.4 只讲"在哪一层解封、帧头帧尾装什么" |
| IPv4 首部字段（本科已学） | 本章 15.3.2、15.5.2 只讲 TTL、标识、标志、片偏移这四个必考字段 |
| TCP 首部字段与序号语义 | 见第 17 章 17.1 节；本章 15.5.1 只讲"分段为什么不属于分片" |
| TCP 滑动窗口与接收窗口 `rwnd` | 见第 17 章 17.3 节；本章 15.9.3 只引用它解释 BDP 与窗口的关系 |
| 拥塞窗口 `cwnd` 的演化（慢启动/拥塞避免） | 见第 17 章 17.5 节；本章 15.8 只讲"它为什么必须待在端点上" |
| HTTP 报文与连接管理 | 见第 18 章 18.1 节；本章 15.3 把它当成应用层载荷 |
| DNS 递归与迭代查询、CDN 回源 | 见第 19 章 19.1、19.3 节；本章只引用，不展开 |

## 15.1 分层的本质与代价

分层不是"把网络课本切成七块"的排版手段，而是**接口约定（interface contract）+ 关注点分离（separation of concerns）**。看"层与层之间交换什么"就能推出三个结论：每层只向上暴露服务原语（`connect`/`send`/`recv`）、只依赖下层提供的服务，而不暴露实现。

- **对等通信（peer-to-peer）是逻辑上的**：第 N 层只与对端第 N 层"对话"，它写的头部只有对端第 N 层会读，中间设备无需实现第 N 层也能转发。这正是"IP 能跑在任何链路层之上、TCP 能跑在任何网络层之上"的原因——Wi-Fi 换 5G，TCP 一行不改。
- **演进可以按层独立发生**：QUIC（RFC 9000）把可靠传输塞进 UDP 载荷、绕开中间设备对 TCP 的僵化假设，才得以在不改动网络的前提下部署（见第 18 章 18.4 节）。
- **接口在编译期固化**：`connect()` 的调用者不知道对端是光纤还是卫星。这既带来多厂商互通，也带来"上层无法把需求告诉下层"的副作用。

代价是面试真正想听的部分，要答出以下四条而不是笼统的"效率低"：

- **每层都要加头部**：不带选项的 IPv4 + TCP 至少 20 + 20 = 40 字节，加帧头 14 与帧尾 4，链路层共 58 字节。一个 40 字节的请求（GET 加少量首部）有效载荷占比不到一半；头部开销在"小而多"的报文上被放大，这正是 HPACK 与 TCP Fast Open 之类优化的动机。
- **跨层优化被挡住**：无线误码丢包（不是拥塞）会被 TCP 当拥塞信号盲目减窗；应用知道自己在传实时视频，却无法告诉 IP"这包丢了不用重传"。工程补救都是在层间**开受限旁路**：`TCP_NODELAY`、`SO_PRIORITY`、DSCP、`TCP_ULP`，或者像 QUIC 那样直接揉成一个用户态协议。
- **信息隐藏导致重复实现**：校验（以太网 FCS、IP 首部校验和、TCP 校验和）、重传（链路层 ARQ 与 TCP 重传）、分用（端口号与协议号）都在多层各做一遍。
- **中间设备越层窥探**：NAT 必须改传输层端口、防火墙看 HTTP 首部、运营商做 DPI。它们是分层的名义遵守者、实际破坏者，也是 QUIC 要把传输层首部加密的动机。

> [!IMPORTANT]
> 面试问"分层的好处与坏处"，得分点不在"降低复杂度"这种课本话，而在**对等层通信 + 接口约定使逐层替换与演进成为可能**，以及**头部开销、跨层优化受阻、中间设备越层**这三条代价，并且每条都能配一个真实例子（QUIC、NAT、无线误码）。

## 15.2 三种模型与 PDU 对照

OSI 七层是**参考模型**，TCP/IP 四层是**可运行的实现**，教学五层把"网络接口层"再拆成数据链路层与物理层，便于按 PDU 与设备讲解。面试常考三者映射、每层 PDU 名称、每层典型设备与协议。

| OSI 七层 | TCP/IP 四层 | 教学五层 | PDU 名称 | 典型设备 | 典型协议 |
|---|---|---|---|---|---|
| 应用层 / 表示层 / 会话层 | 应用层 | 应用层 | 报文（message） | 主机、代理、网关 | HTTP/1.1（RFC 7230）、HTTP/2（RFC 7540）、DNS（RFC 1034/1035）、TLS、SSH、QUIC |
| 传输层 | 传输层 | 传输层 | 段（segment，TCP）/ 数据报（datagram，UDP） | 主机（内核协议栈）、四层负载均衡 | TCP（RFC 793）、UDP、SCTP、QUIC |
| 网络层 | 网际层 | 网络层 | 分组（packet）/ IP 数据报 | 路由器、三层交换机、防火墙 | IPv4、IPv6、ICMP、ARP（跨 2/3 层，见 15.6）、OSPF/BGP |
| 数据链路层 | 网络接口层 | 数据链路层 | 帧（frame） | 交换机、网桥、网卡、AP、驱动 | 以太网（802.3）、Wi-Fi（802.11）、PPP、VLAN（802.1Q） |
| 物理层 | 网络接口层 | 物理层 | 比特（bit） | 中继器、集线器、光模块、线缆 | 1000BASE-T、10GBASE-SR、DSL、光纤规范 |

> [!TIP]
> 记 PDU 用一句话锚定：**"报文—段—包—帧—比特"**，每往下一层就"包一层信封"。追问"UDP 的 PDU 叫什么"答"数据报"，追问"IP 的 PDU 叫什么"也答"数据报"，但两者不同层——坑就在这里。

**为什么工程讲解用五层**：OSI 的表示层与会话层在实践中几乎没有独立实体，加密与编码（TLS、gzip、序列化）由库和应用完成、会话状态由应用自己维护，它们的职能被并入应用层，而 OSI 作为术语体系（"二层设备""三层转发""七层负载均衡"）被完整保留；TCP/IP 四层把链路与物理合成一层，粒度太粗，讲不清交换机与集线器的差异，也讲不清 MTU 是谁的约束。五层恰好与 PDU、设备、故障排查层次一一对应（第 19 章 19.5 的分层排查法就按这五层走）。

## 15.3 一次 HTTP 请求的完整旅程

### 15.3.1 分层封装（encapsulation）

以客户端 `192.168.1.10:49152` 访问 `203.0.113.5:443` 为例，省略选项，IPv4 与 TCP 首部各 20 字节，帧头 14、帧尾 4 字节。

```text
应用层     生成 HTTP/1.1 请求（应用数据 200 B）
传输层     + 源端口 49152 / 目的端口 443 / 序号 1001 / 标志 PSH,ACK
   TCP 段  ┌──────────────────────────────┐
           │ TCP 头 20 B  │ 应用数据 200 B │
           └──────────────┴────────────────┘
网络层     + 源 IP 192.168.1.10 / 目的 IP 203.0.113.5 / TTL 64 / 协议 6
IP 数据报  ┌─────────────┬──────────────┬────────────────────────────┐
           │ IP 头 20 B  │ TCP 头 20 B  │       应用数据 200 B       │  ≤ MTU 1500
           └─────────────┴──────────────┴────────────────────────────┘
链路层     + 目的 MAC = 默认网关的 MAC（跨网段时帧只为"下一跳"寻址）
 以太网帧  ┌──────────┬─────────────┬──────────────┬──────────────────┬──────┐
           │ 帧头 14B │ IP 头 20 B  │ TCP 头 20 B  │   应用数据 200B  │ FCS  │
           └──────────┴─────────────┴──────────────┴──────────────────┴──────┘
物理层     编码成电/光/无线信号发出；每个中继段重新生成信号
```

三个必被追问的细节：**目的 MAC 不是服务器的 MAC**（跨网段时是默认网关的，服务器 MAC 只出现在最后一跳，怎么知道网关 MAC 就引向 ARP，见 15.6）；**IP 地址沿途不变（NAT 场景除外），MAC 逐跳重写**，这就是"三层端到端、二层逐跳"，也是 traceroute 能工作的前提；**FCS 是链路层校验，每跳验证并重算**，端到端完整性由 TCP 校验和负责，两者层次不同。

### 15.3.2 各层头部里"真正管事"的字段

| 层 | 字段 | 作用 | 面试追问 |
|---|---|---|---|
| 传输层 | 源/目的端口 | 送到本机哪个进程（复用/分用） | "两个客户的源端口会冲突吗"——四元组唯一即可，端口只需在单机内唯一 |
| 传输层 | 序号 / 确认号 | 字节流定位、重传、按序交付 | "分段后会重新编号吗"——不会，分段沿用原序号（15.5.1） |
| 网络层 | 源/目的 IP | 端到端寻址与选路 | "NAT 之后 IP 还是端到端的吗"——不是（15.7） |
| 网络层 | TTL / Hop Limit | 防环；每经一个三层设备减一 | "traceroute 靠什么"——靠沿途回送的 ICMP 超时 |
| 网络层 | 标识 / 标志 / 片偏移 | IPv4 分片与重组（15.5.2） | "DF 置位后收不到通知为什么会黑洞"（15.5.3） |
| 网络层 | 协议号 | 交给 TCP(6) / UDP(17) / ICMP(1) | "ARP 的协议号是几"——ARP 不在 IP 里，见 15.6 |
| 链路层 | 源/目的 MAC | 同一广播域内逐跳投递 | "MAC 能跨路由器吗"——不能，逐跳重写 |
| 链路层 | 类型（EtherType） | 上交给 IPv4(0x0800)/IPv6(0x86DD)/ARP(0x0806) | 与"协议号"的区别：一个属链路层分用，一个属网络层分用 |

### 15.3.3 解封装（decapsulation）

服务端拿到的字节流与客户端发出的完全一致，但每一层做的是**剥离**：网卡检查 FCS 与目的 MAC，按 EtherType 上交网络层；网络层确认目的 IP 属于本机、TTL 减一（转发场景）、校验首部，按协议号上交传输层；传输层按四元组找到连接，按序号排序去重、累积确认，把数据放进该 socket 的接收缓冲区；应用层 `read()` 拿到字节流并解析请求行与首部。

> [!NOTE]
> 网卡有校验和卸载（checksum offload）、TSO/GRO、RSS 等"跨层"优化：TCP 校验和可能由硬件算，超大段在网卡里才被切分。面试官问"是不是每层都严格按软件顺序处理"，正确回答是**逻辑上分层、实现上被打通**；抓包看到远大于 `MSS = 1460` 的巨型 TCP 段，就是 TSO 的痕迹。

## 15.4 中间设备解封到哪一层

**二层交换机只解封到数据链路层**：读源/目的 MAC 查表转发，不看 IP 头（三层交换机除外），也不改 IP 与 TCP 首部。三个追问点：每个端口一个冲突域（全双工下已无冲突），但**所有端口同属一个广播域**，所以 ARP 广播会打到整个二层网络；MAC 地址表默认约 300 秒老化（以具体实现为准），过期即泛洪，表项被伪造就是 MAC 洪泛攻击；判断"两台机器是否同网段"看的是地址与掩码按位与的结果，不是看它们是否接在同一台交换机上。

**路由器解封到网络层**：检查目的 IP、查转发表选下一跳与出接口、TTL 减一、必要时分片（IPv4）或丢弃并回 ICMP（IPv6 不做中途分片），然后重写源/目的 MAC 重新封装转发。它**通常不动传输层**，端口号对路由器透明。

```text
主机 A --[以太网帧]--> 交换机 --> 路由器 R1 --[新帧]--> 路由器 R2 --> 服务器 B
  ↑ 应用/传输/网络三层在 A 生成        ↑ 只看 IP 层：改 TTL、改 MAC、可能分片
  ↑ 端到端：IP（除 NAT）与 TCP 首部不被中间路由器修改
```

所以"端到端"的准确含义是：**传输层与网络层的语义是端到端的，链路层是逐跳的**；IP 首部在正常情况下端到端不变，NAT 与隧道是例外。

| 设备 | 看/改到哪一层 | 为什么必须越层 | 典型后果 |
|---|---|---|---|
| 集线器 / 中继器 | 物理层 | 只是信号再生，属于同一冲突域 | 半双工下冲突域内共用带宽 |
| 交换机 / 网桥 / AP | 数据链路层 | 按 MAC 转发 | 一个广播域内 ARP 泛洪 |
| 路由器 / 三层交换机 | 网络层 | 按 IP 选路 | 只看 IP，对端口号透明 |
| NAT 网关 | 网络层 + 传输层 | 必须改端口才能让多台内网主机复用公网 IP（15.7） | 破坏端到端、需要打洞 |
| 防火墙 / DPI | 传输层 + 应用层 | 按端口与 HTTP 首部做策略 | 阻碍新协议部署 |
| 四层负载均衡 | 传输层 | 按端口/连接分发 | 后端看到的是 LB 的地址 |
| 七层负载均衡 / 反向代理 | 应用层 | 要看 URL、Host、Cookie 才能路由 | 需要重建连接（见第 18 章 18.2 节） |

> [!WARNING]
> 被问"路由器工作在哪一层"，答"网络层"之后**必须补一句"它也要先解封链路层帧头"**，否则说明你没分清"哪一层是它的决策依据"与"它必须处理哪些层"。任何三层设备都得先完成二层解封，否则拿不到 IP 数据报。

## 15.5 MTU、MSS 与分片：层次归属

第四篇最高频的深挖点之一。**一句话结论：分段（segmentation）在传输层，分片（fragmentation）在网络层；TCP 自己分段，绝不想让 IP 分片。**

### 15.5.1 MTU 与 MSS 的计算

`MTU`（maximum transmission unit）是**链路层载荷上限**，即"一个完整 IP 数据报能有多大"；`MSS`（maximum segment size）是 **TCP 放进单个 IP 数据报的载荷上限**，只算数据、不含任何头部。因此：

```text
MSS = MTU − IP 首部 − TCP 首部
以太网无选项 IPv4：  MSS = 1500 − 20 − 20 = 1460 字节
带 12 字节时间戳选项：MSS = 1500 − 20 − 32 = 1448 字节
IPv6 + IPsec 隧道：   MSS = 1280 − 60 − 20 = 1200 字节（IPv6 最小 MTU 1280）
PPPoE（MTU 1492）：   MSS = 1492 − 20 − 20 = 1452 字节
```

会算之后还要会说三件事：**MSS 是协商出来的**，双方在 SYN / SYN+ACK 里各带 `MSS` 选项声明"我最多能收多大"，发送方取两者与自身路径约束的最小值——它声明的是**接收能力**，这一点常被答反；**MSS 在连接建立时就固定**，中途路径 MTU 变小只能靠 PMTUD 或黑洞检测补救（15.5.3）；**MSS 与 `rwnd`/`cwnd` 量纲不同**，后两者是字节数（窗口），MSS 是一次封装的粒度，慢启动里"每 RTT 翻倍"正是按 MSS 增长的（见第 17 章 17.5 节）。

### 15.5.2 IPv4 分片的三个字段与后果

当 IP 数据报大于出接口 MTU 且 `DF = 0` 时，路由器把它切开，每片都是独立 IP 数据报、**各带一份复制的 IP 与传输层首部**，却**没有传输层重传语义**：

| 字段 | 宽度 | 语义 | 易错点 |
|---|---|---|---|
| 标识（Identification） | 16 bit | 同一原始数据报的所有片共用同一值，供目的端归组 | 它按数据报递增，与 TCP 序号无关；NAT 与部分实现会重写 |
| 标志（Flags） | 3 bit | `DF`（Don't Fragment，置 1 禁止分片）、`MF`（More Fragments，置 1 表示后面还有片） | 最后一片 `MF = 0` 是重组结束判据；`DF` 与 `MF` 语义不同，常被混答 |
| 片偏移（Fragment Offset） | 13 bit | 本片载荷在原始载荷中的位置，**单位是 8 字节** | 故除最后一片外载荷长度必须是 8 的倍数，这也限制了分片粒度 |

```text
原始 IP 数据报载荷 3000 B（IP 首部 20 B），出接口 MTU 1500
可分片载荷上限 = 1500 − 20 = 1480 B，且须为 8 的倍数（1480 / 8 = 185）
片 1: 标识=0x4A21, MF=1, 偏移=0   (字节 0    ~ 1479)  总长 1500
片 2: 标识=0x4A21, MF=1, 偏移=185 (字节 1480 ~ 2959)  总长 1500
  片 3: 标识=0x4A21, MF=0, 偏移=370 (字节 2960 ~ 2999)  总长 60
  若片 2 丢失：目的端凑不齐 0..2999 的连续载荷，把已到的片全部丢弃
```

这就是"丢一片导致整个报文重传"的完整因果。三条放大效应必须能说出来：**开销放大**（每片复制 IP/TCP 首部）、**丢失放大**（丢片概率按片数累积，尾部尤其脆弱）、**重组代价**（目的端要维护重组缓冲与超时定时器，还有分片重叠的攻击面）。

> [!CAUTION]
> "IP 分片了，TCP 能按序号只重传丢的那一片吗？"——**不能**。TCP 只知道"这个报文段没被确认"，它既不知道是哪一片丢了，也无法只重传某一片。把"IP 分片"与"TCP 分段"混为一谈，是这道题最典型的崩盘点。

### 15.5.3 路径 MTU 发现与黑洞

现代协议栈默认走 **PMTUD**（path MTU discovery）：发送方把 `DF` 置 1 并发送自己认为合适的大小。若某跳 MTU 更小，该跳丢弃数据报并回送 ICMP Type 3 Code 4（"需要分片但 DF 已置位"），其中携带该跳 MTU；发送方据此把路径 MTU 估计降下来，按新尺寸重新分段，并按目标地址缓存一段时间。

**黑洞（PMTU black hole）**由此产生：大量防火墙与中间设备出于策略丢弃全部 ICMP，发送方收不到通知，于是**大包静默消失、小包畅通**——典型症状是"能 ping 通、能建连、一传大文件就卡死"。两类对策：**黑洞检测**，主机观察到"大数据段反复重传而连接无进展"时主动把 `MSS` 降低重试，治的是"ICMP 被丢"，代价是性能骤降；**收紧本端 MSS**，在隧道/VPN/负载均衡上按最小可能 MTU 手工钳制（如 `--clamp-mss-to-pmtu`），把风险提前消掉。

### 15.5.4 为什么 TCP 宁愿自己分段

| 维度 | TCP 分段（segmentation） | IP 分片（fragmentation） |
|---|---|---|
| 所属层 | 传输层 | 网络层 |
| 谁做 | 发送方主机按 MSS 切分 | 任意中间路由器按出接口 MTU 切分 |
| 序号 | 每段沿用原字节序号，正常可靠传输 | 片序号与 TCP 无关，TCP 不可见 |
| 重传粒度 | 按报文段重传，可配合 SACK 只补缺口 | 任一片丢失则整个数据报作废，无片级重传 |
| 首部开销 | 每段一份 TCP 头（本来就需要） | 每片复制一份 IP 与传输层头，纯浪费 |
| 中间设备 | 路由器不参与，路径变更无影响 | 依赖 MTU，NAT/隧道设备常处理不好 |
| 安全性 | 无额外攻击面 | 分片重叠可绕过检测（分片攻击） |

理论依据是**端到端原则（end-to-end argument）**：把功能放进网络中间会带来状态与一致性成本，放在端点则简单且可演进；网络层只负责**尽力而为的转发**，复杂功能交给端点。这与 15.8 节"拥塞控制必须端到端"是同一条原则。

> [!IMPORTANT]
> 面试三步答法：**① 先分清层次**——分段在传输层、分片在网络层；**② 再给计算**——`MSS = MTU − 20 − 20 = 1460`，分片粒度受片偏移 8 字节约束；**③ 最后给判据**——分片带来首部开销、丢失放大与重组代价，所以 TCP 主动按 MSS 分段并置 `DF`，用 PMTUD 探测路径 MTU、用黑洞检测兜底。

## 15.6 ARP：IP 与 MAC 之间的桥

ARP（address resolution protocol）**不属于 IP**：它没有 IP 首部，直接封装在以太网帧里（EtherType `0x0806`），在五层模型里算网络层的辅助协议、实现上跨越二三层。**有了 IP 为什么还要 MAC**：IP 是逻辑的、可聚合的、端到端的编址，用于选路；MAC 是物理的、扁平的、逐跳的标识，用于在同一广播域内把帧交给下一跳的网卡。路由器无法用 IP "点对点"投递——它必须知道下一跳的硬件地址才能把帧送出去。

```text
请求（广播）：目的 MAC = ff:ff:ff:ff:ff:ff，EtherType = 0x0806
  "谁是 192.168.1.1？请告诉 192.168.1.10（aa:..:10）"
应答（单播）：目的 MAC = aa:..:10
  "192.168.1.1 的 MAC 是 bb:..:01"
```

- **请求必须广播、应答必须单播**：没有初始缓存就无法寻址，所以请求只能广播；应答的目的地址已由请求报文获知，所以单播——这也让欺骗者能只毒化特定目标。
- **ARP 缓存与老化**：Linux 邻居表条目默认有可达/过期状态（`base_reachable_time` 约 30 秒量级、`gc_stale_time`、`gc_thresh1/2/3`），用 `ip neigh show` 观察。缓存是你"记住"的映射，**没有验证机制**——收到任何 ARP 应答（哪怕没发过请求）都会更新缓存，这就是欺骗的入口。
- **免费 ARP（gratuitous ARP）**：主机主动广播"我的 IP 对应这个 MAC"，用于检测 IP 地址冲突（收到别人的应答说明地址被占用）、通知同网段刷新缓存（高可用切换时让流量快速改道）、配合 MAC 漂移做灾备。它本质是"无需请求的应答"，也正好是 **ARP 欺骗的最小工具**。
- **ARP 欺骗**：攻击者持续广播伪造映射，使同网段主机把网关 IP 误映射到攻击者 MAC，从而中间人（MITM）。防线是 **DHCP Snooping + 动态 ARP 检测（DAI）**、端口安全、静态绑定；**跨网段时 ARP 天然被路由器隔离**。

> [!NOTE]
> 面试官爱追问的下一层："ARP 请求能跨路由器吗？"——不能，ARP 只在同一广播域内工作，访问其他网段时解析的是**默认网关的 MAC**（这正是 15.3.1 里"目的 MAC 是网关"的原因）。IPv6 用邻居发现（NDP，基于 ICMPv6）取代 ARP，语义等价但可被 Secure Neighbor Discovery 保护。

## 15.7 NAT：从地址复用到打洞

### 15.7.1 NAPT 的工作原理

**NAPT**（network address and port translation，即常说的 NAT/PAT）在转发时改写源地址与源端口，并维护一张映射表：

```text
内网                                  NAT 出口                   外网
192.168.1.10:49152 ──┐
192.168.1.11:49153 ──┼──> 203.0.113.7:60001 / 60002 / 60003 ──> 服务器
192.168.1.10:49154 ──┘
映射表（出方向建表，回方向查表）：
  192.168.1.10:49152 <- 60001 -> 198.51.100.9:443    TCP  剩余 320 s
  192.168.1.11:49153 <- 60002 -> 198.51.100.9:443    TCP  剩余 118 s
  192.168.1.10:49154 <- 60003 -> 203.0.113.200:1234  TCP  剩余 8 s
```

关键机制：**区分映射靠（内网 IP, 内网端口, 目标 IP, 目标端口, 协议）五元组**，所以同一内网端口到不同目标可以映射成不同外网端口；**回程包必须命中已有表项才能进入**，"没有表项就丢弃"正是内部主机不可被外部主动连接的根本原因；TCP 表项超时通常几分钟到数小时（受 `tcp_established`/`tcp_time_wait` 等参数影响），UDP 更短（常见数十秒到几分钟），长连接因此要靠**应用层保活**给映射续命。

### 15.7.2 NAT 的代价

- **破坏端到端**：外部无法主动连入；IP 不再是稳定的端到端标识（"我的 IP"要从外部视角才知道）。网关被迫越层修改传输层端口、重算校验和，对 TCP/UDP 之外的协议只能靠 ALG 甚至放弃。
- **状态与可靠性**：NAT 成为有状态单点，重启即清空所有映射；表项容量是硬上限，也是常见故障源。
- **协议破坏**：FTP 主动模式、SIP/H.323 把 IP:port 写在应用载荷里，NAT 改不了，必须 ALG 打补丁——这就是这类老协议今天不好用的原因。

### 15.7.3 四种 NAT 类型与打洞可行性

按 RFC 4787 的术语分类（面试常按锥型/对称型这一套说法）：

| 类型 | 出方向映射规则 | 入方向过滤规则 | 打洞可行性 |
|---|---|---|---|
| 完全锥型（full cone） | 同一内网端点固定映射到同一外网端口，与目标无关 | 任何外部主机都可发包到该映射端口 | 最简单：交换公网映射即可互连 |
| 地址受限锥型（address-restricted cone） | 同上，只与内网端点有关 | 只放行"本机曾发过包的目的 IP"（端口不限） | 可行：先向对方公网 IP 发一包开门 |
| 端口受限锥型（port-restricted cone） | 同上 | 只放行"本机曾发过包的目的 IP + 目的端口" | 可行但需精确预测对方端口：双方同时向对方映射端口发包 |
| 对称型（symmetric） | 每个新的（目标 IP, 目标端口）都分配**不同的外网端口** | 同上严格过滤 | 不可行：对方无法预知你的外网端口，预测成功率低 |

打洞成功时，A 先向 `198.51.100.9:60002` 发包（NAT-A 记录"允许该目的"，包在 NAT-B 被丢），B 再向 `203.0.113.7:60001` 发包（NAT-B 记录"允许该目的"，包穿过已放行的 NAT-A 到达 A），此后双向都命中过滤规则；关键在于双方已通过信令知道对方映射。打洞失败时若 A 是对称型，它向 B 发包时外网端口变成 `60003`，而 B 只知道 `60001`，双方永远无法命中，只能回落 **TURN** 中继。

### 15.7.4 为什么 P2P 与 WebRTC 需要 STUN/TURN/ICE

| 组件 | 解决的问题 | 代价 |
|---|---|---|
| STUN | 让主机从**外部视角**发现自己的公网映射（"我看起来是 203.0.113.7:60001"），并辅助识别 NAT 类型 | 只解决"知道自己是谁"；对称型下映射对每个目标都不同，价值有限 |
| TURN | 双方都打不通时，用中继服务器转发全部流量 | 带宽与延迟成本落在中继上，是保底而非首选 |
| ICE | 收集候选（本地、STUN 反射、TURN 中继），按优先级成对做连通性检查，选出可用路径 | 需要信令通道交换候选（通常复用已有连接） |

因此完整链路是"**先试直连（STUN + 打洞），失败回落中继（TURN），全过程由 ICE 编排**"，这也解释了为什么对称型 NAT 占比高的企业网络里，P2P 应用的服务器带宽成本会明显上升。

> [!TIP]
> 面试话术锚点：**"NAT 不是协议，而是一种有状态的地址改写；它带来的是可达性反转——出站自由、入站受限。所有穿透方案（打洞/STUN/TURN/ICE）本质都在绕开'入站受限'这一条。"**

## 15.8 拥塞控制为什么必须端到端

### 15.8.1 路由器做不到的三件事

把拥塞控制下沉到路由器（在网络层做速率决策）在 IP 世界行不通，原因不是"没实现"，而是三条结构性障碍：

- **路由器看不到"流"的完整状态**。它只有单包视图：这个包属于哪条连接、这条连接是刚起步还是已跑了 10 GB、可用带宽多少，路由器都不知道。要判断"该给这条流降多少速"，就得为每条流维护队列与速率状态，在超额订阅的核心网上意味着状态爆炸（同时数百万条流），加密后更不可识别。
- **路由器无法通知发送方**。ICMP 源抑制（source quench）已被废弃，原因正是"通知"在分布式系统里不可靠：ICMP 会被限速或丢弃，发送方拿到过期信息反而误伤；多播式拥塞通知还会引起同步震荡。
- **公平与稳定无法在中间层收敛**。路由器没有"应用价值"信息来裁决谁该让路；而端点各自按丢包/时延反馈调整速率，构成一个无需中心裁决者就能收敛的分布式控制系统——这是 Jacobson 拥塞控制的根本贡献（见第 17 章 17.5 节）。

### 15.8.2 ATM ABR 与 ECN 的两个折中

| 方案 | 位置 | 路由器做什么 | 端点做什么 | 结局 |
|---|---|---|---|---|
| ATM ABR（available bit rate） | 网络层（ATM 层） | 逐跳参与：读写 RM（resource management）信元的 ER（explicit rate）字段，`EFCI` 位置 1 标记轻度拥塞并向源端回送反馈 | 按回送速率调整发送 | 单一厂商管理的封闭域里逐流状态可行，但成本高、难以扩展到开放互联网，随 ATM 退出 |
| ECN（RFC 3168） | IP + TCP | **只标记不决策**：队列超阈值时把 IP 首部的 `CE` 置 1，不维护流状态、不决定速率 | 接收方用 TCP 的 `ECE` 回显，发送方像丢包一样减窗并用 `CWR` 确认 | 保持端到端与无状态，可配 AQM（RED/CoDel）；但要求两端与所有中间设备支持，任何一跳忽略该位就退化为普通丢包 |
| 丢包作为信号 | — | 什么也不做（队列满就丢） | 从超时/重复 ACK 推断拥塞并减窗（RFC 5681） | 部署零成本、普适，但把非拥塞丢包（无线误码）也当拥塞，且必须填满队列才开始反应 |

**ECN 是这套折中的精髓**：路由器的信息优势（它知道队列有多长）被利用，但决策权仍在端点（只有端点知道流的历史与可用窗口）。路由器做的是**观察与标记**，不是**判断与指挥**——与端到端原则完全一致：只有端点才知道的事留在端点，只有网络才知道的事以最小信息量（1 bit）反馈回去。数据中心里的 DCTCP 正是把这 1 bit 用到极致以压低排队时延。

> [!WARNING]
> 错误回答："拥塞控制放路由器上更好，因为路由器最了解网络状况。"面试官会立刻反问"路由器怎么区分一条流是刚建立还是已经跑了很久？怎么把决策通知给发送方？"——答不出"路由器只有单包视图、没有逐流状态"和"ICMP 源抑制为什么被废弃"，这道题就崩了。

## 15.9 性能指标：带宽、时延与 BDP

### 15.9.1 四种时延与算例

`总时延 = 处理时延 + 排队时延 + 发送时延 + 传播时延`，其中前两项常被忽略，后两项是考点主体：

- **发送时延 = 报文长度 / 链路带宽**。1 KB 报文在 1 Gbps 上约 `8192 / 10⁹ ≈ 8.2 μs`，在 100 Mbps 上约 82 μs。它只与带宽和长度有关，与距离无关。
- **传播时延 = 距离 / 传播速度**。光纤中约 `2 × 10⁸ m/s`（约真空光速的 2/3），同城 100 km 约 0.5 ms，跨大洲 15000 km 约 75 ms（单向）。它与带宽完全无关——"加带宽降不了 ping"就是这条。
- **处理时延**：查表转发，量级微秒。
- **排队时延**：链路空闲时接近 0；设链路利用率 `ρ`，按 M/M/1 近似，平均排队时延 `Tq = (ρ/(1 − ρ)) × Ts`（`Ts` 为发送时延）。`ρ = 0.5` 时 `Tq = Ts`，`ρ = 0.9` 时 `Tq = 9 Ts`，`ρ = 0.99` 时 `Tq = 99 Ts`——**利用率逼近 1 时排队时延非线性爆炸**，这就是"容量规划留余量"和"尾延迟先炸"的定量依据。
```text
算例：10 Gbps 链路上 1 KB 报文，ρ = 0.9
  Ts = 8192 / 10¹⁰ = 0.82 μs
  Tq ≈ (0.9 / 0.1) × 0.82 ≈ 7.4 μs   -> 排队占总时延约 90%
  ρ 再升到 0.99，Tq 立刻变成 ≈ 81 μs
  ⟹ 只看平均时延会漏掉长尾；同一 ρ 下到达间隔的抖动会被放大成 P99 时延
```

### 15.9.2 RTT 与它的构成

`RTT`（round-trip time）是一个比特往返一次的墙钟时间，包含**两个方向的传播时延 + 沿途每跳的发送/处理/排队时延 + 端点协议处理**。两个必答点：**RTT 不是常量**（排队时延随负载波动，所以 RTO 必须平滑估计，见第 17 章 17.2 节）；**RTT 与 MTU/MSS 无关**，但与 BDP 一起决定吞吐上限。

### 15.9.3 带宽时延积（BDP）

`BDP = 带宽 × RTT`，单位是比特（常换算成字节），物理含义是**链路上同时"在途"的比特数**，即这条"管道"的容量。同城 `1 Gbps × 10 ms = 10 Mbit = 1.25 MB` 在途；跨大洲 `100 Mbps × 150 ms = 15 Mbit = 1.875 MB` 在途。要把链路跑满，未确认数据量必须 ≥ BDP，因为 `吞吐 ≈ 窗口 / RTT ⟹ 窗口 ≥ 吞吐 × RTT = BDP`；而 TCP 窗口字段只有 16 bit，未开扩大因子时窗口 ≤ 65535 B，于是 `吞吐上界 = 65535 B / 0.15 s ≈ 3.5 Mbps`——与 1 Gbps 的链路相差近 300 倍，这就是 LFN 必须开 window scaling 的原因（完整算例见自测题 Q5）。

**长肥管道（long fat network, LFN）**指"带宽高 + RTT 大"的网络：BDP 大，于是对窗口、拥塞控制收敛速度、丢包恢复时间都提出更高要求（一次丢包后恢复到满窗口所需时间与 RTT 成正比）。工程三件套是**窗口扩大因子（RFC 7323 的 window scaling，最大 2¹⁴ 倍）、选择性确认 SACK、更大的初始窗口**。

### 15.9.4 吞吐、利用率与它们的关系

- **吞吐（throughput）**是单位时间实际传输的有效数据量，受三者共同钳制：`吞吐 ≈ min(瓶颈带宽, 窗口 / RTT, 应用层供给速率)`。第三项常被忽略——服务端 CPU 打满、上游慢、TLS 握手频繁时，链路再宽也用不上。
- **利用率 = 吞吐 / 瓶颈链路带宽**，只对**瓶颈链路**有意义。多跳路径各段带宽不同，算单段利用率会得出"链路很闲但用户很慢"的错误结论。
- **利用率与时延是矛盾的**：由 15.9.1 的公式可见，提高利用率必然抬高排队时延。所以吞吐型业务追求高 `ρ`，延迟敏感业务宁可留余量——这也是缓冲区膨胀（bufferbloat）下 AQM 存在的意义。

> [!IMPORTANT]
> 三个必记结论：**① 传播时延与带宽无关，加带宽降不了 RTT；② `BDP = 带宽 × RTT` 是窗口的下界，窗口不足则吞吐被卡在 `窗口 / RTT`；③ 排队时延在 `ρ → 1` 时按 `ρ/(1 − ρ)` 发散，因此高利用率必然带来长尾。**

## 本章小结

| 关键结论 | 一句话表述 | 常见错误 |
|---|---|---|
| 分层的本质 | 接口约定 + 关注点分离，使对等层可独立替换与演进 | 只说"降低复杂度"，答不出跨层优化受阻与中间设备越层 |
| 模型对应 | OSI 七层是参考模型，工程用五层，表示层与会话层并入应用层 | 说"OSI 有七层所以工程上也分七层"、说四层"少了物理层" |
| 封装与解封装 | 每层加自己的头；目的 MAC 只指向下一跳，IP 端到端不变（NAT 除外） | 说"目的 MAC 是服务器的 MAC"、说"路由器会看端口号" |
| MTU 与 MSS | `MSS = MTU − IP 头 − TCP 头`，以太网 IPv4 为 1460 | 把 MSS 算成 1500，或忘了 MSS 是接收方声明、忘了扣选项 |
| 分段 vs 分片 | 分段在传输层（可靠），分片在网络层（丢一片全重传） | 说"IP 分片丢了 TCP 能按序号只补那一片" |
| 片偏移单位 | 8 字节，故除最后一片外载荷长度为 8 的倍数 | 以为偏移以字节计、把 `MF` 与 `DF` 当成一回事 |
| PMTUD 黑洞 | `DF = 1` 且"需要分片"的 ICMP 被丢弃 ⇒ 大包静默消失 | 只说"改回 `DF = 0` 就没事"，答不出黑洞检测与 MSS 钳制 |
| ARP | 请求广播、应答单播；缓存无验证故可被欺骗 | 说"ARP 请求能跨路由器"、说"应答也是广播" |
| NAT | 有状态的地址端口改写，出站建表、入站需命中 | 说"NAT 是协议"、说"外网能主动连内网只是没配置" |
| 打洞可行性 | 锥型可行，对称型不可行，需 TURN 中继 | 说"有 STUN 就能连上"、把 STUN 与 TURN 职责说反 |
| 拥塞控制位置 | 必须端到端：路由器只有单包视图、无法可靠通知发送方 | 说"放路由器上更好，它最了解网络状况" |
| BDP | `BDP = 带宽 × RTT` 是窗口下界，窗口不足则吞吐被卡住 | 把 BDP 当成"带宽的另一种叫法"，或用单向时延去算 |

## 自测题

**Q1**（计算与推导）链路 MTU 1500 字节，TCP 首部含 12 字节时间戳选项，IPv4 无选项。① 求 MSS；② 应用一次写入 4000 字节，会走分段还是分片，切成几段、各段载荷多大；③ 若某中间路由器出接口 MTU 为 1400 且发送方把 `DF` 置 1，会发生什么？

<details><summary>答案与解析</summary>

① `MSS = 1500 − 20（IP 头）− 20（TCP 基本头）− 12（时间戳选项）= 1448` 字节。

② 走 **TCP 分段**。每段 `1448 + 20 + 32 = 1500`，正好等于 MTU，不需要分片；切 3 段，载荷 1448 + 1448 + 1104 = 4000。

③ 该路由器发现"需要分片但 `DF = 1`"，**丢弃**并回送 ICMP Type 3 Code 4（携带该跳 MTU 1400）；发送方把路径 MTU 降到 1400，此后按 `MSS = 1400 − 20 − 32 = 1348` 发送。

**错在哪**：把 MSS 答成 1460 是漏掉时间戳选项——MSS 是 TCP 载荷，任何 TCP 选项都从 1500 的预算里扣。答"IP 自己分片"是没分清层次：有 TCP 时主机永远先按 MSS 分段，IP 分片只发生在"数据报本身超过 MTU 又无法用分段解决"时（如 UDP 大载荷）。

**面试官会追问**：MSS 是发送方决定还是接收方声明？（接收方在 SYN 中声明接收能力，实际发送取双方与路径约束的最小值。）为什么加时间戳选项 MSS 就变小？（选项与数据共用 1500 这份预算。）

</details>

**Q2**（推导）3000 字节载荷的 IP 数据报经过 MTU 1500 的链路，`DF = 0`。写出各片的标识、`MF`、片偏移与总长度，并说明若中间丢失一片会发生什么。

<details><summary>答案与解析</summary>

每片载荷上限 `1500 − 20 = 1480`，且必须是 8 的倍数；片偏移以 8 字节为单位：
```text
片 1: MF=1, 偏移=0,   载荷 1480 B, 总长 1500
片 2: MF=1, 偏移=185, 载荷 1480 B, 总长 1500   （1480 / 8 = 185）
片 3: MF=0, 偏移=370, 载荷 40 B,   总长 60     （2960 / 8 = 370）
```

三片标识相同（从原始数据报的标识字段复制）。丢失任一片：目的端凑不出连续载荷，**把已到的片全部丢弃**，IPv4 下可能回 ICMP 超时；IP 层没有重传，只能由 **TCP 重传整个报文段**，重传的段同样超长、再次被分片——丢片概率按片数放大，这就是"丢一片全重传"。

**错在哪**：把偏移写成 1480、2960（漏了除以 8）；写"最后一片 `MF = 1`"；或答"重传丢失的那一片"。

**面试官会追问**：为什么偏移单位是 8 字节？（13 bit 要覆盖 65535 字节的最大数据报，只能以 8 字节为粒度。）IPv6 为什么取消路由器分片？（让分片只发生在源端、以 PMTUD 为前提，去掉中间设备的重组状态与攻击面。）

</details>

**Q3**（判断与辨析）"路由器最了解网络拥塞状况，应该由路由器决定每条 TCP 流的发送速率，这比让端点自己猜更准确。"判断对错，给出三条反驳理由，并说明 ECN 如何折中。

<details><summary>答案与解析</summary>

错。三条理由：**① 路由器只有单包视图**，不知道包属于哪条流、流的历史与窗口；要决策就得为每条流维护状态，核心网上意味着数百万条流的状态爆炸。**② 无法可靠通知发送方**，"通知"依赖 ICMP 之类控制报文，会被限速或丢弃；ICMP 源抑制正因无效而被废弃，过期通知还会误伤。**③ 公平与稳定性**：路由器没有应用价值信息来裁决"谁该让路"，而端点各自按丢包/时延反馈调整，构成能在无中心裁决者下收敛的分布式控制系统。

ECN（RFC 3168）的折中是**路由器只标记不决策**：队列超阈值时把 IP 首部的 `CE` 置 1，不维护流状态；接收方用 TCP 的 `ECE` 回显，发送方像丢包一样减窗并用 `CWR` 确认。路由器的信息优势（队列长度）以 1 bit 反馈出去，决策权仍留在端点。

**错在哪**：只答"端到端原则"却说不出机制；或把 ECN 说成"路由器告诉发送方该发多少"（那是 ATM ABR 的思路）。

**面试官会追问**：ECN 为什么不是万能的？（要求两端与路径上所有设备都支持，任何一跳忽略该位就退化成丢包信号。）ATM ABR 为什么消失？（逐跳信令与逐流状态在开放互联网上可扩展性差，且依赖单一管理域。）

</details>

**Q4**（设计与分析）A 与 B 的 NAT 都是端口受限锥型，A 的公网映射是 `203.0.113.7:60001`，B 是 `198.51.100.9:60002`。① 说明打洞为什么能成功，写出关键两步；② 若 A 侧换成对称型会怎样，需要引入什么组件；③ STUN 与 TURN 的职责分别是什么？

<details><summary>答案与解析</summary>

① 端口受限锥型的过滤规则是"只放行本机曾向其发过包的 目的 IP + 目的端口"。**第一步** A 主动向 `198.51.100.9:60002` 发包，NAT-A 记下"允许该目的"，此包在 NAT-B 被丢（B 尚未发过）；**第二步** B 主动向 `203.0.113.7:60001` 发包，NAT-B 记下"允许该目的"，此包能穿过已放行的 NAT-A 到达 A。此后双向都命中规则，直连建立——前提是双方已通过信令知道对方映射，且映射在出站期间不变。

② 对称型对**每个新目标**分配不同外网端口，A 向 B 发包时端口可能变成 `60003`，而 B 只知道 `60001`，打向 `60001` 的包被丢弃，**打洞失败**。此时需要 **TURN** 中继：双方都与中继建连，由中继转发全部流量。

③ **STUN** 解决"我是谁"——从外部服务器视角发现自己的公网映射地址与端口，并辅助识别 NAT 类型；**TURN** 解决"打不通时怎么办"——在服务器上分配中继地址转发流量（成本与延迟更高）；**ICE** 收集候选、按优先级做连通性检查并选出可用路径。完整链路是"STUN 探测 + 打洞直连 → 失败回落 TURN，由 ICE 编排"。

**错在哪**：把 STUN 当成"转发服务器"（那是 TURN）；或答"对称型也能打洞，多试几个端口就行"（端口预测成功率低，工程上不作为可靠方案）。

**面试官会追问**：为什么长连接要靠保活？（NAT 表项有超时，长时间无流量会过期，之后对端发来的包无法命中表项。）UDP 与 TCP 的表项超时差异？（UDP 通常更短。）

</details>

**Q5**（计算）客户端在跨大洲链路上传输，瓶颈带宽 200 Mbps，单向传播时延 75 ms，未启用窗口扩大因子（窗口上限 65535 字节）。① 求 RTT 与 BDP（用字节表示）；② 求理论上能达到的最大吞吐；③ 若链路升级到 1 Gbps，吞吐会变好吗，为什么；④ 要让 1 Gbps 跑满，窗口至少要多大？

<details><summary>答案与解析</summary>

① `RTT ≈ 75 × 2 = 150 ms`（忽略发送与处理时延）；`BDP = 200 Mbps × 0.15 s = 30 Mbit = 3.75 MB`。

② `吞吐 ≈ 窗口 / RTT = 65535 B / 0.15 s ≈ 437 KB/s ≈ 3.5 Mbps`，只有瓶颈带宽（200 Mbps）的约 1.75%——瓶颈是窗口，不是链路。

③ **不会变好**。吞吐上界是 `窗口 / RTT`，与链路带宽无关；窗口仍是 65535 字节时吞吐仍是约 3.5 Mbps。

④ `窗口 ≥ 带宽 × RTT = 1 Gbps × 0.15 s = 150 Mbit = 18.75 MB`（约 128 万个 1460 字节段在途）。因此必须启用窗口扩大因子（RFC 7323，最大放大 2¹⁴ 倍，配合 16 bit 窗口字段可表示到约 1 GB），并配套 SACK 与大初始窗口。

**错在哪**：把"带宽大"等同于"吞吐大"，忽略窗口与 RTT 的乘积约束；或把 BDP 算成 `带宽 × 单向时延`（BDP 要用 RTT，因为要覆盖"发出去 + 确认回来"的整个在途量）。

**面试官会追问**：BDP 与带宽是一回事吗？（不是，BDP 是链路在途比特容量，单位是比特/字节。）窗口扩大因子在哪协商？（TCP 的 SYN 选项，须两端都支持，中途设备不参与。）还有什么限制 LFN 的吞吐？（丢包恢复时间与 RTT 成正比、慢启动要多个 RTT 才升到目标窗口、应用层供给速率、以及缓冲区膨胀带来的排队时延。）

</details>

## 面试高频问题与陷阱

| 面试问法 | 考查角度 | 陷阱 / 加分点 | 对应本章小节 |
|---|---|---|---|
| 分层到底解决了什么问题，又带来了哪些坏处？ | 是否理解分层的本质是接口约定与关注点分离 | 错误回答：只说"降低复杂度、便于维护"，说不出头部开销（IPv4 + TCP 至少 40 字节）、跨层优化受阻、中间设备越层窥探；加分点是用 QUIC 绕开 TCP 僵化假设来举例 | 15.1 |
| OSI 七层和 TCP/IP 四层怎么对应，工程里为什么讲五层？ | 模型映射与"哪些层没有独立实体" | 错误回答：把表示层/会话层当成有独立协议实体的层，或说四层"少了物理层"；正确说法是这两层职能并入应用层，而 OSI 术语体系仍被保留 | 15.2 |
| 浏览器发起一次请求，从应用层到网线上到底发生了什么？ | 封装链条是否真的走通了 | 错误回答：说"目的 IP 和目的 MAC 都是服务器的"、说"路由器会看端口号"；关键是目的 MAC 只指向下一跳、IP（除 NAT）端到端不变、MAC 逐跳重写 | 15.3 |
| 交换机和路由器各解封到哪一层？ | 设备与层次的对应、越层设备的存在 | 错误回答：说路由器"只处理 IP 层、不解链路层"；加分点是主动提到 NAT 与七层负载均衡必须越层，并说清为什么 | 15.4 |
| MSS 是多少，怎么算出来的？ | 计算能力与"谁声明 MSS" | 错误回答：直接答 1500，或漏掉 TCP 选项；正确是 `MSS = MTU − 20 − 20 = 1460`，带 12 字节时间戳选项则为 1448，且由接收方在 SYN 中声明、发送方取最小值 | 15.5.1 |
| IP 分片和 TCP 分段有什么区别，为什么 TCP 不愿意被分片？ | 层次归属与后果推理 | 错误回答：把两者混为一谈，或说"分片丢了 TCP 可以只重传那一片"；加分点：片偏移单位 8 字节、丢一片则整报重传、分片重叠的攻击面 | 15.5.2、15.5.4 |
| 大文件上传到一半就卡住，小请求却正常，可能是什么原因？ | PMTUD 黑洞的诊断推理 | 错误回答：说"带宽不够"或"重传机制坏了"；正确答案是 `DF = 1` 而"需要分片"的 ICMP 被防火墙丢弃，大包静默丢失，对策是黑洞检测与 MSS 钳制 | 15.5.3 |
| 有了 IP 地址为什么还需要 MAC，ARP 是怎么工作的？ | 逻辑编址与物理编址的分工 | 错误回答：说"MAC 是永久的所以更可靠"；关键是 IP 用于端到端选路、MAC 用于同一广播域内逐跳投递，ARP 请求广播、应答单播，缓存无验证故可被欺骗 | 15.6 |
| NAT 是怎么让多台内网主机共用一个公网 IP 的？ | NAPT 映射表的键与生命周期 | 错误回答：说"靠 IP 地址区分"（必须靠端口）、说"NAT 是协议"；加分点：五元组建表、回程需命中表项、表项超时因此要保活 | 15.7.1 |
| 为什么 P2P 和 WebRTC 有时候连不上，STUN 和 TURN 各做什么？ | NAT 类型与打洞可行性 | 错误回答：说"有 STUN 就能连上"、把 STUN 与 TURN 职责说反；正确是锥型可打洞、对称型不可行必须 TURN 中继，ICE 负责编排与优先级 | 15.7.3、15.7.4 |
| 拥塞控制为什么不能放到路由器上做？ | 端到端原则的机制级论证 | 错误回答：只说"端到端原则要求这样"；必须答出路由器只有单包视图、无法维护逐流状态、无法可靠通知发送方（源抑制被废弃），并用 ATM ABR 与 ECN"只标记不决策"作对照 | 15.8 |
| 为什么加带宽不能让 ping 变快？ | 区分发送时延与传播时延 | 错误回答：说"带宽上去了 RTT 自然变小"；传播时延只由距离与介质决定，同城 100 km 光纤约 0.5 ms、跨大洲 15000 km 约 75 ms | 15.9.1、15.9.2 |
| 什么是带宽时延积，为什么跨大洲传大文件要开窗口扩大因子？ | BDP 与吞吐上界的定量推理 | 错误回答：把 BDP 说成带宽的同义词，或用单向时延计算；正确是 `BDP = 带宽 × RTT`、吞吐上界 `窗口 / RTT`，65535 字节窗口在 `RTT = 150 ms` 时只能跑到约 3.5 Mbps | 15.9.3、15.9.4 |
| 链路利用率是不是越高越好？ | 排队时延与利用率的关系 | 错误回答：说"利用率越高越省钱所以越好"；按 `Tq = (ρ/(1 − ρ)) × Ts`，`ρ = 0.9` 时排队时延是发送时延的 9 倍、`ρ = 0.99` 时约 99 倍，延迟敏感业务必须留余量 | 15.9.1、15.9.4 |

## 延伸阅读

- Kurose & Ross《计算机网络：自顶向下方法》第 1 章（协议层次与服务模型）、第 4 章（网络层数据平面：IPv4 分片、NAT）、第 5 章（控制平面）；
- Tanenbaum & Wetherall《计算机网络》第 1 章 1.4 节（OSI 与 TCP/IP 模型的对比与批评），用于回答"分层的坏处"；
- RFC 791（IPv4：标识、标志、片偏移）、RFC 1191（IPv4 路径 MTU 发现）、RFC 8201（IPv6 路径 MTU 发现）、RFC 8899（DPLPMTUD，面向不可靠 ICMP 的通用化方案）；
- RFC 826（ARP）、RFC 5227（IPv4 地址冲突检测与免费 ARP 的规范行为）、RFC 4861（IPv6 邻居发现）；
- RFC 3022（传统 IP 网络地址转换）、RFC 4787（NAT 对 UDP 的行为要求与锥型/对称型术语）、RFC 5389/8489（STUN）、RFC 8656（TURN）、RFC 8445（ICE）；
- RFC 3168（ECN）、RFC 2914 与 RFC 8085（拥塞控制原则）、RFC 5681（TCP 拥塞控制）、RFC 7323（窗口扩大因子与时间戳选项）；
- ATM Forum `TM 4.0` 规范中的 ABR 服务定义与 RM 信元/ER 字段，用于对照"在网络层做拥塞控制的失败尝试"。


---

> 作者: [破戒僧](https://onlyblacktea.cn)  
> URL: https://onlyblacktea.cn/book/backend/ch15/  

