目录
[二、rdt 2.0:带差错检测的停等协议](#二、rdt 2.0:带差错检测的停等协议)
[三、rdt 2.1:修复 ACK/NAK 不可靠性](#三、rdt 2.1:修复 ACK/NAK 不可靠性)
[四、rdt 2.2:纯 ACK 实现的可靠传输](#四、rdt 2.2:纯 ACK 实现的可靠传输)
[五、rdt 3.0:应对分组丢失和时延抖动](#五、rdt 3.0:应对分组丢失和时延抖动)
[1. 发送方操作](#1. 发送方操作)
[2. 接收方操作](#2. 接收方操作)
可靠数据传输原理是计算机网络中"top10"的问题,可靠数据传输的框架为上层实体提供服务的抽象是:数据可以通过一条可靠的信道进行传输。借助可靠信道,传输数据比特就不会受到损坏或者丢失,而且所有的数据都是按照其发送顺序进行交付。

完成这种服务的抽象是可靠数据传输协议(rdt)。因为可靠数据传输协议的下层也许是不可靠的,例如TCP协议就是在不可靠的(IP)端到端网络层之上实现的可靠数据传输协议,所以我们可以将较低层直接视为不可靠的点对点信道。
构造可靠数据传输协议
这里我们仅仅讨论单向数据传输的情况,即数据的传输是从发送端到接收端的。
一、rdt1.0:理想信道下的可靠传输
rdt1.0假设通信信道 完全可靠 (无分组丢失、无比特错误、分组按序到达),只需解决 发送方与接收方的同步问题。
核心假设与功能
- 信道特性:完全可靠(无差错、无丢失、按序到达)。
- 协议目标:仅需实现数据的 "原样传输",无需任何差错控制机制。
- FSM 模型
- 发送方 :
- 状态:唯一状态为 "等待上层调用"。
- 事件与动作 :
- 收到上层数据 → 封装为分组(无校验和)→ 通过
udt_send()
发送 → 返回初始状态。
- 收到上层数据 → 封装为分组(无校验和)→ 通过
- 接收方 :
- 状态:唯一状态为 "等待分组"。
- 事件与动作 :
- 收到分组 → 提取数据 → 通过
deliver_data()
交付上层 → 返回初始状态。
- 收到分组 → 提取数据 → 通过
- 发送方 :
该协议是后续版本的理论起点,用于验证可靠传输的基础逻辑(如数据封装与交付),但未解决现实信道的复杂性。
二、rdt 2.0:带差错检测的停等协议
rdt2.0假设信道可能引入 比特错误 (分组损坏),但 无分组丢失 ,且分组按序到达。需解决 错误检测、确认与重传 问题。
在 rdt 协议中,rdt2.0 及后续版本主要采用校验和方式进行差错检测。发送方在分组中添加校验和字段,接收方通过校验和验证分组的完整性,若校验失败则认为分组损坏,进而采取相应的处理措施。
核心假设与功能
- 信道特性:可能发生比特错误,但分组按序到达且无丢失。
- 协议目标:通过差错检测和重传机制实现可靠传输。
- 关键机制 :
- 差错检测:分组添加校验和字段,接收方通过校验和验证完整性。
- 确认机制 :
- ACK:正确接收分组时发送。
- NAK:检测到错误时发送。
- 停等协议:发送方发送分组后必须等待 ACK/NAK,才能发送下一个分组。
- FSM 模型 :
- 发送方 :
- 状态 1 :等待上层调用 → 发送分组并进入等待 ACK/NAK状态。
- 状态 2 :
- 若收到 ACK → 返回状态 1。
- 若收到 NAK → 重传分组,保持状态 2。
- 接收方 :
- 状态:唯一状态为 "等待分组"。
- 事件与动作 :
- 收到正确分组 → 交付上层 → 发送 ACK。
- 收到错误分组 → 发送 NAK。
- 发送方 :
该协议引入 自动重传请求(ARQ)思想,但未考虑 ACK/NAK 本身可能出错的问题,导致协议存在死锁风险。
三、rdt 2.1:修复 ACK/NAK 不可靠性
核心改进
- 问题背景 :ACK/NAK 可能在传输中受损,导致发送方无法正确判断分组状态(冗余分组)。
- 关键机制 :
- 序列号(1 bit):分组序号为 0 或 1,避免接收方混淆重复分组。
- 移除 NAK:接收方若收到错误分组,静默丢弃并等待发送方超时重传。
- 超时重传:发送方启动定时器,超时未收到 ACK 则重传分组。
- FSM 模型 :
- 发送方 :
- 状态 1 :等待上层调用 0 → 发送序号 0 分组 → 进入等待 ACK0/NAK0状态。
- 状态 2 :
- 若收到 ACK0 → 进入等待上层调用 1 状态。
- 若收到 NAK0 或超时 → 重传序号 0 分组,保持状态 2。
- 接收方 :
- 状态 1:等待序号 0 分组 → 正确接收后发送 ACK0 → 进入等待序号 1 状态。
- 状态 2:等待序号 1 分组 → 正确接收后发送 ACK1 → 返回状态 1。
- 若收到重复分组 → 丢弃并发送对应 ACK。
- 发送方 :
通过序列号和超时机制解决 ACK/NAK 不可靠问题,但仍依赖停等协议,效率较低。
四、rdt 2.2:纯 ACK 实现的可靠传输
核心改进
- 设计逻辑 :通过带序号的 ACK 简化协议**(冗余ACK)**,移除 NAK 的显式使用。
- 关键机制 :
- ACK 携带序号 :ACK 中显式包含期望接收的下一个分组序号 ,例如:
- 接收方正确接收序号 0 分组后,发送 ACK1(表示 "下一个期望序号为 1")。
- 若收到重复的序号 0 分组,仍发送 ACK1(隐含 "序号 0 已接收,无需重传")。
- 发送方逻辑 :
- 若发送序号 0 分组后收到 ACK1 → 确认序号 0 已接收,发送序号 1 分组。
- 若收到 ACK0 → 重传序号 0 分组(可能分组或 ACK 丢失)。
- ACK 携带序号 :ACK 中显式包含期望接收的下一个分组序号 ,例如:
- FSM 模型 :
- 发送方 :
- 状态 1 :等待上层调用 0 → 发送序号 0 分组 → 进入等待 ACK0状态。
- 状态 2 :
- 若收到 ACK0 → 进入等待上层调用 1 状态。
- 若收到 ACK1 或超时 → 重传序号 0 分组,保持状态 2。
- 接收方 :
- 状态 1:等待序号 0 分组 → 正确接收后发送 ACK1 → 进入等待序号 1 状态。
- 状态 2 :等待序号 1 分组 → 正确接收后发送 ACK0 → 返回状态 1。
- 发送方 :
该协议通过隐含否定确认 (ACK 序号)实现与 rdt 2.1 相同的功能,但逻辑更简洁,是 ARQ 协议的典型设计 。通过累积确认舍弃NAK。
五、rdt 3.0:应对分组丢失和时延抖动
核心假设与功能
- 信道特性:可能丢失分组(数据或 ACK),且存在随机时延抖动。
- 协议目标:在分组丢失和时延不确定的信道中实现可靠传输。
- 关键机制 :
- 超时重传:发送方发送分组后启动定时器,超时未收到 ACK 则重传。
- 处理时延抖动:定时器设置需大于统计平均 RTT,避免误触发重传。
- 序号循环使用:仍使用 0/1 序号,通过状态机区分新旧分组。
- FSM 模型 :
- 发送方 :
- 状态 1 :等待上层调用 0 → 发送序号 0 分组并启动定时器 → 进入等待 ACK0状态。
- 状态 2 :
- 若收到 ACK0 → 停止定时器 → 进入等待上层调用 1 状态。
- 若超时 → 重传序号 0 分组,重启定时器,保持状态 2。
- 接收方 :
- 状态 1:等待序号 0 分组 → 正确接收后发送 ACK0 → 进入等待序号 1 状态。
- 状态 2:等待序号 1 分组 → 正确接收后发送 ACK1 → 返回状态 1。
- 发送方 :
该协议是停等协议的最终形态,但效率低下 (发送方在等待 ACK 时无法发送新数据),为后续滑动窗口协议(如 GBN、SR)奠定基础。因为其核心特征是分组序号在 0 和 1 之间交替,所以它也被称为比特交替协议。
协议演进路径
- rdt 1.0 → rdt 2.0:从理想信道到处理比特错误,引入校验和、ACK/NAK 和停等机制。
- rdt 2.0 → rdt 2.1:修复 ACK/NAK 不可靠性,通过序列号和超时重传增强健壮性。
- rdt 2.1 → rdt 2.2:简化确认机制,仅用带序号的 ACK 实现相同功能。
- rdt 2.2 → rdt 3.0:应对分组丢失和时延抖动,引入定时器和超时重传。
所以我们看到,在检验和,序号,定时器,肯定和否定分组技术中,每种机制都在协议的运行中起到了关键作用。
流水线可靠数据传输协议
流水线可靠数据传输协议是为解决停等协议信道利用率低的问题而提出的一类协议,它允许发送方在未得到对方确认的情况下一次发送多个分组,就像工厂的流水线一样连续不断地发送数据,从而提高了信道利用率。

因此,流水线协议必须增加序号范围,因为每一个传输中的分组必须有一个唯一的序号,而且有多个在传输中未被确认的报文。协议的接收方和发送方两端也不得不缓存多个分组。所需序号范围和对缓冲的要求取决于数据传输协议如何处理丢失,损坏及时延过大的分组。解决流水线差错恢复的处理有两种基本方法是:回退N步(GBN)和选择重传(SR)。
停等操作
流水线操作
回退N步
发送方维护一个发送窗口,称为滑动窗口,窗口内的分组是可以连续发送的。最早未确认分组的序号称为基序号(base),最小未使用的序号称之为下一个序号(nextseqnum)。序号范围被划分为已发送并确认、已发送未确认、可利用序号以及不可用序号四个部分。随着协议运行,窗口在序号空间内向前滑动。

当上层调用 需要发送数据时,发送方检查发送窗口是否已满,未满则产生分组并发送,然后自增变量;已满则提示上层窗口已满,请上层稍后再尝试。收到 ACK 时,采用累积确认方式,即收到序号为 n 的 ACK,意味着序号 n 及之前的所有分组都已被正确接收,然后进行 "窗口滑动"。遇到超时事件时,发送方要重传所有已发送但未确认的分组,这就是 "回退 N 步" 的实现。
如果一个序号为 n 的分组被正确接收且是按需接收的,接收方就对分组 n 发送 ACK,并将该分组中的数据部分交付上层。接收方必须按序将数据交付给上层,对于其他情况(如失序分组)则直接丢包,并且为最近按序接收的分组重新发送 ACK。接收方不需要缓存任何失序分组,只需维护下一个按序接收的分组序号。

所以对于发送方来说,发送方必须维护窗口的上下界以及nextseqnum在窗口中的位置,接收方唯一需要维护的就是下一个按序接收的分组序号。需要注意的是,GBN协议的接收窗口大小为1。
选择重传
GBN 以简单性换取低效率,而 SR 通过复杂机制实现高效传输。前文我们可以看出,单个分组的差错就能引起GBN重传大量分组,许多分组根本没有必要重传。
与GBN累积确认不同的是,SR采用的是独立确认方式,接收方对每个正确接收的分组单独发送 ACK,无需按序。发送方和接收方窗口大小均为N
,且满足**N ≤ 2^(k-1)
** (k
为序号位数),以避免序号混淆。因为这一特性,SR拥有缓存机制,接收方能够缓存失序分组,直到连续分组到达后一并交付上层。每个分组对应一个定时器,超时后仅重传该分组,避免批量重传。

1. 发送方操作
- 上层调用:若序号在窗口内,发送分组并启动定时器;否则缓存数据或返回上层。
- 接收 ACK :若 ACK 对应的分组在窗口内,标记为已接收。若窗口基序号
base
的所有分组均被确认,窗口向前滑动至未确认分组的最小序号,并发送窗口内的新分组。 - 超时事件:仅重传超时的分组,并重启定时器。
2. 接收方操作
- 窗口内接收 :若分组序号在接收窗口内,接收并缓存,发送 ACK。若序号等于
rcv_base
,将连续分组交付上层,并滑动窗口。 - 窗口外接收 :若分组序号在
[rcv_base-N, rcv_base-1]
内(已接收但未确认),发送 ACK;否则忽略。

前面我们提到:发送方和接收方窗口大小均为N
,且满足**N ≤ 2^(k-1)
** (k
为序号位数)。
接收窗口过大的本质风险是序号混淆 和资源耗尽,这会直接破坏协议的可靠性和效率。
接收窗口过大,导致 序号循环时的混淆以及协议失效。

- 图 a
- 初始发送 :发送方在窗口内依次发送
pkt0
、pkt1
、pkt2
。接收方正确接收这三个分组后,分别返回ACK0
、ACK1
、ACK2
,此时接收方窗口滑动到下一个期望接收的序号位置(这里假设序号循环)。 - 超时重传 :假设网络出现问题,发送方迟迟未收到
pkt0
的确认,超时后重传pkt0
。但此时接收方窗口已经滑动,新窗口内并不期望接收pkt0
(因为接收方认为pkt0
已经正确接收过了)。如果接收窗口过大,就可能导致接收方把重传的pkt0
错误地当作新的、期望接收的分组接收 ,造成接收错误。
- 初始发送 :发送方在窗口内依次发送
- 图 b
- 正常发送与接收部分分组 :发送方发送
pkt0
、pkt1
、pkt2
、pkt3
等分组。接收方收到pkt0
、pkt1
、pkt2
后返回相应确认。假设pkt3
丢失,发送方窗口正常滑动,继续发送新的分组(图中显示发送了新的pkt0
)。 - 错误接收 :由于接收窗口过大,当发送方重传的
pkt0
到达接收方时,接收方可能因为窗口包含这个序号,就错误地接收它,而此时接收方实际期望的是丢失的pkt3
,这样就会造成接收的分组序号混乱,无法正确交付给上层,破坏了数据传输的正确性。
- 正常发送与接收部分分组 :发送方发送
接收窗口越大,接收方需要缓存的失序分组越多,接受方缓存压力剧增, 且接收窗口过大会间接影响发送方的发送策略,导致网络拥塞风险上升。 并且定时器管理复杂度也会陡增。
在 LTE 网络中,调度请求(SR)的发送周期和次数受严格限制,以避免 PUCCH 信道过载。类似地,SR 协议的窗口管理也需遵循资源约束,否则可能导致信道拥塞。例如在 TCP 等协议中,接收窗口由接收方根据自身缓冲区状态动态通告,发送方结合拥塞窗口(cwnd)调整发送速率,从而避免窗口过大引发的问题。
SR选择性确认,缓存失序分组,仅重传丢失的分组,减少冗余传输,尤其在高误码率环境下效率更高。但是需要更多缓存空间和复杂的定时器管理,实现难度较大。实际协议常结合两者的优点,例如 TCP 采用累积确认和部分选择性重传(如快速重传),以平衡性能与实现难度。
结语
本文假设是单向数据传输,我们假设分组在单向之间的信道不能重新被排序。在单段物理线路相连的情况下,这种假设是合理的。然而当连接的信道是一个网络时,分组重新排序是可能发生的。在数据传输过程中,分组重新排序针对接收到的乱序分组进行整理,使其恢复正确顺序,减少不必要的重传同时提升吞吐量。它是保障数据正确处理和交付给上层应用的关键环节。
🌱🌱🌱.