本页目录

网络 I · 分层、TCP/IP 与拥塞控制

对标:Stanford CS144 / Kurose–Ross 自顶向下 | 前置:408 网络的概念框架、os 线(socket 是系统调用) 网络是"让全世界的机器可靠通信"的工程奇迹,而它的核心设计哲学只有一个词——分层。这一页讲清 TCP/IP 四层各干什么、为什么这样切,然后深入 TCP 的两大发明:在不可靠的网络上造出可靠传输(确认 + 重传 + 滑动窗口)与拥塞控制(几十亿设备共享带宽却不崩溃的分布式算法)。

学习层:一个丢包,为什么不会让字节流失序?

具体谜题:序号 2 消失之后,ACK 应该说什么?

发送端一次允许发送序号 0–5,接收端按序交付。若数据包 2 丢失,而 3、4、5 先到达,接收端是确认“我收到了 5”、重复确认 2,还是立刻交付 3–5?三种回答对应三种不同的可靠性设计;先写出你认为 TCP 应该做什么。

先预测,再展开:预测累计 ACK 的值、发送端下一次重传的序号,并判断三个重复 ACK 对拥塞窗口的影响。不要把“收到包”与“交付字节流”混为一谈。

最小心智模型:四个边界和一个滑动窗口

IP 只负责尽力转发;TCP 在其上维护发送序号、接收序号、确认、重传计时器和窗口。对接收端而言,序号是字节流的位置,不是数据包的身份;乱序段可以暂存,但只有连续前缀能推进交付边界。

形式机制与不变量

若 \(ACK=k\),累计确认表示所有序号小于 \(k\) 的字节已按序收到。发送边界满足 \(\mathrm{snd.una}\le\mathrm{snd.nxt}\le\mathrm{snd.una}+\min(\mathrm{rwnd},\mathrm{cwnd})\);只有右边界仍有空间时(\(\mathrm{snd.nxt}<\mathrm{snd.una}+\min(\mathrm{rwnd},\mathrm{cwnd})\))才能继续发送。接收端的交付不变量是不会跳过缺口。Reno 的典型规则是无拥塞时 \(cwnd\leftarrow cwnd+1/cwnd\),检测到丢包时降低窗口,体现 AIMD 而不是“网络越快越无限发送”。

反例与失效边界

累计 ACK 不是全局顺序的证明:接收端可能已缓存乱序段;三个重复 ACK 的快速重传依赖具体实现与时序,超时重传仍是另一条路径。TCP 的可靠性也不保证应用语义上的幂等;UDP 没有这些机制,拥塞控制更可能由应用自行承担。

迁移任务:从 trace 到可验收的传输实现

在 P05 迷你 TCP 中为每个状态写出 snd.una、snd.nxt、重传队列和 ACK 处理的不变量,再把丢包 trace 改成乱序加重复包。L12 HTTP 服务器建立在可靠字节流之上,但它不能替 TCP 隐藏超时、拥塞和连接生命周期;两者的分层接口要分别验收。

交互实验:滑动窗口与累计 ACK 重放

无 JavaScript 时的静态读法:默认窗口含序号 0–5,序号 2 丢失。接收 0 后发送 ACK=1,接收 1 后 ACK=2;3、4、5 虽到达却只能各产生重复 ACK=2,不能越过缺口交付。三个重复 ACK 触发快速重传 2,随后 ACK=6,发送端才继续推进;若改成超时模型,拥塞窗口会更激烈地下降。状态中的窗口边界是字节/序号账本,不是带宽测量。

事件 接收端动作 ACK 发送端结论
收到 0 交付 0 1 确认前缀 [0]
收到 1 交付 1 2 缺口为 2
收到 3/4/5 缓存乱序 2、2、2 三次重复 ACK
重传 2 交付 2–5 6 窗口前沿推进

1. 为什么分层:对抗复杂度的经典范式

TCP/IP 四层 + 封装:[以太网[IP[TCP[HTTP]]]] 套信封。

图 net-01.3TCP/IP 四层 + 封装:[以太网[IP[TCP[HTTP]]]] 套信封。

网络要处理的事太多——电信号、路由、丢包、应用协议……分层把它们切成独立的关注点,每层只依赖下层的抽象服务:

层 职责 地址/单位 代表协议
应用层 应用逻辑 — HTTP、DNS、SMTP
传输层 进程到进程、可靠性 端口 TCP、UDP
网络层 主机到主机、路由 IP 地址 IP
链路层 相邻节点、物理传输 MAC 以太网、WiFi

核心思想——封装:应用数据下沉时,每层加自己的头部(像套信封):[以太网头[IP头[TCP头[HTTP数据]]]]。接收方逐层拆封。每层只看自己的头、不管上层内容——这个"关注点分离"让 IP 不用懂 HTTP、以太网不用懂 IP,各层能独立演进(IPv4→IPv6 不影响上层)。分层是计算机科学对抗复杂度最成功的一次实践,理解它比记住任何协议细节都重要。

