可靠数据传输:rdt 1.0 → 3.0 与 GBN / SR 两种流水线协议
可靠数据传输 — rdt 家族与流水线协议
核心结论
传输层向上要交付可靠的数据流,而它下面的网络层、链路层、物理层提供的信道不可靠(丢包、比特损坏、乱序)。可靠数据传输的全部机制,就是在这条不可靠信道上,用校验和 + 确认 + 重传 + 序号 + 定时器堆出来的。
rdt 家族是这套机制的最小推导路径:每加一种故障,就补一个机制。到 rdt3.0 功能上完备,但窗口为 1 的停等协议在大 RTT 下利用率极低,于是有了流水线的 GBN 与 SR。
五个版本:每加一种故障,补一种机制
| 版本 | 新增的故障假设 | 新增机制 | 状态数(发送端) |
|---|---|---|---|
| rdt1.0 | 下层完全可靠、保序 | 无(只发、只收) | 1 |
| rdt2.0 | 数据包比特可能损坏 | 校验和 + ACK/NAK 反馈 + 重传 | 2 |
| rdt2.1 | ACK/NAK 也可能损坏 | 加 1 bit 序号(0/1),接收端按序号判重传还是新包 | 4 |
| rdt2.2 | 同上,但要更简单 | 去掉 NAK,只用 ACK + 序号(ACK 语义改为"我收到了 seq=x") | 2 |
| rdt3.0 | 数据包会丢失 | 定时器 + 超时重传(否则双方互等死锁) | 4 |
几个容易记错的细节:
- rdt2.0 起就是停等协议:发送端在等 ACK/NAK 期间不会再向上一层取新数据。这不是缺陷,是定义。
- rdt2.1 为什么要序号:ACK 损坏时发送端不知道该不该重传 —— 重传可能让接收端收到重复包,不重传可能让接收端一直等。序号把"是重传包还是新包"变成可判定的事实。
- 2 bit 就够:停等协议下接收端只需要区分"上一包"和"新包",两个序号(0,1)足够。
- rdt3.0 收到损坏包或错序号 ACK 时不做处理、直接等超时:定时器本来就很短,等超时比额外定义一个 NAK 路径更简单。
停等协议为什么慢:滑动窗口视角
把待发数据排成一列,协议用一个"框"罩住当前允许发送的区间,这个框就是滑动窗口:
- 发送窗口大小 = 1,接收窗口大小 = 1 → 就是 rdt3.0 的停等协议:每发一个包都要等 RTT 走完才能发下一个。
- 发送窗口 > 1 → 流水线协议:发送端可以在定时器窗口内连发多个未确认分组,把等待时间填满。
rdt3.0 的利用率问题本质是:一个 RTT 只搬运一个包,RTT 越大、带宽越大,浪费越严重。要改,就得同时扩三样东西:
- 序号范围(多个在途分组必须各有唯一序号);
- 发送端缓冲(保存已发未确认的分组);
- 接收端缓冲(保存已收但还不能上交/确认的分组)。
按接收端缓冲扩不扩,分出两种流水线协议。
GBN:只扩发送窗口
Go-Back-N:发送端维护大于 1 的窗口,接收端窗口仍为 1。
- 采用累计确认:
ACK n表示"n 及之前的全部收到"。 - 接收端丢弃乱序包,只按序收;收到不按序的包时,重复发送最近一次正确收到的 ACK。
- 发送端超时后重传该包及其之后所有已发未确认的包("回退 N 步"因此得名)。
典型现象:第 2 号包丢失时,后面的 3、4 号包虽然到了接收端也会被丢弃,接收端持续回 ACK 1("我收到的最大序号是 1"),发送端超时后重发 2、3、4。
反过来,如果只是某个 ACK 丢了(如 ACK2),后来的 ACK3/ACK4 已经隐含"2 号也收到了",发送端不会重发 2 —— 累计确认天然吃掉这类丢失。
SR:发送、接收窗口都扩
Selective-Repeat:发送端与接收端各维护一个大于 1 的窗口。
- 采用单独确认:每个分组都有自己的 ACK。
- 接收端缓存乱序到达的包,只把确实丢失的那个报告给发送端(靠超时)。
- 发送端超时后只重传丢失的那一个包。
代价是接收端要有缓冲和乱序重组逻辑,换来的是重传量最小化。信道质量差、窗口大时,这个代价通常值得。
对比
| 维度 | GBN | SR |
|---|---|---|
| 发送窗口 | > 1 | > 1 |
| 接收窗口 | = 1 | > 1 |
| 确认方式 | 累计确认 | 单独确认 |
| 乱序分组 | 丢弃 | 缓存 |
| 超时后重传 | 该包及之后全部 | 只重传出错的那一个 |
| 接收端复杂度 | 低 | 高(需缓冲与重组) |
| 恶劣信道下的重传量 | 大 | 小 |
一句话选型:信道误码低、缓冲贵 → GBN;信道差、重传代价高 → SR。
与 TCP 的对照
TCP 是这条推导在工程上的实现:序号 + 校验和 + 累计确认 + 超时重传 + 流水线。它更接近 GBN 的思路,同时用可选扩展(SACK)获得 SR 的"只重传缺失段"能力。理解 rdt 家族的价值在于:TCP 里每个看似随意的字段,都能追溯到它要修复的那一种故障。
来源
- 原文:可靠数据的传输原理(RDT/GBN/SR)
- 教材:Computer Networking: A Top-Down Approach(Kurose & Ross, 7th Ed.)第 3 章
- 交互演示:Go-Back-N · Selective-Repeat
