回退N步和选择重传

979 阅读5分钟

在上一篇文章中我们讲到了解决流水线的差错恢复有两种基本方法,它们分别是 回退 N 步选择重传

那么这篇文章我们就来讲解一下这两个方法具体是怎么实现的。

回退 N 步(GBN)

回退 N 步 协议中,允许发送方发送多个分组而不需要等待确认,但它受限于在流水线中未确认的分组数不能超过某个最大允许数 N

如下图所示,将基序号定义为最早未被确认分组的序号,将下一个序号定义为最小的未使用序号(即下一个待发分组的序号),则可将序号分为四段。

0 ~ base - 1 段内的序号对应于已经发送并被确认的分组,base ~ nextseqnum - 1 段内对应已经发送但未被确认的分组,nextseqnum ~ base + N - 1 段内的序号能用于那些要被立即发送的分组,如果有数据来自上层的话。

最后大于或者等于 base + N 的序号是不能使用的,直到当前流水线中未被确认的分组已得到确认。

image.png

那些已被发送但还未被确认的分组的许可序号范围可以被看成是一个序号范围内长度为 N 的窗口,随着协议的运行,该窗口在序号空间向前滑动。因此 N 常被称为 窗口长度(window size),GBN 协议也常被称为 滑动窗口协议

image.png

在上面的图片中,上方的是发送方,下方的是接收方,我们可以看到上方的深蓝色(是叫深蓝色吗???)和下方的红色为已被确认的分组,而上方的灰色矩形框是 GBN 的窗口长度,右侧是数据也正是我们前面的内容中所讲到的。

我们先来看一下正常情况下的 GBN 是一个怎么样的情况的,如下图所示:

动画.gif

在这里的操作中我们可以通过 Pause 选择暂停,点击某个在发送中的包 ack 或者 packet,通过点击 Kill Packet/ACk 执行丢包的过程,这样就模拟了一个丢包的过程,首先我们来看看发送过程中的丢包,具体如下图所示:

动画.gif

当发送过程中的 1 号包发生丢失时,发送方没有收到接收方的 ACK,于是后面发送的 ACK2,ACK3,ACK4全部变成了 ACK0,代表接收方因为丢失了分组1,所以分组 234 分组都被丢弃。

所以全部返回 ACK0,经过一段时间后,定时器确认超时没有收到 ACK2ACK3ACk4,所以发送方将重新发送。也代表接收方首先只收到了分组1之前的包。

我们再来看看在接收过程中发送丢包,具体如下图所示:

动画.gif

在上面的例子中,因为本次返回了 ACk2ACK3ACk4,所以发送方可以判断接收到消息,不再进行重复发送。

选择重传(SR)

GBN 协议潜在地允许发送方用多个分组 "填充流水线",因此避免了停等协议中所提到的信道利用问题。然后,GBN 本身也有一些情况存在着性能问题,尤其是当窗口长度和带宽时延都很大时,在流水线中会有很多分组更是如此。

单个分组的差错就能引起 GBN 重传大量分组,许多分组根本没有必要重传。

选择重传 协议便是用来解决这个问题,原理也很简单,接收端总会缓存所有收到的帧,当某个帧出现错误时,只会要求重传这一个帧,只有当某个序号后的所有帧都正确收到后,才会一起提交给高层应用,重传协议 的缺点在于接收端需要更多的缓存。

选择重传协议通过发送方仅重传那些它怀疑在接收方出错(丢失或受损)的分组而避免了不必要的重传,这种个别的、按需的重传要求接收方逐个地确认正确接收的分组,再次用窗口长度 N 来限制流水线中未完成、未确认的分组数。

GBN 不同的是,发送方已经收到了对窗口中某些分组的 ACK

我们来看看 SR 协议在发送端发送过程中发生丢包的情况,如下图所示:

动画.gif

在上图中,在发送的过程中,分组1丢失,但其他分组都被正常接收,这和 GBN 不同的是,分组1会被标记起来,分组2、3、4会被接收端缓存起来。等待分组1的计时器超时后,分组1重新发送,然后在接收端将分组1、2、3、4一起交付交付,并往发送端发送 ACK1

我们再来看看 Sr 协议在接收端发送过程中发生丢包的情况,如下图所示:

动画.gif

这和 GBN 不同的是,会在接收方标记出哪个分组没有被正常响应,等到计时器到时时会选择重新发送一个。

文章到这里的时候也就说明了可靠数据传输原理也就讲完了。

参考文献

  • 书籍: 计算机网络自顶向下方法原书第七版;