计算机网络 (4) 数据链路层-可靠传输

259 阅读9分钟

本文引用代码及图片均来自 高军: 计算机网络

数据链路层主要解决主机编址以及数据分组的格式问题,使得数据可以在一个网络内流动

链路层涉及以下三个重要概念:

  1. 封装成帧
  2. 差错检测
  3. 可靠传输

本文介绍第三部分:可靠传输

可靠传输

如果链路层提供的是不可靠传输服务,那么在帧出现误码时链路层直接把帧丢弃,其他什么也不做。如果提供的是可靠传输服务,那么链路层要想办法实现发送方发送什么它就收到什么

值得一提的是,可靠传输并不是链路层特有的概念,它贯穿整个计算机网络体系。在 计算机网络 (3) 数据链路层-封装成帧、差错检测 中介绍过传输过程中的比特错误,其实传输时还可能遇到分组丢失、分组失序以及分组重复等问题,其中比特错误是链路层的问题,而后面几个都是链路层之上的层级的问题,每一层都可以实现可靠传输

可靠传输主要涉及以下协议(这些协议并不限于链路层):

  1. 停止等待协议
  2. 回退N帧协议
  3. 选择重传协议

停止等待协议

停止等待协议中,发送方每发送一个分组都必须等待接收方的确认分组ACK(Acknowled Character)才能发送下一个分组,如果是否认分组NAK(Negative Acknowledge)则重传上次发送的分组

image.png

超时重传

如果发送方分组丢失,那么接收方就不会发送ACK,此时发送方就会一直等待ACK而不能发送数据。为了避免这种情况,发送方主动设置一个时钟,如果分组发出后超过了一定的时间没有收到ACK就自动重发分组,这称为超时重传,超时时间一般设置为略大于一个分组往返的时间

image.png

分组编号

接收方的确认(否认)分组也是可能丢失的,假设发送方发送了分组并且被接收方接收,接收方的确认分组在传输过程中丢失,那么发送方因为没收到确认分组就会触发超时重传把相同的分组再发送一遍,此时接收方会收到一个重复的分组

为了避免分组重复,发送方需要给每个分组编号,因为发送方每次只发送一个分组就停下来等待,所以发送方只需使用一个比特进行编号就能使分组区分开来

当接收方检查编号发现是重复的分组时就知道上个分组的确认分组丢失了,此时接收方只需丢弃收到的分组并发送ACK即可,发送方收到ACK后也不会再重发分组了

image.png

ACK编号

接收方的ACK也有可能迟到,发送方发送分组0后因为ACK迟到触发超时重传再次发送分组0,再次发送分组0后收到了迟到的ACK然后发送方发送分组1。假设接收方先收到重传的分组0然后发送ACK再收到分组1,但是发送方收到重传的分组0ACK时有可能误认为是分组1ACK。为了避免上述情况,ACK也需要编号以便发送方确认,同样的ACK编号也只需要一个比特

image.png

由以上的种种情况分析,发送方每发送一个分组都需要等待接收方的回应再做下一步,因此停止等待协议信道利用率很低,大多数时间都用来等待了

回退N帧协议

相比较于停止等待协议每次发送分组后都必须等待接受方的确认,回退N帧协议采用流水线方式传输数据——在收到接收方的确认之前可以连续发送多个分组

image.png

从上图可以看出流水线式传输可以很大的提高信道利用率,实际上发送方和接收方都使用滑动窗口来控制每次可发送或接收的分组个数,分别称为WT{W_{T}}WR{W_{R}},本节以WT=5,WR=1{W_{T}} = 5, {W_{R}} = 1为例

理想情况

在理想情况下,接收方将窗口内的0-4号分组依次发送,接收方每次接收一个分组,同时返回ACK分组并将窗口向右滑动

image.png image.png

接收方依次收到0-4号分组的ACK分组并依次将窗口向右滑动,其实,在收到0号分组的ACK分组时窗口向右滑动5号分组落入窗口,这时5号分组就可以发送了不需要等待1-4号ACK分组

image.png

接收方不一定每次接收一个分组后就返回对应的ACK分组,它可以在连续接收了几个分组后只返回对于最后正确接收分组的ACK分组,表示此分组及之前的分组都已正确接收,这称为累计确认

