数据链路层

数据链路层使用的信道主要有以下两种类型:

  1. 点对点信道
  2. 广播信道

3.1使用点对对信道的数据链路层

3.1.2数据链路和帧

链路和数据链路并不是一个东西

链路:从一个结点到相邻结点的一段物理线路,中间没有任何交换结点。

数据链路:当需要在一条线路上传送数据时,除了必须有一条物理线路外,还必须有一些通信协议利啊控制这些数据的传输。把实现这些协议的硬件和软件加到链路上,就构成了数据链路。

现在最常用的方法是使用网络适配器(如拨号上网使用拨号适配器,通过以太网上网使用局域网适配器)来实现这些协议。一般的适配器都包括了数据链路层和物理层的功能。

规程:早期的数据通信协议曾叫作通信规程,因此在数据链路层,规程和协议是同义语

:数据链路层的协议数据但元叫做帧。

数据链路层把网络层交下来的数据构成帧发送到链路上,以及把接收到的帧中的数据取出并上交给网络层。在互联网中,网络层协议数据单元就是IP数据报(或简称为数据报,分组或包)

点对点信道的数据链路层通信的主要步骤

  1. 结点A的数据链路层把网络层交下来的IP数据报添加首部和尾部封装成帧
  2. 结点A把封装好的帧发送给结点B的数据链路层
  3. 若结点B的数据链路层收到的帧无差错,则结点B的数据链路层从收到的帧中提取出IP数据报交给上面的网络层,否则丢弃这个帧

image-20221007162648127

3.1.3封装成帧

帧的封装:网络层的IP数据报向下传输到数据链路层,成为帧的数据部分,同时它的前后面分别加上首部和尾部,封装成一个完整的帧。

帧的长度等于帧的数据长度加上帧首部和帧尾部的长度。

帧定界:数据链路层必须使用物理层提供的服务来传输一个一个的帧,物理层将数据链路层交来的数据以比特流的形式在物理链路上传输。因此,数据链路层的接收方为了能以帧为单位处理接收的数据,必须正确识别每个帧的开始和结束,即帧定界。

MTU:虽然为了提高帧的传输效率,应当使帧的数据部分的长度尽可能大一些,但考虑到差错控制等多种因素,每种链路层协议都规定了帧的数据部分长度的上限,即最大传送单元(Maximum Transfer Unit,MTU)

帧的数据部分长度不能超过规定的MTU数值。

image-20221007165536269

实现帧定界的方法:实现帧定界有很多方法,但并不是每种方法在是数据链路层都好用,以下介绍几种方法

插入时间间隔:在传输的帧和帧之间插入时间间隔。不过并不是所有的传输层传输服务都会保证数据链路层发送帧之间的时间间隔。某些物理层会将传输的帧之间的间隔”挤掉“,也有可能在一个帧中间插入发送帧的时间间隔。因此该方法不一定适合所有的场合。例如,物理链路采用面向字节的异步传输方式时,字节之间的时间间隔就不是固定的。

帧定界符:一种常用的实现帧定界的方法是在每个帧开始处和结束处添加特殊的帧定界标准(帧定界符),标记一个帧的开始和结束。帧开始标志和帧结束标志可以不同也可以不同。

image-20221007175013867

当物理链路提供的是面向字符的传输服务时(物理链路以字符为单位传输数据),可以使用某个特殊的不可打印的控制字符作为帧定界符。

ASCII码是7位编码,128个ASCII码中可以打印的有95个,而不可打印的控制字符有33个。

透明传输:由于帧开始标志和帧结束标准使用专门的控制字符,因此所传输的数据中不能出现与之相同的字节,否则就会出现帧定界错误。当传送的是文本文件中的数据时(文本文件中的字符都是键盘上输入的),帧的数据部分显然不会出现不可以打印的帧界定符。但当数据部分是非ASCII码文本的数据时(如二进制代码的计算机程序或者图像等),情况就不同了。如果数据中某个字节的二进制代码恰好和帧界定符一样,接收方的数据链路层就会错误地”找到帧的边界“,而收不到完整的帧。

image-20221007181501796

我们希望数据链路层提供一种”透明传输“的服务,即对上层交给的传输数据没有任何限制,就好像数据链路层不存在一样。图3-6显然不是透明传输,因为要发送的的数据中不能出现帧界定符,

字节填充/字符填充:为了解决透明传输的问题,对于面向字符的物理链路,可以使用一种称之为字节填充(Byte Stuffing)或者字符填充(Character Stuffing)的方法。该方法的基本原理如图3-7所示,发送端的数据链路层在数据中出现的标记字符(与帧定界符相同的字符)前面插入一个转义字符(如特殊的控制字符”ESC“),而接收端的数据链路层不会讲转义字符后面出现的标记字符解释为帧定界符,并且会在将数据送往网络层之前删除这个插入的转义字符。如果中国转义字符也出现在数据当中,那么解决方法仍然是在转义字符的前面插入一个转义字符。因此,当接收端收到连续的两个转义字符时,就删除前面的一个。

image-20221007195701631

比特填充:当物理链路提供的是面向比特的传输服务时(物理链路传送连续的比特流),帧定界符可以使用某个特殊的比特组合,如PPP所使用的”01111110“。由于帧的长度不再要求必须是整数个字节,因此,可以采用开销更小的比特填充(Bit Stuffing)来实现透明传输。

