计算机网络 滑动窗口协议

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34037046/article/details/78303741
(i)  1位滑动窗口协议
在7.4.1节介绍的协议都假定数据帧沿着一个方向传输,但事实上大多数的通信都是双向的。当双方都有数据发送时,将确认序号携带在数据帧中传输可以减少开销,这称为捎带应答(Piggybacking)。捎带应答带来的一个问题是:当需要发送确认时没有要发送的数据帧怎么办?这可以让确认信息推迟一点时间再发送,如果仍然没有数据帧要发送,再用一个单独的帧进行确认。本节及后面两节将要介绍的三个协议都是用于双向数据传输的协议,且都属于滑动窗口协议,但它们的效率、复杂度及对内存的需求都不同。
1位滑动窗口协议使用"停-等"方式,所以只需要1比特长的帧序号。由于支持双向传输,所以每个协议实体需要同时完成发送和接收两个功能,过程如下。
(1)初始化发送序号和期待接收的帧序号:next_frame_to_send = 0,frame_expected = 0(next_frame_to_send指明发送方正在发送的哪一帧,而frame_expected则指明了接收方正在等待的哪一帧,在1位滑动窗口协议中,这两个值只能是"0"或者"1");
(2)从网络层接收一个分组,放入缓冲区;
(3)从缓冲区中取出分组构造一个帧,它又分为以下三个小步骤。
将缓冲区中的分组拷入帧的信息域;
将next_frame_to_send拷入发送序号域;
将1- frame_expected(第一个期待的帧)拷入确认序号域。
(4)对最近收到的帧确认。
(5)将帧传给物理层,同时启动相关的计时器;
(6)等待事件发生(帧到达,收到坏帧,超时);
(7)如果发生的事件为帧到达,则从物理层接收一个帧,首先检查帧的seq域,若正是期待接收的帧(seq = frame_expected),则将帧中携带的分组交给网络层,frame_expected加1;然后检查帧的ack域,若正是等待确认的帧(ack = next_frame_to_send),终止相关的计时器,从网络层接收一个新的分组放入缓冲区,next_frame_to_send加1,继续执行下一步。如果发生的是其他事件(收到坏帧,超时),则也继续进行下一步。
(8)用缓冲区中的数据分组、next_frame_to_send和1- frame_expected构造一个帧,传给物理层,同时也启动计时器,返回到步骤(6)。以后就重复继续执行这样的循环。

在这种1位滑动窗口协议中,在正常情况下,发送方和接收方是交替发送的;但当发送方和接收方同时向对方发送或超时设置得太短时,会造成不必要的重发,但协议也能够正常运行。


(ii) GO-BACK-N协议的窗口机制
在前面已介绍了GO-BACK-N协议,在此继续介绍这一协议中的窗口机制。
直到现在,我们一直假定信号的传播延迟可以忽略不计,但事实上有些时候是不能忽略的,比如在卫星信道上,如果信道的数据速率为b bit/s,帧的长度为l bit,信号的来回延迟为R秒,则线路的效率为l/(l+bR)。如果我们在等待确认的时候多发送一些帧,就可以提高线路的效率,这事实上允许发送窗口包含多个未被确认的帧,这种技术称为"管道化"(Pipelining)。当信号传播延迟远大于帧的传输时间时,适合采用这个技术。
当管道化技术建立在不可靠的信道上时会有一些问题。比如,如果位于帧流中的某个帧丢失或损坏了,另外在发送进程发现出错前,大量的后继帧会到达接收方;也可能当一个坏帧到达接收方时,显然会被接收方丢弃,这些又如何处理呢?
有两种基本的方法来处理以上问题:(1)称之为"GO-BACK-N"协议,接收进程丢弃所有的后继帧,并且不通知发送进程。该策略对应接收窗口为1的情况,即只能按顺序接收帧,当发送进程超时后,必须按顺序重传所有未被确认的帧。如果错误率高的话,这种方法会浪费很多带宽,但对内存需求不大。(2)称之为"选择重传"(对应接收窗口大于1的情况),只要是落入接收窗口且校验正确的帧,都要接收下来放到缓冲区里,这样当发送进程意识到某个帧出错时,只是重传此帧而不是所有的后继帧。选择重传通常使用NAK对校验出错或疑为丢失的帧进行确认,以便发送进程尽快重传该帧。如果第二次重传成功,接收方的数据链路层中会有许多按顺序排列的正确帧,这些帧可以一起交给网络层,并只对最高序号的帧进行确认。当窗口很大时,这种方法需要大量的数据链路层内存,但它不浪费带宽。
GO-BACK-N的过程如下。
(1)初始化。
开网络层允许;
ack_expected = 0(此时处于发送窗口的下沿);
next_frame_to_send = 0,frame_expected = 0(初始化正在发送的帧和期待的帧序号);
nbuffered = 0(进行发送窗口大小初始化);
(2)等待事件发生(网络层准备好,帧到达,收到坏帧,超时)。
(3)如果事件为网络层准备好,则执行以下步骤。
从网络层接收一个分组,放入相应的缓冲区;
发送窗口大小加1;
使用缓冲区中的数据分组、next_frame_to_send和frame_expected构造帧,继续发送;
next_frame_to_send加1;
跳转(7);
(4)如果事件为帧到达,则从物理层接收一个帧,则执行以下步骤。
首先检查帧的seq域,若正是期待接收的帧(seq = frame_expected),将帧中携带的分组交给网络层,frame_expected加1;
然后检查帧的ack域,若ack落于发送窗口内,表明该序号及其之前所有序号的帧均已正确收到,因此终止这些帧的计时器,修改发送窗口大小及发送窗口下沿值将这些帧去掉,继续执行步骤(7);
(5)如果事件是收到坏帧,继续执行步骤(7)。
(6)如果事件是超时,即:next_frame_to_send = ack_expected,从发生超时的帧开始重发发送窗口内的所有帧,然后继续执行步骤(7)。
(7)若发送窗口大小小于所允许的最大值(MAX-SEQ),则可继续向网络层发送,否则则暂停继续向网络层发送,同时返回互步骤(2)等待。
注:在这个协议中有一个问题,没有考虑到当某个方向上没有数据要发送时,要对收到的帧进行单独确认。在收到期待的帧后应该启动一个ACK超时计时器,当发生超时事件时,判断哪个计时器超时,若是ACK计时器超时,应该单独发送一个确认帧。而当发送了一个数据包时,应将被捎带确认的帧的ACK计时器终止。另外,在使用GO-BACK-N协议时,发送窗口的大小不能超过2n-1。


