关于各种运输层的可靠传输协议

可靠传输协议


相信大家在学习计算机网络时,学到可靠传输协议这里会有一点乱,我把这几天所学的知识整理如下,希望对大家有所帮助。

全文基于对计算机网络有一定基础的人学习,文章中很多地方讲的不是很全很细,倘若要系统性学习,还是建议阅读《计算机网络自顶向下方法》原书。

一对一窗口传输

好像这个协议没有一个官方的名字,我们暂且称其为一对一窗口传输协议吧。所谓的一对一窗口也就是 发送窗口和接收窗口都只有一个,每次只能发送一个。
然后我们来看看如何简单停等协议也是有好几个阶段的发展的。

rdt1.0

最开始的情况我们假设信道是完全可靠的,不会出现丢包等情况,所以最简单的方案就是 发送方 发送数据包,如果接收方接收到完整的数据包,就发送ACK,如果发送的数据包是出现了某些差错的,就发送NAK。

所以这就是最简单的确定-否定模式。

rdt 2.0 也称为停等协议

后面发现虽然不会发现丢包等问题,但是如果接收方发送的NAK或者ACK在发送过来的时候出现了差错,发送方怎么处理。这就产生了rdt2.0版本。如果发送方接收到含糊不清的ACK或者NAK时,就简单重发分组。

然后就发现又出现一个问题,因为对于接收方来说,它又接收了一个新的包,它并不知道这个包是重发的,还是新的数据包。如果是新的包,那么它可以接收,如果是旧的包,它收了就会产生冗余分组。

那么很简单的,我们对要发的包编码,如果是发一个新的包,就+1,在单窗口发送的情况下,就是新的包为1,重发的包为0.

如果出现冗余的就直接丢弃。

但是这样还是会出现问题,就是如果是ACK或者NAK丢失了。
那么发送方重新发送一个数据包,接收方接收之后发送是冗余直接丢弃不做其它操作,这样发送方还是没收到任何ACK或者NAK,它就会一直发送数据包。

可见这种方式还是需要改进,所以就有了rdt2.1

rdt 2.1

如果一开始发的包编号是0,重发的包就还是0,新发的包就为1.

这样接收方接收到数据包时:

  1. 如果发现是冗余的,那么就丢弃,但还是要发一个ACK,这样发送方就知道了对方是接收到,可以发送下一个分组。
  2. 如果是受损的,那么就丢弃,发送一个NAK。

在这里的ACK和NAK都还不用编号,因为此时假设信道上不丢失分组,发送方知道所接收的ACK和NAK分组是对最近发送分组的响应。

rdt2.2

进一步改进,接收方无论接收到冗余还是受损的,都不发送NAK,都直接发送ACK.但是这时需要对ACK进行编号。

如果上一个发送了数据包0,此时发送数据包1.
如果接收方接收到的是冗余分组,就发送ACK1,发送方就知道正确接收到数据包1.
如果接收方接收的是受损分组,就发送上一个确认的ACK,也就是发送ACK0,发送方就知道接收方只接收到上一个数据包0。

rdt3.0

上面的方案看起来都天衣无缝,天真无邪,但是实际上的计算机网络并不是小孩子在过家家,并没有那么多理想的情况。比如网络中就是会出现丢包的问题。

那么如果出现丢包了怎么办?如果按照rdt1.0,rdt2.0,发送方都是会收到ACK或NAK的(只是有没有损坏而已)。但是现在网络上会出现丢包问题,如果在rdt1.0和rdt2.0中,这个问题好像是无解的。

所以就推出了rdt3.0.

就是发送方在发送出数据包之后就启动定时,如果在计时器内没有收到ACK或NAK的话,那么发送方就重新发送。

这样无论是发送的数据包丢失了还是ACK/NAK丢包了,发送方在一定时间内收不到都会启动重传机制。

总结一下:一对一窗口协议的发展

  1. rdt1.0: ACK和NAK 确认与否认。
  2. rdt2.0:收到受损ACK或NAK,就重发分组。同时对分组编号,以便发送方能确认是否为冗余分组。(若冗余则直接丢弃。但是没有给发送方反馈)
  3. rdt2.1:在2.0基础上,接收方收到冗余分组就发送ACK,收到受损分组就发送NAK。
  4. rdt2.2: 在2.1基础上,接收方收到冗余分组就发送对该包的ACK,收到受损分组就发送对前一个确认的包的ACK。
  5. rdt3.0 在前面的基础上,加了一个计时器,在一定时间内没收到分组就启动重传。

