更新于 

DL层功能与组帧

从本讲开始我们将开始学习数据链路层的知识,数据链路层主要的功能是向网络层提供数据帧封装的信息,他会涉及到差错检测,共享信道中冲的突解决以及滑动窗口选择重传的问题,此章是考察的重难点,要透彻理解每一个知识点。

数据链路层概念

数据链路层的功能

数据链路层在物理层的服务的基础上向网络层提供服务,他的主要作用就是加强物理层传输比特流的功能,将物理层提供的可能出错的物理连接改造为逻辑上无差错的数据链路,使之对网络层表现为一条无差错的链路。对于网络层而言,数据链路层的基本任务就是将源机器中来自网络层的数据传输到目标机器的网络层。他可以向网络层提供如下服务:

  • 无确认的无连接服务:源机器发送数据帧时不需要先建立链路连接,目的机器收到数据帧时不需要发回确认信息,对丢失的帧,数据链路层不负责重发而是直接交给上层处理。适用于实时通信或者误码率比较低的通信,比如以太网。
  • 有确认的无连接服务:源机器发送数据帧时不需要先建立连接,但是目的机器接收到数据帧后需要发回确认。源机器在所规定的时间内未收到确定信号时,就会重传丢失的帧,以提高数据传输得可靠性。这种服务适用于误码率较高的通信,比如无线通信。
  • 有确认的面向连接服务:帧传输过程分为三个阶段:建立数据链路、传输帧、释放数据链路。目的机器对收到的每一帧都要给出确认,源机器收到确认后才发送下一帧,因而该服务的可靠性最高,但是成本也高。这种服务适用于通信要求(可靠性、实时性)较高的场合。

一定要注意实际上数据链路层传输数据帧是会有丢帧的,但是它能够立刻进行重传,因此对于网络层来看,数据链路层好像提供了可靠的逻辑上无差错的数据通路,而实际上其对应的物理层是发生了丢失比特流数据或者比特流数据是有错误的,但是物理层就不会检测错误也不会重传,而是直接交付给数据链路层,所以说物理层是傻子

