3.4 Principles of Reliable Data Transfer (Part 2)

上接 Part 1。

3.4.2 Pipelined Reliable Data Transfer Protocols

如我们在 Part 1 中指出的,rdt3.0 虽然是一个正确的可靠数据传输协议,然而它的性能无法满足需求。因为它实质上是一个 stop-and-wait 的协议,即在收到上一个数据的 ACK 之前无法发送下一个数据。

解决方法是,sender 不需要等待 ACK,可以连续发送多个数据包。

  • 每个 inflight 的包都应该有一个唯一的序号
  • 序号的范围与传输协议的行为有关
  • Sender 和 Receiver 需要缓存所有 inflight 的数据包

3.4.3 Go-Back-N

在 Go-Back-N 协议中,Sender 允许在未收到 ACK 的情况下最多发送 N 个数据包。

之所以有 N 这个限制,是为了流量控制和拥塞控制。

  • 流量控制:控制发送速度以防接收方缓存溢出
  • 拥塞控制:网络拥塞时控制发送速度

下图是一个正在发送 nextseqnum 号数据包的情形:

Sender's view of sequence numbers in Go-Back-N
  • [0, base-1]:已经收到ACK
  • [base, nextseqnum-1]:已经发送,尚未收到 ACK (inflight)
  • [nextseqnum, base+N-1]:尚未发送,但是允许在未收到 ACK 前继续发送
  • [base+N, +∞]:在收到 ACK 前无法发送

对于发送方,行为如下图所示:

GBN sender

对于不同的事件,值得注意的地方有:

事件 重点
rdt_send(data) 1. 若已有 N 个 inflight 的数据包,发送失败
2. 若这是第一个 inflight 的数据包,开始计时
3. 每次发送序号+1
timeout 1. 重发所有 inflight 的数据包
rdt_rcv(rcvpkt) 1. 若数据包损坏,不作处理
2. 更新 base 为收到的数据包序号 + 1
3. 刷新计时器
GBN receiver

对于接收方,相对简单一些。尤为值得注意的是,我们期望收到的包序号仍旧是每次 +1 的。这意味着如果我们收到了乱序的数据包,例如本来期望 m,但是收到了m+1,那我们会丢弃掉这个提前收到的数据包。这个做法似乎有点浪费,但是由于接收方要保证数据的顺序,所以必须这么做。

下图是一个 N=4 的例子。

Go-Back-N in operation

值得注意的点:

  • 在未收到 ACK 之前,连续发送了 N = 4 个数据包,然后才开始等待。

  • 收到 0 的ACK,发送 4 号数据包,收到 1 的ACK,发送 5 号数据包

  • 2 丢包会导致 2~5 数据包全部重发

3.4.4 Selective Repeat

Go-Back-N 虽然相对 stop-and-wait 协议有所提升,但是还是存在性能问题。它的问题在于一个传输出错的数据包会导致许多重传(联系上面的图,2号数据包的丢失导致2~5号数据包全部重传)。

selective-repeat 协议避免了不必要的重传。相比于 GBN 协议,它主要的改动在于让 receiver 维护一个 buffer,对于乱序收到的数据包,我们回复 ACK 并保存在 buffer 中,直到收到之前所有的数据包再交付给上层。

它的原理如下图所示:

Selective-repeat sender and receiver views
  • send_base 永远指向第一个没有收到 ACK 的需要发送数据
  • rcv_base 永远指向第一个未发送 ACK 的数据(即未收到)

因此 [send_base, send_base + N - 1] 是 Sender 的发送窗口(发送数据),而 [rcv_base, rcv_base + N - 1] 是 Receiver 的接收窗口,两者并不是一样的。

Sender

  1. 每个packet有自己的 timer
  2. 收到 ACK 时,将 send_base 移动到下一个未收到确认的包

Receiver

对于收到的序号,分四种情况:

  1. rcv_base:从 rcv_base 开始,到下一个未发送 ACK 的为止,将这部分数据交付给上层,并发送 ACK rcv_base
  2. [rcv_base + 1, rcv_base + N-1]:说明提前收到了后来的数据。将这些数据缓存,并发送 ACK rcv_base + m
  3. [rcv_base - N, rcv_base - 1]:这部分是已经发送了 ACK 的部分,但是不能保证是否 Sender 收到了 ACK,所以再次收到这部分数据时,虽然不需要处理数据,但需要重复 ACK。该范围的 N 是由于发送端最多允许 N 个 inflight 的消息。
  4. 其他:不作处理。

对于图 3.22 种的场景,如果我们不用 Go-Back-N 而是使用 Selective-Repeat,我们就无需重传 3~5 号数据包。

SR operation

这样我们就有了一个真正可用的可靠数据传输协议。我们再扩展一下 Part 1 中的表格:

机制 作用 注释
Checksum 检测 bit error
ACK/NAK 接收方通知发送方数据包是否正确收到 包含 ACK/NAK 数据包的 Sequence number
Sequence number 将发送端到接收端到每个数据包编号 接收端若发现 gap,则说明丢包;若发现重复,则说明收到重传的数据
Pipelining 允许发送方在收到 ACK 之前发送多个数据包,提高性能
Window 限制发送方只能发送一定范围内的数据,用于拥塞控制和流量控制

我们现在对信道仍有一个假设:数据包必须按顺序传输。

这个假设在实际网络中并不成立。其表现为,我们可能收到序号不在窗口之中的数据包或者 ACK。实际上的网络信道可以认为是一个缓存了要发送的所有数据包的 buffer,并且可能随时随机地触发这些数据包。

由于我们可能会重用序号,实际中,我们会设置一个数据包的“寿命”(TCP 协议中大约是 3 分钟)。这样就保证了在重用序号之前,所有该序号的游荡数据包都已经消失。

你可能感兴趣的:(3.4 Principles of Reliable Data Transfer (Part 2))