(iii) 选择性重传协议的窗口机制
同样,在前面我们已介绍了选择性重传协议,在此继续介绍这一协议中的窗口机制。
在该协议中,发送方的窗口大小从0开始增长到某个预定的最大值,而接收方的窗口总是保持固定大小的,并等于该最大值。接收窗口内的每个序号都有一个缓冲区,并有一位指示缓冲区是空还是满。当一个帧到达时,只要其序号落在接收窗口内,且此前并未收到过(相应缓冲区为空),就接收此帧,并存于相应的缓冲区中;仅当序号比它小的所有帧都已递交给了网络层,此帧才会被提交给网络层。使用选择重发协议,发送窗口也不能大于2n-1。
具体的选择重发过程可以描述如下:
(1)初始化:类似GO-BACK-N的初始化,但增加了与接收窗口相关的内容,如设定接收窗口的大小、清空缓冲区满标志等。
(2)等待事件发生(帧到达,收到坏帧,数据帧超时,网络层准备好,ACK超时)。
(3)如果发生的事件为网络层准备好,则从网络层接收一个分组,组帧发送,修改相关参数,与GO-BACK-N的处理方法相同,继续执行步骤(6)。
(4)如果事件为帧到达,则从物理层接收一个帧,若为数据帧,且不是期待接收、未发送过NAK(不应答)的帧,则发送一个NAK帧,要求重发指定序号的帧(Frame_expected);否则启动ACK计时器;若收到的帧落在接收窗口内,且此前未收到过,则放入相应缓冲区并设置缓冲区满标志;若接收窗口下沿帧已经到达,则从该帧开始将连续的若干个帧交给网络层,并修改相应参数(缓冲区满标志,接收窗口范围),启动ACK计时器。
若为NAK帧,且请求重发的帧落在当前的发送窗口内,则重发这个帧。若从发送窗口下沿开始连续的若干个帧已被确认,则终止这些帧的计时器,修改发送窗口大小及发送窗口下沿值将这些帧去掉;继续执行下一步。
(5)如果发生的事件为收到坏帧,则在尚未发送过NAK时,发送一个NAK,继续执行步骤(6);如果发生的事件为超时(数据帧超时),重发超时的帧,也继续执行步骤(6);如果事件为ACK超时,为指定的帧发送单独的确认帧,同样继续执行步骤(6)。
(6)若发送窗口大小小于所允许的最大值(NR_BUFS),则允许继续向网络层发送帧,否则暂停向网络层继续发送帧,返回到步骤(2),继续等待

猜你喜欢

转载自blog.csdn.net/qq_34037046/article/details/78303741
今日推荐