同时数据链路层还有如下功能:

  1. 链路管理,即数据链路的建立、维持和释放(用于面向连接的服务时使用)
  2. 组帧(将从网络层传下来的数据报进行封装得到帧以便在数据链路上传送)
  3. 流量控制(保证传送的数据不会过快也不会过慢,并且仅会限制发送方
  4. 差错控制(帧错/位错都会检测到,然后可能重传以保证无差错交付给网络层)

数据链路层的组成

节点:主机、路由器(一定要注意对于数据链路层,路由器也是他的服务对象)

链路:网络中两个节点之间的物理通信,链路的传输介质有双绞线、光纤和微波。分为有线链路和无线链路。

数据链路:网络中两个节点之间的逻辑通道,把实现控制数据传输协议的硬件和软件加到链路上就构成了数据链路。

帧:链路层的协议数据单元,封装网络层数据报而来。

数据链路负责通过一个链路从一个节点向另一个物理链路直接相连的物理链路直接相连的相邻节点传送数据报。

思考:链路和数据链路的本质区别?

链路就是通常所说的物理数据信道。而数据链路是虚拟的概念,他不是一个具象的实物,他是在物理链路的基础上绑定了一系列协议实现的一种逻辑信道,他和物理链路的最大区别就是物理链路上会出现数据丢失或者数据错误以及链路故障,但是在数据链路中他通过协议为网络层提供了一种传输的数据不会出错(实际上是出错了就重传)的链路。因此数据链路层的服务本质上还是由物理层提供的,我们还要注意数据链路由于是基于链路实现的,因此如果两个节点的物理链路不相连,那么它们之间也就没有数据链路可连。

链路管理

数据链路层连接的建立、维持和释放过程称为链路管理,它主要用于面向连接的服务。链路两端的节点要进行通信,必须首先确认对方已处于就绪状态,并且交换一些必要的信息以对帧序号初始化,然后才能建立连接,在传输过程中还要维持这种连接,而在传输完毕后要释放该连接。在多个站点共享同一个物理信道的情况下(例如局域网)如何在要求通信的站点间分配和管理信道也属于数据链路层管理的范畴。

从上面的介绍中我们可以得到一个信息,数据链路上的连接并不是持续存在的,他只在需要数据传输时才建立;而物理链路上的连接却是一直存在的,除非物理链路发生了损坏导致链路断路,两个节点之间的链路连接才会消失。

帧定界、帧同步与透明传输

在两个工作站之间进行信息传输时,必须将网络层的分组进行封装成帧,以帧的格式进行传送。将一段数据的前后分别添加首部和尾部,就构成了帧。

首部和尾部中含有许多控制信息,他们的一个重要作用就是确定帧的帧界限,即帧定界。而帧同步就是指接收方能从接收到的二进制比特流中区分出帧的起始与终止。如在HDLC通信规程中,用标志位F(01111110)来标识一个帧的开始和结束。如在通信过程中,检测到帧标识位F即认为是帧的开始,然后一旦再检测到帧标识位F即表示帧的结束。如下图是HDLC标准帧的格式:

对应的位数是:

但是此时有一个小问题,如果数据中恰好出现与帧定界符相同的比特组合(会误认为传输结束而丢弃后面的数据),那么就需要采用一种有效的措施来解决这个问题,即透明传输。透明传输就是不管所传送的数据是什么样的比特组合,都应当能够在链路上传送。

思考:透明传输是如何解决上述问题的?

由于透明传输是要求所有的比特组合都能在信道上传输的,即遇到帧停止标识符后并不会导致后面的数据不再接收,那么接收方就可以判断出此时的01111110到底是停止标识符还是中间数据了,由于每两个帧之间传输不是连续的,而是有间隔的,因此如果立刻收到了一个好像01111110的停止标识位时接收方会继续等待接手新的帧,而又由于透明传输保证了比特组合不会被拒绝接收,因此后面部分的数据会紧接着抵达接收方,接收方发现这段数据开头不是标识位,那么就可以断定之前的那个0111110不是停止标识位了。

流量控制

由于收发双方的各自工作速率和缓存空间不同,可能出现发送方的发送能力大于接收放的接受能力的现象,如果此时不适当限制发送方的发送速率(即链路上的信息流量),那么前面来不及接受的帧将会被后面的不断发送的帧"淹没",造成帧的丢失而出错。因此流量控制实际上就是限制发送方的数据流量,使其发送帧的速率不超过接收方的能力。

我们要注意即使后面的帧挤掉了前面的帧,但是由于数据链路层中接收方是有序接收的,新挤上来的帧也不会被接收方接受的,这样就会导致后面所有再发送的帧都会被丢弃造成资源的浪费。

这个过程的实现需要某种反馈机制是发送方能够知道接收方是否能够跟上自己的节奏,并且很明显这个过程是动态变化的,并不是稳定的,因此需要有一些规则每隔一段时间就使得发送方知道在什么情况下可以接着发送下一帧,而在什么情况下必须暂停发送,以等待收到某种反馈信息后继续发送。

这里介绍一种最简单的实现方法,即当接收方收不下时就不回复给发送方反馈信息,发送方再没有收到下一个反馈信息之前不发送下一个帧,而当接收方可以接收时就回复确认来告诉发送方可以发送下一个帧了。这种方法实现简单,但是也到了许多问题,首先每次都需要反馈信息,效率低,其次这也导致了数据链路收发双方帧的传输只能是如上图的这种格式一个一个有序的传输。

同时我们要注意流量控制并不是数据链路层特有的功能,许多高层协议中也提供此功能,只不过控制的对象不同而已。对于数据层来说,控制的是相邻两节点之间数据链路上的流量即点对点形式,而对于传输层来说,流量控制是端到端形式的,同时传输层就对流量控制的实现进行了优化,不再是一个一个的有序接收传输了,而是接收端发送一个动态的窗口公告来持续的通知发送方自己的缓存区空间大小。

差错控制

由于信道噪声等各种原因,帧在传输过程中是可能出现错误的。使发送方确定接收方是否正确收到其发送的数据的方法称为差错控制。通常这些错误都是位错(位数反转)或者帧错。

位错指帧中某些位出现了差错,通常采用循环冗余校验码(CRC)方式或者海明码方式发现位错并进行纠正,或者通过自动重传请求(Automatic Report reQuest,ARQ)通知发送方重传错误帧。具体做法是让发送方将要发送的数据帧附加一定的CRC冗余检错码一并发送,接收方根据检错码对数据帧进行差错检测,若发现错误则丢弃,发送方(未在规定时间收到反馈信息)内超时重传该数据帧。这种差错控制方法称为ARQ法,ARQ法只需返回很少的控制信息就可以有效地确认发送数据帧是否被正确接收。具体的CRC检测步骤请参考这里:

帧错指帧的丢失、重复或者失序等错误。在数据链路层引入定时器和编号机制,能够保证每一帧最终都能有且仅有一次正确地交付给目的节点。

组帧(封装成帧)

数据链路层之所以要将比特组合成帧为传输单位,就是为了在出错时之重发出错的帧,而不需要重新发全部数据,提高了传输的效率。为了使接收方能够正确的接受并检查所传输的帧,发送方必须依据一定的规则把网络层递交的分组封装成帧(称为组帧)。组帧主要解决帧定界、帧同步、透明传输等问题。

封装成帧就是在一段数据的前后端加上首部和尾部,这样就构成了一个帧。接收端在收到物理层上交的比特流数据后,就能根据首部和尾部的标记,从收到的比特流中识别一段帧的开始和结束。

思考:为什么组帧时需要在数据的首部和尾部都进行包装?

在网络中信息是以帧为最小单位进行数据传输的,所以接收端要正确的接收帧,必须能够清楚帧在一串比特流中从哪里开始和到哪里结束(因为接收端收到的只是一串比特流,没有首部和尾部就不能正确的区分帧),而分组(即IP数据报)仅是包含在帧中的数据部分(后面将详细讲解),所以不再需要增加尾部来定界。

我们把接收方应当能从接收到的二进制比特流中区分出帧的开始和结束的过程称为帧同步

组帧有四种方法:①字符计数法②字符(节)填充法③零比特填充法④违规编码法,下面我们注意介绍这几种组帧方法的步骤

字符计数法

这种方法实现简单,原理也很简单。帧首部使用一个计数字段(第一个字节,八位)来标明帧内字符数(计数长度包含首部)。如上图,第一个帧我们从第一个字节的首部可得知长度是5,因此第一个帧就是51234,然后下一个字节就是属于第二个帧的首部了,因此第二个帧长度也是5,因此第二个帧时56789,以此类推,第三个帧、第四个帧等等都可以得到区分。

我们思考一下这种方法的缺点有哪些,其实我们很容易就可以看出来,他把好多帧都连在一起了,即鸡蛋放在同一个篮子里了,当有其中的任意一个帧的计数首部字段发生错误时,会导致连锁反应,造成许多段无法得到正确的区分。即帧边界划分依据不太好,很容易造成帧的结束位和下一帧的开始位混乱,收发双方将失去同步,从而造成灾难性后果。

字符填充的首位定界符法

字符填充法是使用一些特定的字符来定界一帧的开始和结束(DLE STX)与结束(DLE ETX),这个思路跟我们上面介绍透明传输时使用的帧分割的思路一致,即使用特殊的帧开始和停止标识位,但是我们就面临了一个问题,即如何能够使信息位中出现的特殊字符不会被误判为帧的首位定界符?

之前我们介绍过一个解决策略即透明传输,即在特殊字符前填充一个转义字符(DLE)来加以区分(注意,转义字符是ASCII码中的控制字符,是一个字符而不是"D",“L”,"E"三个字符的组合),以实现数据的透明传输。接收方收到转义字符后,就知道其后面紧跟的是数据信息,而不是控制信息。

当传送的帧是由文本文件组成时(文本文件的字符都是从键盘上输入的,因此都是对应着ASCII码),因此都可以放到帧中传输,即透明传输。当传送的帧时由非ASCII码的文本文件(二进制程序或者图像文件),那么就要采用字符填充方法实现透明传输。

如上图就是一个包含转义信息的帧的组帧发送和接受的过程。我们发现在从网络层传下来的数据中有EOT、SOH、ESC等需要转义的内容,因此发送方除了在首部添加SOH首部和EOT尾部后还需要对中间的内容进行转义,因此插入了蓝色转义内容ESC(我们要注意内容中的转义字段也需要再转义,如上图中的ESC需要再转义)。而接收方再得到数据后会删除插入的转义字段,结果得到的是原始数据,这就是字符(节)填充法组帧的由来。

零比特填充的首位标志法

我们思考一下实际上字符填充的首位定界符法已经可以很完美的解决帧定界的问题了,但是他的性能可以进一步提升,在字符填充的首位定界符法中操作的对象是ASCII码,但是我们完全可以将操作对象进一步简化到比特流数据,这样更偏向硬件层,性能肯定也更佳(毕竟任何一个数据本质上都是一段比特流数据)。零比特填充法允许数据帧包含任意个数的比特,也允许每个字符的编码包含任意个数的比特。他使用一个特定的比特模式,即01111110来标志一帧的开始和结束,因此他也面临解决中间数据内容部分不会被误判的问题,但是他的解决策略并不是进行转义,而是对数据进行修改操作使得中间的数据比特流内容不可能出现标志位形式。为了不使信息位中出现比特流01111110被误判为帧的首位标志,发送方的数据链路层在信息位中遇到5个连续的1时,就会自动在其后插入一个0,而接收方做该过程的逆操作,即每收到5个连续的1时,自动删除后面紧跟的0,以恢复原信息。

这样就保证了透明传输,在传送的比特流组合中可以传送任意比特组合,而不会引起对帧边界的判断错误。这种方法很容易由硬件来实现,性能要优于字符填充法。

违规编码法

在物理层进行比特编码时,通常采用违规编码法,例如使用曼彻斯特编码方式将数据比特"1"编码成"高-低"电平对,将数据比特"0"编码成"低-高"电平对,而""高-高电平对和"低-低"电平对在数据比特中是违规的(即没有被采用表示数据),我们可以借用这些违规编码来定界帧的起始为和终止位。例如局域网IEEE 802标准就采用了这种方法。

违规编码法不需要采用任何填充技术,便能实现数据传输的透明性,他是它只适用于采用冗余编码的特殊编码环境。

总结

组帧方法 特点 优缺点
字符计数法 用首部计数段区分不同帧 原理简单,但是脆弱
字符填充法 使用转义字符使得标志位形式的数据不会被误判 安全但是复杂且不兼容
零比特填充法 使数据部分不可能出现标志位组合 实现简单且稳定
违规编码 使用违规电平作为帧的标志位 实现简单且稳定

由于字节计数法中计数字段的脆弱性和字符填充法实现上的复杂性和不兼容性,目前常用的组帧方法是比特填充法和违规编码法。