image.png

如上图中接收方在成功接收0号和1号分组后返回对于1号分组的ACK分组,在接收2、3、4号分组后返回对于4号分组的ACK分组,接受方在收到1号ACK分组后就知道0号和1号分组已经被正确接收,4号ACK分组同理

累计确认有一个优点——如果之前的确认分组丢失可能不会导致发送方超时重传。比如上图中1号ACK分组丢失但是4号ACK分组被正确接收,那么发送方也会知道0-4号分组都被正确接收而不重传分组,这里说“可能”是因为发送方的超时重传时间和后面的ACK分组到达时间不确定

传输出错

假设传输过程中接收方通过检查FCS发现5号分组出现误码,此时接收方丢弃5号分组

image.png

对于后续到达的6、7、0、1号分组,由于分组序号和接收方窗口对应的序号不一致接收方不予接收,此时接收方重复返回最后一次正确接收的分组(4号分组)的ACK分组

image.png

发送方收到重复的ACK分组就知道之前发送的分组出现差错,此时不必等待计时器超时就可以直接重传分组

image.png

另外,虽然6、7、0、1号分组都正确到达,但是由于5号分组不被接收导致它们也不会被接收,发送方也需要重传6、7、0、1号分组,这就是所谓的回退N帧

窗口大小限制

在回退N帧协议中WR{W_{R}}固定为1,1<WT<2n11 < {W_{T}} < 2^{n} - 1,其中 n{n} 为用于分组编号的比特数,以 n=3{n} = 3为例,此时应有 1<WT<71 < {W_{T}} < 7,下例中取 7<WT=87 < {W_{T} = 8},看看会出现什么情况

假设接收方成功接收了发送方发送的0-7号分组,此时接收方返回针对7号分组的累计确认ACK分组并且滑动窗口移动到0号位置

image.png

但是7号ACK分组在传输过程中丢失,发送方迟迟收不到ACK分组导致超时重传0-7号分组又发送了一遍。假设接收方正确接收到重传的0-7号分组,由于序号和接收窗口的序号可以对上,那么接收方将无法分辨此次接收的0-7号分组新的分组还是重复的分组

image.png

从以上分析可以知道,如果WT{W_{T}}超出限制,可能导致接收方无法分辨接收的是新分组还是重复分组

协议总结

image.png image.png

选择重传协议

回退N帧协议中,一个分组出现差错就导致其后续的分组无法被接收,发送方需要重传出错的分组及其后的分组,导致通信资源的浪费。选择重传协议就是为了避免多个分组的重传的发生,使得发送方仅需重传出错的分组

为了将出错分组后面的正确分组接收下来,接收方的窗口大小WR{W_{R}}不再设置为1,同时,为了使发送方仅重传出错分组,接收方不再使用累计确认而是对正确接收的分组进行逐一确认

在理想情况下选择重传协议的流程和回退N帧差不多,本节仅讨论分组出错的情况,本节以WR=WT=4{W_{R}} = {W_{T}} = 4为例

传输出错

发送方依次发送0-3号分组,其中2号分组在传输过程中丢失

image.png

接收方正确接收0,1号分组后返回对应的ACK分组并将窗口向右滑动,随后接收3号分组但因为2号分组未接收导致窗口无法向右滑动,接收方接着返回3号分组的ACK分组

image.png

发送方收到0、1号ACK分组,发送窗口向右滑动,4、5号分组落入窗口并被发送。随后接收方收到3号ACK分组但由于未接收2号ACK分组导致窗口无法向右滑动,为避免3号分组超时重传需要打上标记

image.png

接收方收到4、5号分组后仍然无法向右滑动窗口,发送方收到4、5号ACK分组后同样仍然无法滑动窗口,此时4、5号数据也打上标记避免超时重传

image.png

最后2号分组触发超时重传,接收方收到2号分组后就可以将窗口向右滑动。同理,发送方收到2号ACK分组后也能将窗口向右滑动

选择重传协议对于WT{W_{T}}的限制为 1<WT<2n1{1 < W_{T} < 2^{n-1}},如果超过限制会导致和回退N帧协议一样的问题——接收方无法分辨接收的数据是新的分组还是重复分组

协议总结

image.png image.png

参考文献