2.2可靠数据传输原理——流水线可靠运输协议、回退N步、选择重传

概述

可靠数据传输:服务模型与服务实现如下图所示:其中

rdt-send()函数可以调用数据传输协议的发送方,它将要发送的数据交付给位于接收方的较高层(rdt表示可靠数据传输)

rdt_rev()函数可以在接收端接收分组信号

deliever-data()函数可以向较高层交付数据。

udt_send()函数用来将分组发送给对方(udt表示不可靠数据传输)

由上左图可以看到,为上层实体提供的服务抽象是:数据可以通过一条可靠的信道进行传输。借助于可靠信道,传输数据比特就不会受到损坏或丢失,而且所有数据都是按照其发送顺序进行交付。这恰好是TCP向调用它的因特网应用所提供的服务模型。实现这种服务抽象的是可靠数据传输协议。

另外,很现实的一个问题是可靠传输协议的下层协议也许是不可靠的,因此十分困难。比如TCP是在不可靠的(IP)端到端网络层之上实现的可靠数据传输协议。

构造可靠数据传输协议

1.经完全可靠信道的可靠数据传输:rdt1.0

横线上方是引起状态变迁的事件,横线下方是事件发生采取的动作,无事件或状态变化用A表示

简单协议中,有了完全可靠的信道,接收端就不需要提供任何反馈信息给发送方,也不必担心出现差错。

2.经具有比特差错新到的可靠数据传输:rdt2.0

底层信道更为实际的模型是分组中的比特可能受损。但是现在仍然假定所有分组(虽然有些比特可能受损)将按发送顺序被接收

接收端接收到分组后需要使用肯定确认(ACK)否定确认(NAK)让发送方知道 哪些内容被正确接收,哪些内容接受有误,并因此需要重复。基于这样重传机制的可靠数据传输协议称为自动重传请求(ARQ)协议。基本上,ARQ还需要另外三种协议来处理比特差错的情况,分别是:差错检测、接收方反馈、重传

rdt2.0:初步解决了分组中比特受损的问题

 如上图中的发送端所示,发送端发送分组后需要等待接收端反馈,如果接收端反馈为NAK(否定确认)则重新发送分组,否则返回初始状态,等待来自上层的调用。接收端对接收到的数据进行差错检测,如果没有问题则将数据交给较高层,并向发送端反馈ACK,否则返回NAK。

注意:发送方在处于等待ACK或NAK状态时,不能从上层接收到更多数据,仅当接收到ACK离开该状态时这种情况才能发生,因此发送方将不会发送新数据,除非发送方确信接收方已经正确接收当前分组。因此rdt2.0也被称为停等协议。

rdt2.1:通过在发送方数据分组中添加0,1序号解决ACK、NAK比特受损问题

 由上图可以看到,发送端发送序号为0的数据分组,进入等待ACK或NAK状态,当接收到的是NAK或两次ACK时说明数据没有被正确送达,则重新发送数据,否则发送端进入等待来自上层的调用状态,并准备发送序号为1的数据分组。接收端对接收到分组进行差错检查,如果分组受损,接收方将发送NAK,如果不发送NAK而是对上次正确接收的分组发送一个ACK,也能实现与NAK一样的效果。

rdt2.2 在rdt2.1基础上实现的无NAK的可靠数据传输协议

rdt2.2和rdt2.1的细微变化是,接收方此时必须包含由一个ACK报文所确定的分组序号(这可以通过在接收方make_pkt()中包含参数ACK 0或ACK 1来实现)发送方必须检查接收到的ACK报文中被确认的分许序号(这可以在发送方中的isACK()包含参数0或1来实现)

3.经具有比特差错的丢包信道的可靠数据传输:rdt3.0

问题:怎样检测丢包以及丢包后该做些什么

rdt2.2实现了检测丢包,因此需要增加基于时间机制的发送方重传。

为了实现基于时间的重传机制,需要一个倒计数计时器,在一个给定的时间的量过期后,可中断发送方。因此,发送方需要能做到:(1)每次发送一个分组(包括第一次分组和重传分组)时,便启动一个定时器。(2)响应定时器中断(采取适当的动作)(3)终止定时器

现在我们归纳下数据传输协议的要点。在检验和、序号、定时器、肯定和否定确认分组技术中,每种机制都在协议中起到了必不可少的作用,至此,我们得到了一个可靠数据传输协议。

流水线可靠数据传输协议