端到端原则:复杂功能(可靠性、加密)尽量放在端(主机),网络核心保持简单(只管尽力转发)。这是互联网可扩展的哲学根基——"聪明的边缘、笨的核心"。

2. IP 与路由:尽力而为的底座

IP 层只承诺"尽力而为"——尽力把包送到,但可能丢失、乱序、重复、延迟。它不保证任何东西。为什么这么弱?因为端到端原则:可靠性交给端上的 TCP。IP 的工作是路由——每个路由器看目标 IP、查路由表、转发到下一跳。路由表怎么来的是路由协议(BGP 连接全球自治域、OSPF 域内)的事。理解"IP 不可靠"是理解 TCP 全部复杂性的前提:TCP 的每个机制都在弥补 IP 的某个不保证。

3. TCP:在不可靠之上造可靠

TCP 三次握手 SYN/SYN-ACK/ACK 时序 + 为什么三次。

图 net-01.2TCP 三次握手 SYN/SYN-ACK/ACK 时序 + 为什么三次。

TCP 给应用的承诺:可靠、有序的字节流。它靠三招在不可靠的 IP 上实现:

这就是 [大 Project P05 迷你 TCP] 的核心:在 UDP(不可靠)之上,用序号 + ACK + 滑动窗口 + 超时重传,亲手实现可靠传输——做完这个,"可靠传输"从名词变成你写过的代码。

4. 拥塞控制:几十亿设备的分布式协作

AIMD 拥塞窗口锯齿曲线:慢启动指数→拥塞避免线性增→丢包减半。

图 net-01.1AIMD 拥塞窗口锯齿曲线:慢启动指数→拥塞避免线性增→丢包减半。

流量控制防的是"发送方淹没接收方";拥塞控制防的是"大家一起淹没网络中间的路由器"。这是 TCP 最深刻的发明——没有中央协调,每个连接各自调整,却涌现出全局稳定的带宽分配:

读法:拥塞控制是"自私的个体遵守简单规则、涌现出全局良序"的绝佳范例(🔗 与博弈论、物理站的涌现同构)。AIMD 为什么公平稳定,可以用一个二维相图证明(收敛到公平线上),是理论之美与工程实用的少见合体。

5. TCP vs UDP:什么时候不要可靠

UDP 是"裸 IP + 端口"——不可靠、无序、无连接,但快、简单、无队头阻塞。选择取决于需求:

6. 练习与要点

例 1(三次握手为什么是三次) 论证两次不够(服务器无法确认客户端能收)、四次多余——最小回合数的推理,理解协议设计的"恰好够用"。

例 2(AIMD 锯齿) 画出单个 TCP 连接窗口随时间的锯齿曲线,标出慢启动、拥塞避免、丢包减半——"带宽的呼吸"可视化,再想两个连接如何收敛到公平。

例 3(选 TCP 还是 UDP) 给三个场景(转账确认、直播、多人游戏位置同步)各选传输协议并说理由——把"可靠性 vs 延迟"的权衡用到真实决策。\(\blacksquare\)


📋 大 Project P05 · 迷你 TCP(用户态可靠传输)

教师版作业说明书,不提供完整解。 这是网络线的核心课程作业:在 UDP 之上重建一个可靠、有序、有流量控制和拥塞控制的字节流协议。

  • 学习目标:让学生把“TCP 可靠”拆成序号、ACK、重传、窗口、状态机、拥塞控制这几块,并理解每块解决哪类网络故障。
  • 教师提供:UDP unreliable network harness(丢包、乱序、重复、延迟、限速)、参考黑盒 endpoint、pcap 日志导出、文件传输 benchmark。
  • 学生任务:① ByteStream 读写缓冲;② sender:分段、序号、RTO 估计、超时重传;③ receiver:乱序重组、累积 ACK、窗口通告;④ connection:三次握手、四次挥手、TIME_WAIT;⑤ congestion:慢启动、拥塞避免、丢包减半。
  • 协议约束:不得假设 UDP 包可靠到达;所有计时器必须可测试;序号回绕要有清晰处理;流量窗口和拥塞窗口要同时限制发送。
  • 验收测试:0% 丢包下可传大文件且校验一致;10% 丢包/乱序/重复下仍可靠有序;与参考 endpoint 互通;吞吐随窗口增大合理上升,丢包后 cwnd 呈 AIMD 行为。
  • 评分重点:字节流与重组 20%,重传与 ACK 30%,连接状态机 20%,拥塞控制 20%,抓包分析报告 10%。
  • 延伸挑战:实现 fast retransmit / fast recovery,并用一张 cwnd 时间图对比超时重传。

下一页:网络 II——应用层:HTTP 的演进、TLS 握手、DNS,以及现代网络(CDN、QUIC)如何让网页秒开。