篇首语:回退N步(GBN)和选择重传(SR)是解决流水线的差错恢复的两种基本方法。
本篇我们先来看看GBN。
首先我们了解滑动窗口的概念:滑动窗口的作用是控制流量,它可以存在于接收端和发送端。以发送窗口为例,其基本原理就是在任意时刻,发送方都维持了一个连续的允许发送的帧的序号。不同的滑动窗口协议窗口大小一般不同。发送方窗口内的序列号代表了那些已被发送但还未被确认的帧和未被发送但可用于发送的帧。(注:发送窗口和接收窗口的序号的上下界甚至大小不一定要一样)同时我们规定滑动窗口的首个序号,即最早未确认的分组,为base序号,而规定最早的未被发送但可用于发送的序号为nextseqnum序号(nextsequm-base<=N)。
现在再来看回退N步。我们将各个分组编号,设滑动窗口大小为N。发送方一次传输N个分组过去,当接收方接受到其中一个分组,接收方会判断分组序号是否为上一个已确认分组的序号+1。是的话,接收方返回ACK给发送端并提交分组给上一层。发送端收到ACK后,再比较是否和其base序号相同,相同则滑动窗口向后移动一位。
上述中出现了两次是否判断,分别在接收方和发送方。现在我们看看如果出现否的情况。
1.如果接收方接受到的分组不是比提交的分组大1(或根本没接收到什么分组),说明在该分组之前的分组遗失了,于是接收方会丢弃该分组,也不返回对应的ACK。发送方长时间接受不到所需ACK,会导致其定时器超时。
2.如果发送方收到的ACK序号与其base不同,说明在其之前的ACK遗失了,但滑动窗口依旧会滑动,不用重传,因为一旦收到了某序号的ACK,说明在此之前的分组接收方都已确认接收。
但如果发送方没接受到此后任何的ACK,导致超时,则会引起重传,比如这种情况会发生在整个传输中的最后一个分组身上。
而上述两者情况一旦引起定时器超时,最终造成的反应方都是发送方,即发送方重新发送分组(从滑动窗口中最早未确认的分组开始)。(重传是保证可靠数据传输的灵丹妙药)
那么定时器有是什么东西呢?首先我们明确一下GBN只有一个定时器,这个定时器计时的对象始终是发送方滑动窗口的base,当base+1,定时器就会刷新计时。(注:定时器的启动和结束的判断依据都是base == nextseqnum)
以上就是GBN的运行基本原理。
我们可以看到,一旦出现错误,接收方会丢弃所有失序的分组,而发送方则会从滑动窗口中的第一个未确认的(base)分组开始重传。值得肯定的是,这种方法对接收方是十分友好的,他不要求接受方缓存任何失序的分组,而是靠发送方维护滑动窗口(上下界和nextseqnum的位置)来保障数据的可靠传输。但缺点也是十分明显的,一旦某个分组(或)丢失,则可能导致同一个窗口发送过来的分组都会被丢弃,这样不仅了网络的浪费,同时不必要的重传也会增大出错率,所以,如果信道传输质量很差,导致误码率较大时,后退N帧协议不一定优于停止-等待协议。
这里建议大家看看一个java小程序,来实操一下GBN的过程,可能还会发现其他意外情况。
错误之处,还望指出。