rdt3.0是一个功能正确的协议,但是性能却十分不理想,核心问题在于它是一个停等协议。

 通过对比上图的停等操作和流水线操作可以明显的看出停等操作对于发送发的利用率很低,导致性能也很低。解决这种问题的一个方法就是:不是用停等方式运行,允许发送方可以在等待确认之前发送多个报文。因为很多从发送方向接收方输送的分组可以被看成是填充到一条流水线中,多以称为流水线可靠数据传输

流水线技术对可靠数据传输谢易可带来如下影响:

  • 1.必须增加序号范围,因为每个输送中的分组(不计算重传的)必须有一个唯一的序号,而且也许有多个在输送中未确认的报文
  • 2.协议的发送方和接收方两端也许必须缓存多个分组。发送方最低限度应当能够缓冲那些已发送但没有确认的分组、
  • 3.所需序号范围和对缓冲的要求取决于数据传输协议如何处理丢失、损坏及延时过大的分组。解决流水线差错恢复有两种基本的方法是:回退N步选择重传

回退N步(GBN)

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

下图为发送方看到的GBN协议的序号范围。其中基序号为最早的未确认分组的序号,下一个序号定义为最小的未使用序号(即下一歌待发分组的序号),则可将序号范围分割成4段。

[0,base-1]段内的序号对应于已经发送并被确认的分组。

[base,nextseqnum-1]段内对应已经发送但未被确认的分组

[nextseqnum,base+N-1]段内的序号能用于那些要被立即发送的分组,如果有数据来自上层的话

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

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

GBN发送方必须响应三种类型的时间:

  • 1.上层的调用。当上层调用rdt_send()时,发送方首先检查发送窗口是否已满,即是否有N个已发送但未被确认的分组。如果窗口未满,则产生一个分组并将其发送,并相应地更新变量。如果窗口已满,发送方将数据返回上层,隐式地指示上层该窗口已满。
  • 2.收到一个ACK。在GBN协议中,对序号为n的分组的确认采用累积确认的方式,表明接收方已正确接收到序号为n的以前且包括n在内的所有分组。
  • 3.超时事件。就像在停等协议中那样,定时器将再次用于恢复数据或确认分组的丢失。如果出现超时,发送方重传所有已发送但未被确认的分组。

GBN接收方的动作也很简单。如果一个序号为n的分组被正确接收到,并且按序,则接收方为分组n发送一个ACK,并将该分组中的数据部分交付到上层。在其他所有情况下,接收方丢弃分组,并为最近按需接收的分组重新发送ACK。 因此使用累积确认是GBN一个自然地选择。

下图为窗口长度为四个分组的GBN协议的运行情况:

选择重传(SR)

从上面可以看到,GBN协议潜在地允许发送方用多个分组“填充流水线”,因此避免了停等协议中所提到的信道利用率问题。然而,GBN本身也存在着性能问题。单个分组的差错就能引起GBN重传大量分组。许多分组根本没有必要重传。

选择重传(SR)协议通过让发送方仅重传那些它怀疑在接收方出错(即丢失或受损)的分组而避免了不必要的重传

下图为SR的操作: 注意与GBN不同的是在接收方缓存分组。

 

 但是,SR协议有一个重要的方面,就是对于哪些分组已经被正确接收,哪些没有,发送方和接收方并不总是看到相同的结果。即发送方和接收方得窗口并不总是一致,例如下面的两种情况对于接收方而言是等同的:接收方就无法确认是第一个分组的重传还是第5个分组的初次传输。

 

注意:对于SR协议而言,窗口长度必须小于或等于序号空间大小的一半。 原因:

首先,发送窗口不能比接收窗口大,不然接收窗口可能会溢出

其次,要最大化发送窗口的流水线分组,但是要保证不能产生二义性。假设序号最大为7即0,1,2,3,4,5,6,7,发送窗口大小为5,当发送窗口发送0,1,2,3,4后,假设接收窗口全部收到,则接收窗口向前移动到5次,接受窗口期望接收5,6,7,0,1.若发送窗口并没接收到任何ACK,所以发送窗口重发0,1,2,3,4此时接收窗口会以为重发的0,1是新的分组。

因为发送窗口<=接收窗口。要最大化发送窗口,则发送窗口=接收窗口。假设发送窗口为m,则接收窗口也为m.发送窗口发送m个分组时,接收窗口向前移动m,接收窗口为m+1,m+2,...2m.要避免二义性,必须满足2m<=序号最大值

  总结

可靠数据传输机制及其用途的总结:

 

猜你喜欢

转载自blog.csdn.net/weixin_39722922/article/details/88390098