图3-8以PPP采用的零比特填充法来说明比特填充是如何实现透明传输的。在发送端,先扫描整个信息字段(通常是用硬件实现,但也可以软件实现,只是会慢一些)。只要发现5个连续的1,则立即填入一个0。经过这种零比特填充的数据,就可以保住在信息字段中不会出现6个连续的1。接收端在收到一个帧时,先找到帧定界以确定一个帧的边界,再用硬件对其中的比特流进行扫描。每当发现5个连续的1时,就把5个连续的1后的一个0删除,以还原比特流。这样就保证了透明传输:所传送的数据比特流可以包含任意组合的比特模式,而不会引起对帧边界的判断错误。

image-20221007200548559

3.1.4差错检测

比特差错:现实的通信链路都不会是理想的,比特在传输过程中可能会产生差错:1可能变成0,而0也可能变成1。这就叫作比特差错。

误码率:在一段时间内,传输错误的比特数和所传输的比特总数的比率称为误码率(Bit Error Rate, BER)。例如,误码率是10^-10^,表示平均传送10^10^个比特就会出现一个比特的差错。

误码率和信噪比有很大的关系,如果设法提高信噪比,就可以使误码率减小。

差错检测码差错检测码(Error-Detecting Code,EDC)是一种用于实现差错检测的方法,具体原理如下。

为了使接收方能检测处接收的数据中是否出现了差错,发送方需要采用某种差错检测算法f,用发送的数据D计算处差错检测码EDC=f(D),并将EDC随数据一起发送给接收方。接收方通过同样的算法计算接收数据D’的差错检测码f(D’),如果接收到的差错检测码EDC‘!=f(D’),则可以判断传输的数据出现了差错,即检测出差错。

要注意是的是,接收方未检测出差错并不代表传输的数据中一定没有出现差错,但是出现差错的概率非常小。为了提高差错检测的检错率,可以使用更长的差错检测码和更复杂的算法,当然这也会导致更大的开销。

image-20221007203338641

帧检验序列:在数据链路层,为了便于硬件检测差错,通常会在帧的尾部设置一个差错检验字段存放整个帧(包含首部和数据)的差错检测码,整个差错检验字段常称为帧检验序列(Frame Check Sequence,FCS )。因此,要在数据链路层进行差错检验,就必须把数据划分为帧,每一帧都加上差错检测码,一帧一帧地传送,然后在接收方逐帧进行差错检验。

循环冗余检验:在数据链路层通常使用循环冗余检验(Cyclic Redundancy Check,CRC)技术进行差错检测。CRC编码的基本原理如图3-10所示。发送方和接收方首先必须协商一个r+1比特生成式G。算法要求G的最高位和最低位的比特为1。考虑d比特的数据D,发送方要选择一个合适的r比特冗余码R(即检错码),并将它附加到D上,使得得到的d+r比特模式用模2算术敲好能被G整除。接收方进行差错检测时,用G去除接收到的d+r比特,如果余数非零则检测出差错,否则认为数据正确

image-20221007215625635

在模2算术中,加法不进位,减法不借位,等价于按位异或( XOR),乘以2和除以2等价于左/右移位。

公式表示为

以图3-10为例,假定等待传送的数据D=101001(d=6),G=1101(r=3),经过模2除法运。。,算后的结果:商Q=110101(这个商没有什么用处),而余数R=001。这个余数R就作为冗余码拼接在数据D的后面发送出去。因此完整发送帧为:101001001,有d+r比特

在接收端把接收的数据除以同样的出书生成式G(模2算术),然后检查得到的余数R。如果传输过程无差错,那个经过CRC后得到的余数R肯定为0。(按照上面的例子来说就是R:101001001/1101=0)

多项式编码:CRC也称为多项式编码,因为该编码能够将要发送的比特串看作0和1的一个多项式,对比特串的模2算术被解释为多项式算术。在上面的例子中可以用多项式G(X)=X^3^+X^2^+1表示生成式G=1101(最高位对应X^3^,最低为对应X^0^)。多项式G(X)称为生成多项式。

现在广泛使用的生成多项式G(X)有以下几种:

CRC-16=X^16^+X^15^+X^2^+1

CRC-CCITT=X^16^+X^12^+X^5^+1

CRC-32=X^32^+X^26^+X^23^+X^22^+X^16^+X^12^+X^11^+X^10^+X^8^+X^7^+X^5^+X^4^+X^2^+X+1

CRC有很好的检错能力,虽然计算比较复杂,但非常容易于硬件实现,因此被广泛应用于现代计算机网络的数据链路层。在数据链路层,发送FCS的生成和接收端CRC完全用硬件完成,处理很快,对数据传输的延误非常少。

凡是接收端数据链路层接收的层均无差错

使用CRC这样的差错检测技术,只能检测出帧在传输中过程中出现了差错,并不能纠正错误。虽然任何差错检测技术都无法做到检测出所有差错,但是通常我们认为:凡是接收端数据链路层通过差错检测接收的帧,我们都能以非常接近1的概率认为这些帧在传输过程中没有产生差错。接收丢弃的帧虽然曾经收到,但是最终还是因为有差错被丢弃,即没有被接受。上述原则可以近似地表述为:凡是接收端数据链路层接受的帧均无差错。

向前纠错FEC:想要纠正传输中的差错可以使用冗余信息更多的纠错码(Error-Correcting Code)进行向前纠错(Forward Error Correction, FEC)。通过纠错码能检测数据中出现差错的具体位置,从而纠正错误。由于纠错码要发送更多冗余信息,开销非常大,在计算机网络中较少使用。