可靠数据传输依靠数据在一条可靠信道上进行传输。
TCP也正是依靠可靠信道进行传数据,从而数据不会被丢失。
而实现这种可靠数据传输服务是可靠数据传输协议的责任
在协议rdt1.0下,底层信道是完全可靠的。
上图是rdt1.0发送方和接收方的有限状态机的定义。
rdt2.0的底层信道是不可靠的,在该信道下分组中的比特可能会受损。
考虑一下你自己是怎样通过电话口述一条长报文的。在通常情况下,报文接收者在 听到、理解并
记下每句话后可能会说“0K” 。如果报文接收者听到一句含糊不清的话时, 他可能要求你重复那句容
易误解的话。这种口述报文协议使用了肯定确认("OK”)与否定确认("请重复一遍)。这些 控制报文使
得接收方可以让发送方知道哪些内容被正确接收,哪些内容接收有误并因此需 要重复。在计算机
网络环境中,基于这样重传机制的可靠数据传输协议称为自动重传请求 (Automatic Repeat
reQuest, ARQ)协议。
ARQ协议还需要另外三种协议功能来处理比特差错的情况。
1.差错检测。需要一种机制以使接收方检测到何时出现了比特差错。
2.接收方反馈。因为发送方和接收方通常在不同端系统上执行,可能相隔数千英里,发送方要了解接收方的情况(此时分组是否被正确接收)的唯一途径就是让接收方提供明确的反馈信息给发送方。
3.重传。接收方收到有差错的分组时,发送方将重传该分组文。
在rdt2.0下,发送方有两个状态。
最左边的状态发送端协议正等待来自上层传下来的数据。
最右边的状态发送端协议等待接收一个ACK/NAK分组。
如果接受到ACK代表,分组已经被正确接收,此时关闭该状态,重新变为最左边的状态,对于这种行为,我们也称之为“停等”。
而接收方仍然只有一种状态,并且只会回答ACK/NAK(正确/错误),这取决于分组是否受损。
尽管如此,rdt2.0仍然存在很大问题,因为ACK或者NAK在返回的时候,也有可能受损!!!
下面考虑处理ACK和NAK时受损的三种可能性:
1.接收方可能并不能理解会大方的ACK和NACK是什么意思,显然这不可能
2.增加足够多的检验和比特,使发送方不仅可以检测差错,还可恢复差错。
对于会产生差错但不丢失分组的信道,这就可以直接解决问题。
3.第三种方法是重发分组,然而这种方法会向信道中引入亢余分组。
对于这些可能性,其实有一个简单方法(几乎所有现有的数据传输协议中,包括TCP、都采用了这种方法)是在数据分组中添加一个新字段,让发送方对其数据分组编号,即将发送数据分组的序号放在该字段。
于是,接收方只需要检查序号即可确定接收到的分组是否一次重传。
下面是rdt2.1的FSM描述,是rdt2.0的修订版,rdt2.1的发送方和接收方FSM的状态数都是以前的两倍。这是因为协议状态必须反映出目前(由发送方)正发送的分组或(在接收方)希望接受的分组序号是0还是1。
以上是rdt2.1发送方
以上是rdt2.1接收方。
现在我们界定除了比特受损外,底层信道还会丢包。
一个处理这个问题的方法是:“重传”。
在发送方发送完一个分组后,如果长时间没有接收到ACK,则会自动重传。
问题关键在于,等待的时间该如何确定?
注意到,如果一个分组经历了特别大的时延,但是没有丢失,发送方仍然会重传一个分组,这就造成了亢余数据分组的问题,幸运的是,rdt2.2协议已经能处理亢余分组情况了。
因此为了实现时间的重传机制,需要一个倒计数定时器。
在一个给定的时间量过期后,可中断发送方。
因此,发送方需要做到:
1.每次发送一个分组时,便启动一个定时器。
2.响应定时器中断。
3.终止定时器。
下图给出了rdt3.0的发送方FSM。
下面是rdt3.0在运行过程中四种协议运作的情况:
(rdt3.0有时被称为比特交替协议)
上图中的括号代表计时器建立时间以及终止时间。
rdt3.0是一个共功能正确的协议,但是rdt3.0作为一个停等协议,会严重造成性能浪费!
为此,一种不以停等方式工作的协议诞生了,被称为:“流水线”。
流水线协议不以停等方式运行,允许发送方发送多个分组而无需等待确认,如下图所示:
但流水线技术也带来了下面三个影响:
1.必须增加序号范围,因为每个输送中的分组必须有一个唯一的序号。
2.协议的发送方和接收方两端也许不得不缓存多个分组。发送方最低限度应当能缓冲那些已发送但没有被确认的分组。
3.所需序号范围和对缓冲的要求取决于数据传输协议如果处理丢失、损坏及延时过大的分组。
解决流水线的差错恢复有两种基本方法是:
回退N步(GBN)和选择重传(SR)。
允许发送方发送多个分组而不需等待确认,但也受限于在流水线中未确认的分组数不能超过某个最大允许数N。
下图是一个发送方看到的GBN协议的序号范围:
其中我们将基序号(base)定义为最早未确认分组的序号,将下一个序号(nextseqnum)定义为
最小未使用的序号,即下一个待发分组的序号。
则可以将上面的序号范围分割成四段,在[0,base-1]段内的序号已经发送,在[base,
nextseqnum-1]为已发送但是未接收到响应的分组,在[nextseqnum,base+N-1]段内的序号是马上
要被立刻发送出的分组,大于base+N-1的序号是不能使用。
因此,这个序号范围可以被看作是一个长度为N的窗口。
通常随着协议的运行,该窗口会向前滑动,而N常被称为窗口长度。
GBN协议也被常常称为滑动窗口协议。
该窗口也可以想象为一个队列,不断地进出元素(未发送的分组序号/已发送且收到回应的分组序号)。
下图为GBN的扩展FSM图:
除此之外,GBN发送方必须响应三种类型的事件:
1.上层的调用。当上层调用时,发送方检查发送窗口是否已满,若未满则产生一个分组并将其发送,并更新变量(base、nextseqnum)。若窗口已满,发送方则隐式的告诉上层该窗口已满。
2.收到一个ACK。在GBN协议中,对序号为n的分组的确认采取累积确认的方式,表明接收方已正确接收到一个窗口容量的分组。
3.超时事件。若出现超时,发送方重传所有已发送但还未被确认过的分组。
而接收方的动作也很简单,如果一个序号为n的分组被正确的接收到,并且按序接收到(即上次交付的分组序号为n-1),则接收方为分组n发送一个ACK。
其它所有情况下,接收方会丢弃该分组。
在上面所说的GBN协议潜在地允许发送方用多个分组"填充流水线",因此避免了停等协议中所提到
的信道利用率的问题。但是GBN本身也有一些情况存在着性能问题,尤其是当窗口长度和宽带时
延积都很大时,在流水线中会有很多分组处于重传状态。这会导致接收到的数据很断断续续的,严
重影响使用感。
而选择重传(SR)只会选择性的重传它觉得可能出错或出错的位置,具体的原理是,当发现出错
后,接收方会缓存出错序号的所有分组,直到该分组之前的正确分组被传送过来,这一批分组才会
按照次序被传送给上层。
当我们面对有限序号范围的现实时,发送方和接收方窗口间缺乏同步会产生严重的后果。
下面两个例子都代表了接收方无法区别新传来的分组是上一次传输的重传副本还是新一次传来分组的起始。
下面我们来看一个对于该节知识点的一个总回顾图片。