Appearance
选择重传协议(SR)
2026 大纲 三(四)4 选择重传协议(SR)。一般约束
与 的推导集中在本篇;GBN 只推它自己那条特例,信道利用率公式的原始推导在停止-等待协议。
一、丢一帧连坐一整批,太亏了
GBN 有一处很别扭:丢了帧 2,后面正确到达的帧 3、4、5 全被丢弃,超时后连它们一起重传。这些帧本身一点问题都没有。
SR 要做的就是把这个连坐去掉:只重传真正出错的那一帧,正确到达的乱序帧先缓存起来。
但这句话不能只改一处,必须同时改三处:
| 改哪里 | 为什么非改不可 |
|---|---|
| 接收窗口 | 不然接收方连"收下非期望序号的帧"的资格都没有 |
| 确认方式改成逐个确认 | 累积确认表达不了"3、4 收到了但 2 没有",缓存了也白缓存 |
| 每帧一个计时器 | 只有一个计时器就只能判"最早未确认帧超时",没法单独说某一帧超时 |
三者是一套,拆掉任何一半 SR 就退化回 GBN。 接收方缓存了乱序帧却仍用累积确认,发送方永远得不到"帧 3、4 已到"这条信息,超时时照样成批重传——缓存与逐个确认是一对。
二、逐个确认换来什么、丢掉什么
逐个确认:ACK
| 累积确认(GBN) | 逐个确认(SR) | |
|---|---|---|
| ACK 丢失 | 后续更大的 ACK 自动覆盖,不必重传 | 无法覆盖,该帧只能等超时重传 |
| ACK 数量 | 可以合并,少 | 每帧一个,多 |
| 发送方状态 | 一个左边界即可 | 窗口内每帧一个状态位 + 一个计时器 |
| 反馈信息量 | 只能表达连续前缀 | 能表达任意接收模式 |
第一行是 SR 的真实代价,容易被忽略:GBN 里丢一个 ACK 几乎没有后果,SR 里丢一个 ACK 就一定会引发一次多余重传。SR 用更精确的反馈换来更少的连坐重传,同时失去了累积确认自带的那份容错。
三、接收方按三个区域行事
收到一帧,先看它落在哪里:
| 帧落在哪 | 动作 |
|---|---|
| 接收窗口内 | 缓存,并发本帧的 ACK;若它补齐了最左端,就把最左端起的连续帧一并按序交付,窗口前移相应格数 |
| 窗口之前(已收过) | 丢数据,但必须重发该帧的 ACK |
| 窗口之后 | 丢弃 |
第二行的"必须"值得单独说:发送方之所以重传这一帧,只有一个原因——它没收到这一帧的 ACK(要么丢了,要么迟到了)。接收方若因为"我早就收过了"而沉默,发送方会一直超时重传下去,这一帧的计时器永远停不下来,发送窗口的左边界永远推不动,整条流水线卡死。
这里有两处措辞要与 GBN 分开,它们是同一句话的两个版本,不能互换:
- SR 对窗口之前的重复帧重发"本帧"的 ACK;
- GBN 重发的是"上一个按序帧"的 ACK(它只有一个期望序号,说不出别的)。
还有一条边界:缓存乱序帧不等于提前交付。帧 3、4 缓存着,帧 2 没补上就一个都不能交给上层——缓存解决的是"不用重传",不是"提前交付"。
交互可视化
四、同一丢帧场景:SR 与 GBN 的分野
与 GBN 的唯一实质差别在两处 Note:帧 3、4 被缓存而不是被丢弃,因此超时后只重传帧 2。
把数字算出来更直观。
GBN(
| 到达的帧 | 接收方期待 | 处理 | 回送 |
|---|---|---|---|
| 0 | 0 | 收下交付,期待→1 | ACK 0 |
| 1 | 1 | 未到达 | — |
| 2 | 1 | 不匹配 → 丢弃 | ACK 0(重复) |
| 3 | 1 | 不匹配 → 丢弃 | ACK 0(重复) |
| 4 | 1 | 不匹配 → 丢弃 | ACK 0(重复) |
帧 1 超时 → 重传 1, 2, 3, 4,共 4 帧。
SR(
| 到达的帧 | 接收窗口 | 处理 | 回送 |
|---|---|---|---|
| 0 | 落在窗口内,收下缓存;它补齐了最左端,交付帧 0,窗口前移 1 → | ACK 0 | |
| 1 | 未到达 | — | |
| 2 | 落在窗口内,收下缓存(不能交付,前面缺 1) | ACK 2 | |
| 3 | 落在窗口内,收下缓存 | ACK 3 |
帧 1 超时 → 只重传帧 1,共 1 帧。帧 1 到达后,接收方把缓存的 1、2、3 一起按序交付,窗口前移 3 格。
同一场景 GBN 重传 4 帧、SR 重传 1 帧,省下 3 帧——省下的数量恰好等于"丢失帧之后已经正确到达的帧数"。 误码率越高、窗口越大,这个数字越大。
两个窗口是异步滑动的
发送窗口看"最早未确认帧是否被确认",接收窗口看"最左端起是否连续收齐"。判据不同,位置必然错开——大小可以相同,位置从来不必相同。
也正因如此,SR 的发送窗口里会出现"洞"(后面的帧已确认、前面的还没有)。GBN 里洞不可能存在,累积确认让左边界一推就把中间全填了。
以
初始:
发送窗口 [0 1 2 3]
接收窗口 [0 1 2 3]
发出帧 0,1,2,3,其中帧 2 丢失:
发送窗口 [0 1 2 3] ← 4 帧全部已发未确认,窗口填满,发不出新帧
接收方 收到 0,1,3;缓存 3;交付 0,1;窗口前移 2 格
接收窗口 [2 3 4 5] ← 仍在等帧 2
收到 ACK 0、ACK 1、ACK 3 后:
发送窗口 [2 3 4 5] ← 左边界推到最早未确认帧 2;3 已确认但不能越过 2(这就是"洞")
帧 2 超时,重传帧 2,接收方收到后:
接收方 2 补齐最左端,把 2、3 一起按序交付,窗口前移 2 格
接收窗口 [4 5 6 7]
发送窗口 [4 5 6 7] ← 收到 ACK 2 后左边界推到 4接收窗口前移几格,只看"从最左端起连续收齐了几个",不是看窗口有多大。这里连续段是 2、3,所以只滑 2 格。
五、窗口约束:一条通用式管三个协议
序号
| 协议 | 代入通用式 | 结果 | |
|---|---|---|---|
| 停止-等待 | 1 | ||
| GBN | 1 | ||
| SR( |
三个上限是同一条式子的三次代入,记住通用式就不必分开记。
⚠️ 注意
违反约束会具体错在哪
故意违反:
| 时刻 | 发送方 | 信道 | 接收方 |
|---|---|---|---|
| ① | 发送窗口 | 三帧全部正确到达 | 接收窗口 |
| ② | 仍在等确认 | 接收方逐个发出 ACK 0、1、2 | 0,1,2 连续,按序交付上层,接收窗口前移 3 格 → |
| ③ | — | 三个 ACK 全部丢失 | — |
| ④ | 帧 0 的计时器超时,只重传帧 0 | 重传的帧 0 到达 | 接收窗口是 |
| ⑤ | — | — | 重复数据被当作新的一轮数据,可靠传输失效 |
取
六、SR 的四份代价,与怎么选
SR 的上限反而小于 GBN,这一条最反直觉:
由此推出另一条:无差错时 SR 的利用率不如 GBN。同样的
四份代价一起摆出来:
- 窗口上限被压小(
对 ); - 接收方要缓冲区与重排序逻辑;
- 发送方要管
个计时器; - ACK 丢失无法被后续 ACK 覆盖,丢一个 ACK 必然引发一次多余的超时重传。
该选谁:误码率低、窗口是瓶颈(
本节小结
- SR 只重传出错的那一帧,为此必须同时改三处:
、逐个确认、每帧一个计时器——三者是一套,拆掉任何一半就退化回 GBN。 - 接收方按三区域行事:窗口内缓存并发本帧 ACK(补齐最左端才连续交付);窗口之前丢数据但必须重发该帧的 ACK;窗口之后丢弃。缓存解决的是"不用重传",不是"提前交付"。
- 通用约束
由"发送方可能重传的旧序号"与"接收方将要接收的新序号"不得重叠推出;代入 得 GBN 的 ,代入 得 SR 的 。接收窗口的格数是从发送窗口里扣的,所以 SR 上限反而更小,无差错时利用率也更低。
考点速记
本节在真题里被考过的形式有三类,三类各卡一个不同的点:
① 数重传帧数(cn-2011-35)。已发 0~3,收到 1 号帧的确认,0、2 号帧依次超时,问要重传几帧。SR 是逐个确认,ACK 1 只确认帧 1、不隐含帧 0;超时的是 0 和 2,就只重传这 2 帧,帧 3 既没超时也没被连坐。把这道题按 GBN 的累积确认去做会得到 3 或 4,那正是干扰项。
② 由一个窗口反求另一个窗口(cn-2019-35)。3 比特编号、发送窗口 5,问接收窗口最大是多少。这道题必须回一般式——
③ 读时序图判断某时刻发什么(cn-2024-37)。序号 3 比特、发送窗口与接收窗口相同且均为最大值,故
是收到 ACK0 的时刻:SR 逐个确认,ACK0 让左边界推到 1,窗口变成 —— 腾出一格,发 F4。 是F1 超时的时刻:每帧一个计时器,超时的是谁就只重传谁,发 F1。
图上另外那些信息(ACK3 在回程丢失)是干扰兼提示:SR 的 ACK 丢失无法被后续 ACK 覆盖,所以 F3 将来还要靠它自己的计时器超时重传,但那发生在
易错:SR 的窗口上限是
,比 GBN 的 小。 别因为"SR 更先进"就以为窗口更大。
易错:
时必须回一般式 。 只是 的特例。
易错:SR 是逐个确认,ACK
不隐含前面的帧。 数重传帧数时不能按累积确认推。
易错:对窗口之前的重复帧,SR 重发"本帧"的 ACK,GBN 重发"上一个按序帧"的 ACK。 两句话不能互换。
易错:缓存乱序帧不等于提前交付。 最左端没补上,缓存的帧一个都交不出去。
易错:接收窗口前移几格,看的是"从最左端起连续收齐了几个",不是窗口大小、也不是缓存了几个。
教材出处
谢希仁《计算机网络》(第 8 版)在链路层与运输层都没有以"选择重传协议"为题的独立小节,因此本篇的窗口约束推导无该书可引;此处只引与 SR 的核心思想(选择性地只补缺失部分)直接对应的段落,其余结论未在正文中标注页码出处。
- 谢希仁《计算机网络》(第 8 版)p235(5.6.3 选择确认 SACK):提出 SR 所要解决的问题——"若收到的报文段无差错,只是未按序号,中间还缺少一些序号的数据,那么能否设法只传送缺少的数据而不重传已经正确到达接收方的数据?答案是可以的";并说明接收方缓存乱序块的做法——"如果这些字节的序号都在接收窗口之内,那么接收方就先收下这些数据,但要把这些信息准确地告诉发送方,使发送方不要再重复发送这些已收到的数据"。同页还给出一条现实注记:SACK 文档"并没有指明发送方应当怎样响应 SACK。因此大多数的实现还是重传所有未被确认的数据块"。
- 同书 p225(5.4.2 连续 ARQ 协议):累积确认的局限——"缺点是不能向发送方及时反映接收方已经正确收到所有分组的信息","发送方无法知道后面三个分组的下落,而只好把后面的三个分组都再重传一次"。这正是 SR 改用逐个确认要补上的信息缺口。
- 同书 p222 脚注:序号循环使用导致的新旧帧混淆问题——"分组编号使用的位数总是有限的,编号会重复使用……必须能够区分开哪些是新发送的,哪些是重传的"。这是本篇窗口约束推导的出发点。
相关知识
后退 N 帧协议(GBN)|停止-等待协议|三种 ARQ 协议对比