网络工程师教程数据链路层.docx
《网络工程师教程数据链路层.docx》由会员分享,可在线阅读,更多相关《网络工程师教程数据链路层.docx(26页珍藏版)》请在冰豆网上搜索。
网络工程师教程数据链路层
选择重传ARQ协议
为进一步提高信道的利用率,可设法只重传出现差错的数据帧或者是计时器超时的数据帧。
但这时必须加大接收窗口,以便先收下发送序号不连续但仍处在接收窗口中的那些数据帧。
等到所缺序号的数据帧收到后再一并送交主机。
这就是选择重传ARQ协议。
使用选择重传ARQ协议可以避免重复传送那些本来已经正确到达接收端的数据帧。
但我们付出的代价是在接收端要设置具有相当容量的缓存空间,这在许多情况下是不够经济的。
正因如此,选择重传ARQ协议在目前就远没有连续ARQ协议使用得那么广泛。
今后存储器芯片的价格会更加便宜,选择重传ARQ协议还是有可能受到更多的重视。
对于选择重传ARQ协议,接收窗口显然不应该大于发送窗口。
若用n比特进行编号,则可以证明,接收窗口的最大值受下式的约束(见习题3-10)
WR2n/2(3-18)
当接收窗口WR为最大值时,WT=WR=2n/2。
例如在n=3时,可以算出WT=WR=4。
习题
3-01数据链路(即逻辑链路)与链路(即物理链路)有何区别?
“电路接通了”与“数据链路接通了”的区别何在?
3-02数据链路层中的链路控制包括哪些功能?
3-03考察停止等待协议算法。
在接收结点,当执行步骤(4)时,若将“否则转到(7)”改为“否则转到(8)”,将产生什么结果?
3-04试导出公式(3-5)。
3-05试导出停止等待协议的信道利用率公式。
3-06信道速率为4kb/s。
采用停止等待协议。
传播时延tp=20ms。
确认帧长度和处理时间均可忽略。
问帧长为多少才能使信道利用率达到至少50%?
3-07在停止等待协议中,确认帧是否需要序号?
请说明理由。
3-08试写出连续ARQ协议的算法。
3-09试证明:
当用n个比特进行编号时,若接收窗口的大小为1,则只有在发送窗口的大小WT2n1时,连续ARQ协议才能正确运行。
3-10试证明:
对于选择重传ARQ协议,若用n比特进行编号,则接收窗口的最大值受公式(3-18)的约束。
3-11在选择重传ARQ协议中,设编号用3bit。
再设发送窗口WT=6而接收窗口WR=3。
试找出一种情况,使得在此情况下协议不能正确工作。
3-12在连续ARQ协议中,设编号用3bit,而发送窗口WT=8。
试找出一种情况,使得在此情况下协议不能正确工作。
3-13在什么条件下,选择重传ARQ协议和连续ARQ协议在效果上完全一致?
3-14在连续ARQ协议中,若WT=7,则发送端在开始时可连续发送7个数据帧。
因此,在每一帧发出后,都要置一个超时计时器。
现在计算机里只有一个硬时钟。
设这7个数据帧发出的时间分别为t0,t1,...,t6,且tout都一样大。
试问如何实现这7个超时计时器(这叫软时钟法)?
3-15卫星信道的数据率为1Mb/s。
取卫星信道的单程传播时延为0.25秒。
每一个数据帧长都是2000bit。
忽略误码率、确认帧长和处理时间。
试计算下列情况下的信道利用率:
(1)停止等待协议。
(2)连续ARQ协议,WT=7。
(3)连续ARQ协议,WT=127。
(4)连续ARQ协议,WT=255。
5.3.1可靠传输——第4版的第3章
第3章数据链路层
数据链路层的许多概念都是计算机网络的重要概念。
本章在介绍数据链路层的基本概念后,就详细地讨论两个重要的协议:
停止等待协议和连续ARQ协议,包括滑动窗口的概念。
接着阐明面向比特的链路控制规程HDLC的要点。
最后介绍因特网中的数据链路层协议PPP。
3.1数据链路层的基本概念
我们已多次使用过“链路”和“数据链路”这两个术语。
这里要强调一下,“链路”和“数据链路”并不是一回事。
所谓链路(link)就是一条无源的点到点的物理线路段,中间没有任何其他的交换结点。
在进行数据通信时,两个计算机之间的通路往往是由许多的链路串接而成的。
可见一条链路只是一条通路的一个组成部分。
数据链路(datalink)则是另一个概念。
这是因为当需要在一条线路上传送数据时,除了必须有一条物理线路外,还必须有一些必要的通信协议来控制这些数据的传输(这将在后面几节讨论)。
若把实现这些协议的硬件和软件加到链路上,就构成了数据链路。
现在最常用的方法是使用适配器(在许多情况下适配器就是网卡)来实现这些协议的硬件和软件。
一般的适配器都包括了数据链路层和物理层这两层的功能。
在讨论数据链路层的功能时,常常在两个对等的数据链路层之间画出一个数字管道,而在这条数字管道上传输的数据单位是帧。
虽然我们知道在物理层之间传送的是比特流,而在物理传输媒体上传送的是信号(电信号或光信号),但有时为了方便我们也常说,“在某条链路(而没有说数据链路)上传送数据帧”。
其实这已经隐含地假定了我们是在数据链路层上来观察问题。
如果没有数据链路层的协议,我们在物理层上就只能看见链路上传送的比特串,根本不能找出一个帧的起止比特,当然更无法识别帧的结构。
有时我们也会不太严格地说,“在某条链路上传送分组或比特流”,但这显然是在网络层或物理层上讨论问题。
也有人采用另外的术语。
这就是将链路分为物理链路和逻辑链路。
物理链路就是上面所说的链路,而逻辑链路就是上面的数据链路,是物理链路加上必要的通信协议。
这两种划分方法实质上是一样的。
早期的数据通信协议曾叫作通信规程(procedure)。
因此在数据链路层,规程和协议是同义语。
数据链路层的主要功能如下(有些协议可以省略其中的一些):
(1)链路管理当网络中的两个结点要进行通信时,数据的发方必须确知收方是否已经处在准备接收的状态。
为此,通信的双方必须先要交换一些必要的信息。
或者用我们的术语,必须先建立一条数据链路。
同样地,在传输数据时要维持数据链路,而在通信完毕时要释放数据链路。
数据链路的建立、维持和释放就叫做链路管理。
(2)帧定界在数据链路层,数据的传送单位是帧。
数据一帧一帧地传送,就可以在出现差错时,将有差错的帧再重传一次,而避免了将全部数据都进行重传。
帧定界是指收方应当能从收到的比特流中准确地区分出一帧的开始和结束在什么地方。
帧定界也可称为帧同步。
(3)流量控制发方发送数据的速率必须使收方来得及接收。
当收方来不及接收时,就必须及时控制发方发送数据的速率。
这种功能称作流量控制(flowcontrol)。
(4)差错控制在计算机通信中,一般都要求有极低的比特差错率。
为此,广泛地采用了编码技术。
编码技术有两大类。
一类是前向纠错,即收方收到有差错的数据帧时,能够自动将差错改正过来。
这种方法的开销较大,不大适合于计算机通信。
另一类是差错检测,即收方可以检测出收到的帧有差错(但并不知道是哪几个比特错了)。
当检测出有差错的帧时就立即将它丢弃,但接下去有两种选择:
一种方法不进行任何处理(要处理也是由高层进行),另一种方法则是由数据链路层负责重传丢弃的帧。
这两种方法都是很常用的。
(5)将数据和控制信息区分开在许多情况下,数据和控制信息处于同一帧中。
因此一定要有相应的措施使收方能够将它们区分开来。
(6)透明传输所谓透明传输就是不管所传数据是什么样的比特组合,都应当能够在链路上传送。
当所传数据中的比特组合恰巧出现了与某一个控制信息完全一样时,必须有可靠的措施,使收方不会将这种比特组合的数据误认为是某种控制信息。
只要能做到这点,数据链路层的传输就被称为是透明的。
(7)寻址必须保证每一帧都能送到正确的目的站。
收方也应知道发方是哪个站。
当OSI确定了应当有一个数据链路层后,又出现了许多种采用不同媒体接入控制的局域网。
这些局域网无法使用一种统一的数据链路层协议。
于是局域网的数据链路层就分解为两个子层。
本章实际上是讨论最基本的数据链路层协议,其基本概念对学习全课程都很重要。
至于更为复杂的局域网的数据链路层协议将在第4章进行讨论。
下面先讨论最简单的停止等待协议。
3.2停止等待协议
停止等待(stop-and-wait)协议是最简单但也是最基本的数据链路层协议。
很多有关协议的基本概念都可以从这个协议中学习到。
我们先从最简单的情况讲起。
3.2.1完全理想化的数据传输
当两个主机进行通信时,应用进程要将数据从应用层逐层往下传,经物理层到达通信线路。
通信线路将数据传到远端主机的物理层后,再逐层向上传,最后由应用层交给远程的应用进程。
但现在为了把主要精力放在数据链路层的协议上,可以采用一个简化的模型(图3-1),即把数据链路层以上的各层用一个主机来代替,而物理层和通信线路则等效成一条简单的数据链路。
在发方和收方的数据链路层分别有一个发送缓存和接收缓存。
若进行全双工通信,则在每一方都要同时设有发送缓存和接收缓存。
缓存就是一个存储空间,它是必不可少的。
这是因为在通信线路上数据是以比特流的形式串行传输的,但在计算机内部数据的传输则是以字节(或若干个字节)为单位并行传输的。
计算机在发送数据时,先以并行方式将数据写入发送缓存,然后以串行方式从发送缓存中按顺序读出比特,发送到通信线路上。
在接收数据时,计算机先从通信线路上将串行传输的比特流按顺序存入接收缓存,然后再以并行方式按字节(或若干个字节)将数据从接收缓存读出。
图3-1所示的简化模型对于一个计算机网络中任意一条数据链路上的数据传输情况都是适用的。
在网络内部,各交换结点的数据链路层的上面只有一个网络层。
对于这种交换结点,网络层就相当于简化模型中的主机。
为了深入理解数据链路层的协议,我们先从一种假想的、完全理想化的数据传输过程开始讨论。
为了和后面的讨论相衔接,我们假定数据传输是以帧为单位。
所谓完全理想化的数据传输就是基于以下两个假定:
假定1:
链路是理想的传输信道,所传送的任何数据既不会出差错也不会丢失。
假定2:
不管发方以多快的速率发送数据,收方总是来得及收下,并及时上交主机。
图3-1两台计算机通过一条数据链路进行通信的简化模型
第一个假定很容易理解。
对第二个假定则需加以解释。
我们假设主机A连续不断地向主机B发送数据。
在收方,主机B的数据链路层也就将收到的数据逐帧交给主机B。
在理想情况下,收方数据链路层的缓存每存满一帧就向主机B交付一帧。
如果没有专门的流量控制协议,则收方并没有办法控制发方的发送速率,而收方也很难做到:
向主机交付数据的速率永远不会低于发方发送数据的速率。
若收方数据链路层向主机交付数据的速率略低于发方发送数据的速率,则收方的缓存中暂时存放的数据帧就会逐渐堆积起来,最后造成缓存溢出和数据帧丢失。
因此,上述第二个假定就相当于认为:
接收端向主机交付数据的速率永远不会低于发送端发送数据的速率。
在这样理想化的条件下,数据的传输就非常简单(不需要有流量控制,也不需要有差错控制)。
但下面我们要逐步去掉这些完全理想化的假定。
3.2.2具有最简单流量控制的数据链路层协议
现在去掉上述的第二个假定。
但是,仍然保留第一个假定,即主机A向主机B传输数据的信道仍然是无差错的理想信道。
然而现在不能保证接收端向主机交付数据的速率永远不低于发送端发送数据的速率。
为了使收方的接收缓存在任何情况下都不会溢出,在最简单的情况下,就是发方每发送一帧就暂时停下来,等待收方的确接收完毕后再发送下一帧。
收方收到数据帧后就交付给主机,然后发一信息给发方,表示接收的任务已经完成。
这时,发方才再发送下一个数据帧。
在这种情况下,收方的接收缓存的大小只要能够装得下一个数据帧即可。
显然,用这样的方法收发双方能够同步得很好,发方发送的数据流受收方的控制。
这里应强调一下,由收方控制发方的数据流,乃是计算机网络中流量控制的一个基本方法。
现将以上具有最简单流量控制的数据链路层协议写成算法如下:
假定:
链路是理想的传输信道,即所传送的任何数据既不会出差错也不会丢失。
在发送结点:
(1)从主机取一个数据帧。
(2)将数据帧送到数据链路层的发送缓存。
(3)将发送缓存中的数据帧发送出去。
(4)等待。
(5)若收到由接收结点发过来的信息(此信息的格式与内容可由双方事先商定好),则从主机取一个新的数据帧,然后转到
(2)。
在接收结点:
(1)等待。
(2)若收到由发送结点发过来的数据帧,则将其放入数据链路层的接收缓存。
(3)将接收缓存中的数据帧上交主机。
(4)向发送结点发一信息,表示数据帧已经上交给主机。
(5)转到
(1)。
图3-2是前面所述的两种情况的对比。
图3-2(a)是不需要任何协议的理想化情况。
主机A将数据帧(图中用DATA表示)连续发出,而不管发送速率有多快,收方总能够跟得上,收到一帧即交付给主机B。
显然,这种完全理想化情况的传输效率是很高的。
图3-2(b)是由收方控制发方发送速率的情况。
发方每发完一帧就必须停下来,等待收方的信息。
这里要指出,由于假定了数据在传输过程中不会出差错,因此收方将数据帧交给主机B后向发方主机A发送的信息,不需要有任何具体的内容,即不需要说明所收到的数据是否是正确无误的。
这相当于只要发回一个不需要装入任何信件的空信封就能起到流量控制的作用。
图3-2不需要任何数据链路层协议的数据传输(a)和具有最简单的流量控制的数据链路层协议(b)
3.2.3实用的停止等待协议
现在去掉前面的两个假定,讨论实用的数据链路层协议。
这就是说,传输数据的信道不能保证使所传的数据不产生差错,并且还需要对数据的发送端进行流量控制。
图3-3(a)画的是数据在传输过程中不出差错的情况。
收方在收到一个正确的数据帧后,即交付给主机B,同时向主机A发送一个确认帧ACK(ACKnowledgement)。
当主机A收到确认帧ACK后才能发送一个新的数据帧。
这样就实现了收方对发方的流量控制。
现在假定数据帧在传输过程中出现了差错。
由于通常都在数据帧中加上了循环冗余检验CRC(CyclicRedundancyCheck),所以结点B很容易用硬件检验出收到的数据帧是否有差错(使用循环冗余检验进行差错检测的原理在后面的3.2.4小节讨论)。
当发现差错时,结点B就向主机A发送一个否认帧NAK(NegativeAcKnowlegement),以表示主机A应当重传出现差错的那个数据帧。
图3-3(b)画出了主机A重传数据帧。
如多次出现差错,就要多次重传数据帧,直到收到结点B发来的确认帧ACK为止。
为此,在发送端必须暂时保存已发送过的数据帧的副本。
当通信线路质量太差时,则主机A在重传一定的次数后(如8次或16次,这要事先设定好),即不再进行重传,而是将此情况向上一层报告。
有时链路上的干扰很严重,或由于其他一些原因,结点B收不到结点A发来的数据帧。
这种情况称为帧丢失(图3-3(c))。
发生帧丢失时结点B当然不会向结点A发送任何确认帧。
如果结点A要等收到结点B的确认信息后再发送下一个数据帧,那么就将永远等待下去。
于是就出现了死锁现象。
同理,若结点B发过来的确认帧丢失,也会同样出现这种死锁现象。
要解决死锁问题,可在结点A发送完一个数据帧时,就启动一个超时计时器(timeouttimer)。
计时器又称为定时器[MINGCI94]。
若到了超时计时器所设置的重传时间tout而仍收不到结点B的任何确认帧,则结点A就重传前面所发送的这一数据帧(见图3-3(c),(d))。
如果在重传时间tout内收到确认,则将超时计时器清零并停止计时。
显然,超时计时器设置的重传时间应仔细选择确定。
若重传时间选得太短,则在正常情况下也会在对方的确认信息回到发送方之前就过早地重传数据。
若重传时间选得太长,则往往要白白等掉许多时间。
一般可将重传时间选为略大于“从发完数据帧到收到确认帧所需的平均时间”。
图3-3数据帧在链路上传输的几种情况
然而现在问题并没有完全解决。
当出现数据帧丢失时,超时重传的确是一个好办法。
但是若丢失的是确认帧,则超时重传将使主机B收到两个同样的数据帧。
由于主机B现在无法识别重复的数据帧,因而在主机B收到的数据中出现了另一种差错——重复帧。
重复帧也是一种不允许出现的差错。
要解决重复帧的问题,必须使每一个数据帧带上不同的发送序号。
每发送一个新的数据帧就把它的发送序号加1。
若结点B收到发送序号相同的数据帧,就表明出现了重复帧。
这时应当丢弃这重复帧,因为已经收到过同样的数据帧并且也交给了主机B。
但应注意,此时结点B还必须向结点A发送一个确认帧ACK,因为结点B已经知道结点A还没有收到上一次发过去的确认帧ACK。
我们知道,任何一个编号系统的序号所占用的比特数一定是有限的。
因此,经过一段时间后,发送序号就会重复。
例如,当发送序号占用3bit时,就可组成8种不同的发送序号,从000到111。
当数据帧的发送序号为111时,下一个发送序号就又是000。
因此,要进行编号就要考虑序号到底要占用多少个比特。
序号占用的比特数越少,数据传输的额外开销就越小。
对于停止等待协议,由于每发送一个数据帧就停止等待,因此用一个比特来编号就够了。
一个比特可以有0和1两种不同的序号。
这样,数据帧中的发送序号(以后记为N(S),S表示发送)就以0和1交替的方式出现在数据帧中。
每发一个新的数据帧,发送序号就和上次发送的不一样。
用这样的方法就可以使收方能够区分开新的数据帧和重传的数据帧了。
从以上的讨论可以看出,虽然物理层在传输比特时会出现差错,但由于数据链路层的停止等待协议采用了有效的检错重传机制,数据链路层对上面的网络层就提供了可靠传输的服务。
3.2.4循环冗余检验的原理
在数据链路层传送的帧中,广泛使用了循环冗余检验CRC的检错技术。
下面我们用一个具体的例子来说明循环冗余检验的原理。
假设待传送的数据M=1010001101(共kbit)。
我们在M的后面再添加供差错检测用的nbit冗余码一起发送。
在所要发送的数据后面增加一些冗余码,虽然增大了数据传输的开销,但却可以进行差错检测。
在传输可能出现差错时,付出这种代价还是值得的。
这nbit冗余码是这样得出的。
用二进制的模2运算①进行2n乘M的运算,这相当于在M后面添加n个0。
得到的(k+n)bit的数除以事先选定好的长度为(n+1)bit的数P,得出商是Q而余数是R,余数R比除数P至少要少1个比特。
至于P是怎样选定的,下面还要介绍。
在图3-4所示的例子中,n=5,P=110101,模2运算的结果是:
商Q=1101010110,而余数R=01110。
现在将得到的余数R就作为冗余码添加在数据M的后面发送出去,即发送的数据是101000110101110,或2nM+R。
为检测差错而在数据后面添加上的冗余码常称为帧检验序列FCS(FrameCheckSequence)。
帧检验序列就是要保证收到的数据和发送的数据完全相同。
这里应当注意,循环冗余检验CRC和帧检验序列FCS并不等同。
CRC是一种常用的检错方法,而FCS是添加在数据后面的冗余码,它可以用CRC,但也不一定选用CRC这种方法。
图3-4循环冗余检验的原理说明
———————————
①注:
用模2运算进行加法时不进位,例如,1111+1010=0101。
减法和加法一样,按加法规则计算。
———————————
如果数据在传输过程中不产生误码,则接收端收到的应当是2nM+R。
将这个数除以P(模2运算)后,得出的余数显然应当是0(读者可以自己进行类似图3-4的运算。
被除数现在是101000110101110,而除数是P=110101,看余数是否为0)。
若数据在传输过程中出现误码,则在接收端进行以上的运算后,一般就不会得出余数为0的结果。
一种较方便的方法是用多项式来表示循环冗余检验过程,即使用多项式相应的系数来表示上述二进制数字中的1和0。
例如,可以用多项式P(X)=X5+X4+X2+1来表示上面的除数P(称为生成多项式)。
因此,在接收端进行的运算就可以写为
只要得出的余数R不为0,就表示检测到了差错(注意:
这种检测方法并不能确定究竟是哪一个或哪几个比特出现了差错),然后就丢弃这个出现差错的帧。
那么,能不能说只要得出的余数R是0,就一定没有出现差错呢?
不行!
因为在某种非常特殊的比特差错组合下,也可能非常碰巧地使得余数R恰好为0。
但只要经过严格的挑选,并使用位数足够多的除数P,那么出现检测不到的差错的概率就可以是个极小的数值。
现在广泛使用的P(X)有以下几种:
CRC-16=X16+X15+X2+1
CRC-CCITT=X16+X12+X5+1
CRC-32=X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X+1
应当注意,仅用循环冗余检验CRC差错检测技术只能做到无差错接受(accept)。
所谓“无差错接受”就是指:
“凡是接受的帧(即不包括丢弃的帧),我们都能以非常接近于1的概率认为这些帧在传输过程中没有产生差错”,或更简单些,这是指“凡是接受的帧均无传输差错”(丢弃的帧都不属于接受的帧)。
而要做到“可靠传输”(即发送什么就收到什么)就必须再加上确认和重传机制。
3.2.5停止等待协议的算法
为了对上面所述的停止等待协议有一个完整而准确的理解,下面给出此协议的算法,读者应弄清算法中的每一个步骤。
在发送结点:
(1)从主机取一个数据帧。
(2)V(S)←0。
{发送状态变量初始化}
(3)N(S)←V(S);{将发送状态变量的数值写入发送序号}
将数据帧送交发送缓存。
(4)将发送缓存中的数据帧发送出去。
(5)设置超时计时器。
{选择适当的超时重传时间tout}
(6)等待。
{等待以下(7)~(9)这三个事件中最先出现的一个}
(7)若收到确认帧ACK,则:
从主机取一个新的数据帧;
V(S)←[1V(S)];{更新发送状态变量,变为下一个序号}
转到(3)。
(8)若收到否认帧NAK,则转到(4)。
{重传数据帧}
(9)若超时计时器时间到,则转到(4)。
{重传数据帧}
在接收结点:
(1)V(R)←0。
{接收状态变量初始化,其数值等于欲接收的数据帧的发送序号}
(2)等待。
(3)当收到一个数据帧,就检查有无产生传输差错(如用CRC)。
若检查结果正确无误,则执行后续算法;
否则转到(8)。
(4)若N(S)=V(R),则执行后续算法;{收到发送序号正确的数据帧}
否则丢弃此数据帧,然后转到(7)。
(5)将收到的数据帧中的数据部分送交主机。
(6)V(R)←[1V(R)]。
{更新接收状态变量,准备接收下一个数据帧}
(7)发送确认帧ACK,并转到
(2)。
(8)发送否认帧NAK,并转到
(2)。
从以上算法可知,停止等待协议中需要特别注意的地方,就是在收发两端各设置一个本地状态变量(仅占1bit)。
状态变量的概念很重要,一定要弄清以下几点:
(1)每发送一个数据帧,都必须将发送状态变量V(S)的值(即0或1)写到数据帧的发送序号N(S)上。
但只有收到一个确认帧ACK后,才更新发送状态变量V(S)一次(将1变成0,或0变成1)并发送新的数据帧。
(2)在接收端,每接收到一个数据帧,就要将发方在数据帧上设置的发送序号N(S)与本地的接收状态变量V(R)相比较。
若二者相等就表明是新的数据帧,否则为重复帧。
(3)在接收端,若收到一个重复帧,则丢弃它(即不做任何处理),且接收状态变量不变,但此时仍须向发送端发送一个确认帧ACK。
(4)在以上的算法中,我们假定接收