数据链路层要实现可靠传输,必须解决一个根本问题:物理信道会出错,帧在传输过程中可能丢失、损坏或乱序。发送方把数据交给接收方之后,如何保证接收方最终拿到的是完整且正确的数据?解决这个问题的核心机制,就是自动重传请求,也就是ARQ。
ARQ是Automatic Repeat reQuest的缩写,中文译为自动重传请求,它是差错控制的两大基本方法之一。差错控制的另一大类是前向纠错,简称FEC。两者最大的区别在于纠错责任由谁承担:FEC靠接收方自己纠错,发送方在编码时加入大量冗余校验位,接收方利用这些冗余信息在解码时直接恢复出错的数据,不需要发送方参与;而ARQ把纠错的责任交还给发送方,接收方只负责检测错误,一旦发现帧有错或者丢失,就向发送方发回一个反馈,请求发送方把这一帧重新传一遍,直到正确接收为止。
从软考命题的角度看,考生首先要分清这两类差错控制的边界。FEC常见于海明码、卷积码、RS码等纠错码,适合单向信道、实时性要求高、无法等待重传的场景;ARQ则需要一条双向信道,因为接收方必须能够把确认信息或者否认信息反馈给发送方,适合误码率可控、允许一定传输延迟的场景。软考网络工程师考试重点考查的是ARQ这一类,因为它在数据链路层的实际协议中应用最为广泛。
值得强调的是,ARQ中的自动两个字,点明了整个机制的运行方式不需要人工干预:发送方发出帧之后,接收方的反馈、发送方的判断、重传的触发,全部由协议本身根据事先约定好的规则自动完成。这种自动化的背后,依赖的是三个相互配合的支撑条件。第一,帧必须带有序号,用于区分新帧与重传帧,避免接收方把重复数据交给上层;第二,必须有一套确认机制,接收方通过回送确认帧或否认帧来告诉发送方传输结果;第三,发送方必须设置超时定时器,防止确认帧丢失时陷入无限等待。这三个支撑条件,是理解一切ARQ变体的共同基础,无论协议如何演化,都逃不出序号、确认、超时这三根支柱。
在正式教材和标准文档中,ARQ协议被划分为三个经典类型,这是软考选择题和案例分析题反复出现的考点。第一种是停止等待协议,也叫停等协议,简写为SW,它的特点是发送方每发出一个数据帧,就停下来等待接收方的确认,收到确认后才能发送下一帧。第二种是回退N帧协议,英文是Go-Back-N,简写为GBN,它的特点是发送方可以连续发送多个帧,不需要每发一帧就等一次确认,但如果某一帧出错,发送方需要把这一帧及其之后所有已发送的帧全部重传。第三种是选择重传协议,英文是Selective Repeat,简写为SR,它的特点是发送方连续发送多个帧,出错时只重传出错的那一帧,其余正确接收的帧不必重传。
从演进逻辑上看,三者的差异归根结底是连续发送能力的差异。停等协议一次只能有一个帧在途,回退N帧允许一个窗口的帧在途,选择重传不仅允许多帧在途,还允许接收方把乱序到达的帧缓存起来。在途帧数量的增加,意味着信道上同时流动的数据变多,信道的空闲时间变少,传输效率自然提升。但这种提升不是免费的,每多允许一个帧在途,协议就要多维护一份序号状态、多占用一块缓存空间、多处理一种乱序可能。理解这三种协议的本质差异,是掌握整个ARQ知识体系的第一块基石。停等协议牺牲效率换简单,回退N帧用多传几帧的代价换取实现的简洁,选择重传用复杂的缓存和编号机制换取最高的重传效率。三者的演进逻辑,本质上是效率与复杂度之间的一连串权衡。
停止等待协议是所有ARQ协议中最简单的一种,它的运行规则可以用一句话概括:发送一帧,等待确认,收到确认再发下一帧。发送方在发出一个数据帧之后,就进入等待状态,同时启动一个超时定时器。接收方收到这一帧后,先做差错校验,如果帧正确无误,就向发送方回送一个确认帧,记为ACK;如果帧出错,就回送一个否认帧,记为NAK,或者干脆不回送任何信息。发送方收到ACK后,确认这一帧已成功交付,于是从缓存中取出下一帧继续发送;如果收到NAK,或者定时器超时还没有收到任何反馈,就重新发送刚才那一帧。
停止等待协议要处理的一个细节,是确认帧丢失的问题。假设发送方发出了数据帧,接收方正确收到并回送了ACK,但这个ACK在传输途中丢失了。发送方等不到确认,定时器超时,于是重传这个数据帧。此时接收方会第二次收到同一个数据帧,它必须能够识别出这是一个重复帧,而不是新的一帧,从而只回送一个确认而不把数据重复交给上层。解决这个问题的办法就是给帧编号,用序号来区分新帧和重传帧。在停等协议中,序号只需要一位,0和1交替使用,就能判断收到的帧是新的还是重复的。这个"一位序号"的细节,恰恰是软考命题人喜欢考查的。
停等协议有一个非常致命的问题,就是信道利用率太低。因为发送方在等待确认的这段时间里,信道是完全空闲的,发送方什么事都不做,白白浪费了宝贵的带宽。信道利用率可以用一个公式来计算:设帧的发送时延为tf,信号从发送方传到接收方再传回来的往返传播时延为2tp,那么停等协议的信道利用率约等于tf除以tf加2tp。这个公式的含义非常直观:在一个发送周期里,真正用来传输数据的时间只有tf那么一小段,其余时间都花在了等待上。当传播时延远远大于发送时延时,信道利用率会急剧下降,这就是停等协议只适合近距离、低速率、传播时延很小的链路的原因。软考经常围绕这个公式出计算题,考生务必把分子分母的含义记清楚。
回退N帧协议引入了滑动窗口机制,让发送方可以连续发送多个帧,不必每发一帧就停下来等待确认。这里的关键概念是发送窗口。发送窗口是发送方允许自己连续发送、但还没有收到确认的帧的序号范围。假设发送窗口大小为W,序列号用n位二进制表示,那么发送方最多可以连续发出W个帧,这W个帧处于已发送但未确认的状态。接收方收到这些帧后,采用累积确认的方式,也就是只对按序到达的最后一个正确帧发确认,这个确认号代表该序号及其之前的所有帧都已经正确接收。
回退N帧协议处理出错帧的方式,就是它名字的由来。假设发送方连续发出了0、1、2、3、4五个帧,接收方正确收到了0和1号帧,但2号帧出错。这时接收方会丢弃2号帧,并且对之后收到的3、4号帧,因为它不是期望收到的序号,也一律丢弃,只对1号帧发出确认。发送方收到对1号帧的确认后,得知2号帧出了问题,于是从2号帧开始,把2、3、4号帧全部重新发送一遍。这就是回退N帧的含义:一旦中间某一帧出错,发送方要退回到出错的那一帧,把它之后的所有帧都重传,即使其中有些帧接收方其实已经正确收到了,也要被丢弃重传。
累积确认是回退N帧协议实现简单、开销低的关键所在。发送方不需要为每一帧单独维护一个确认状态,只需要记住连续正确接收到的最后一帧的序号即可。但这种简单也带来了代价,就是重传的帧数可能比实际出错的帧数多,造成带宽浪费。
选择重传协议在回退N帧的基础上进一步改进,把只重传出错帧作为目标。它的核心变化是接收方不再采用累积确认的简单丢弃策略,而是为每一帧单独维护接收状态。即使中间某一帧出错,接收方也会把后面正确收到的帧先缓存起来,而不是一丢了之。接收方对每一个正确收到的帧都单独发出确认,发送方收到哪个帧的确认,就确认哪个帧已成功交付。
当某一帧出错时,选择重传协议只需要重传这一个出错的帧。延续前面的例子,发送方连续发出0、1、2、3、4五个帧,2号帧出错,3、4号帧正确到达。接收方会把3、4号帧缓存下来,并分别对它们发确认,同时对2号帧发否认或者不发确认。发送方超时后只重传2号帧。接收方收到重传的2号帧后,把它和之前缓存的3、4号帧一起按序交给上层。这样,错误只导致一帧的重传,带宽利用效率最高。
选择重传协议的高效是有代价的,这个代价就是接收方必须设置接收窗口,并且要维护一套复杂的缓存和排序机制,同时发送方和接收方都要记录每个帧的确认状态,实现复杂度明显高于回退N帧。
把停等协议、回退N帧、选择重传放在一起比较,可以清晰地看出它们的递进关系。停等协议的发送窗口和接收窗口都等于1,实现最简单,但信道利用率最低。回退N帧的发送窗口大于1,接收窗口等于1,通过连续发送和累积确认提高了吞吐量,但重传代价是连坐式的,一个帧出错会拖累一批帧重传。选择重传的发送窗口和接收窗口都大于1,逐帧确认,精确重传,效率最高,
本篇完!