实现方式:检验和,序号,定时器,肯定与否定

直观上感受,也能发现停等协议的效率很低。
举个生活中的小例子:
假设你从广州要送货物送到北京,每次来回要1天,而你每次只送一箱,送完一箱后要等到从北京送回来的ACK或者NAK之后你才能继续发送。是不是效率很低。

在计算机网络中,表示此利用率的公式是(L/R )/(RTT+L/R) 其中RTT是往返时延,L/R是将一个分组发送出去所需要的时间。

那么我们很容易想到,要怎么让其效率增高呢?在不改变链路速度和链路距离的情况下,我们每次送的货物多一点,是不是效率会相应地提高。

所以就有了下面的流水线可靠传输协议。

流水线可靠传输协议

  1. GBN 回退N帧协议
  2. SR选择重传协议
  3. TCP可靠传输协议

GBN 回退N帧协议

说白了,就是发送窗口有n个,而接收窗口只有1个。

比如发送窗口有10个,(可以一次性发送序号1到10的分组),但是接收窗口只有一个。

接收方:
对于接收方来说,一定要收到按序到达的分组,接收窗口才会向前移动,同时向发送方发送ACK。

比如发送方发送了一到10,1按序到达了,接收方接收了1,然后就发送ACK1,(表示希望接收序号为1后面的数据)同时接收窗口向前移动到2。

假设此时序号为2的包丢失了,而序号为3,为4,为5的包到达,都没用。对接收方来说,没有接收到2(按序到达的),它就持续发送ACK1,ACK1,ACK1.

另外,还有一个累积重传协议,也就是如何有序接收了分组1,分组2,分组3.那么倘若ACK1丢了也没问题,发送方接收到ACK3 就可以知道前面3个分组都有序到达了。

发送方
对于发送方来说,还是前面那个例子,假设发送窗口为10,发送方一次性发送了序号1到10的包。
然后现在发送窗口就用完了,此时如果接收到ACK1,那么发送窗口就可以往前移动一位。

此时窗口的前沿就移动到序号为2的分组上,此时需要接收到ACK2,否则窗口就不会继续往前移动。

如果在计时器内还没有收到的话,那么就重发窗口内已经发送但是还没有收到确认的分组(比如在该例子里是分组2到分组10)

注意这里有一个和选择重传SR要区分的点 就是定时器的设置:

  1. GBN的发送方只需要设置一个定时器,它可以是最早的已发送但未被确认的分组所使用的。比如上面的例子,原本定时器在序号1上,后面窗口前沿变为2,此时序号为2的分组就重新启动一个计时器)
  2. 而SR需要每个分组都有一个计时器,因为GBN一次性是重发所有分组,而SR只重发未收到ACK的分组。(待会细讲)

为什么叫回退N帧,从上面的例子就可以看出来,分组2丢失了,从2到9全部都得重发,回退N帧。

SR 选择重传

SR在GBN的基础上加以优化,也就是发送窗口和接收窗口都有N个。

接收方
不用按序接收,比如前面的例子,还是发送1到10,分组2,分组6丢了。其它分组到达了。
此时接收方会发送ACK1,ACK3-ACK5,ACK7-ACK10.

发送方
发送方在收到ACK1后,窗口前沿会移动到序号2.
而且在收到此时ACK时,会标记已经接收到ACK的分组。
此时如果分组2的定时器超时了,那么就得重发

此时如果重发分组2并收到ACK2,那么滑动窗口就会一直向前移动到序号6,因为6还没收到ACK。

此时如果序号6的定时器也超时了,就会重新发送分组6.

当然,这个例子也可以是分组6的计时器先超时,然后先重发分组6.

所以这就是前面说的每个分组都必须有自己的逻辑定时器。

上一篇:老生常谈:面试必问“三次握手,四次挥手”这么讲,保证你忘不了


下一篇:tcp_delay_ack与negle算法分析