计算机网络读书笔记——数据链路层(1)

来源:互联网 发布:小清新记账软件 编辑:程序博客网 时间:2024/06/04 23:23

数据链路层的基本概念

数据发送模型
当主机H1向主机H2发送数据时,我们可以想象数据就是在数据链路层从左向右沿水平方向传送,物理层中我们通过频分复用、时分复用等解决了传输速率的问题,所以在链路层主要判断数据帧的开头和结尾,从而来识别发送过程中是否出现某些错误,如果出现错误就丢弃数据包,如果未出现错误就发送给网络层。图中的路由器就是网络层设备,根据发送的数据的网络地址来选择合适路径,然后重新封装到数据链路层,更改MAC地址并加上数据的帧头帧尾,再到物理层转换成比特流继续发送至下一个路由设备。

数据链路层的信道类型

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

  • 点对点信道,这种信道使用一对一的点对点通信方式。
  • 广播信道,这种信道使用一对多的广播通信方式,过程较复杂。广播信道上连接的主机很多,因此必须使用专用的共享信道协议来协调这些主机的数据发送。

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

点对点通信的数据链路层
由上图可以看出数据在网络层时给数据报加入了IP构成IP数据报,然后发送至数据链路层,为封装好的IP数据报再次封装加入帧头(SOH)帧尾(EOT)及校验和。

点对点信道的数据链路层在进行通信时的主要步骤:


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

注意:数据链路层不必考虑物理层如何实现比特流传输的细节。我们甚至可以更简单地设想好像是沿着两个数据链路层之间的水平方向把帧直接发送到对方。

数据链路层的三个基本问题

数据链路层协议有许多种,但是三个基本问题则是共同的。这三个基本问题是:封装成帧透明传输差错检测

封装成帧

封装成帧则是在一段数据的前后分别添加首部和尾部,这样就构成一个数据帧。我们知道,分组交换的一个重要概念就是:所有在因特网上传送的数据都是以分组(即IP数据报)为传送单位。网络层的IP数据报传送到数据链路层就成为帧的数据部分。在帧的数据部分的前面和后面分别添加上首部和尾部,构成了一个完整的数据帧。因此数据帧的长度等于数据部分长度加上帧首部和3尾部的长度,而首部和尾部的一个重要作用就是进行帧定界(即确定帧的界限),此外首部和尾部还包括许多必要的控制信息。为了提高帧的传输效率,应当使帧的数据部分长度尽可能地大于首部和尾部的长度,但每一种链路层协议都规定了帧的数据部分的长度上限——最大传送单元MTU(Maximum Transfer Unit)。如图:
用帧首部和帧尾部进行封装成帧

当数据是由可打印的ASCII码组成的文本文件时,帧定界可以使用特殊的帧定界符。我们知道,ASCII码是7位编码,一共可组合成128个不同的ASCII码,其中可打印的有95个,而不可打印的控制字符有33个(注:可打印的字符就是指可以从键盘上输入的字符,反之则为不可打印的控制字符),控制字符SOH(Start Of Header)放在一帧的最前面,表示帧的首部开始。另一个**控制字符EOT(End Of Transmission)表示帧的结束,SOH和EOT都是控制字符的名称,他们的十六进制编码分别是01(二进制是00000001)和04(二进制是00000100)。
用控制字符进行帧定界的方法举例
当数据在传输中出现差错时,帧定界符的作用更加明显。假定发送端在尚未发送完一个帧时突然出故障中断发送,但随后又恢复正常,于是重新从头开始发送刚才未发送完的帧。由于使用了帧定界符,在接收端就知道前面收到的数据是个不完整的帧(只有SOH而无EOT),所以必须丢弃,而恢复正常后接收到的数据有明确的帧定界符(SOH和EOT),因此是一个完整的帧,应当被收下。


透明传输

透明传输就是说发送的数据中不能包含帧定界符。若发送的是文本文件组成的帧(文本文件中的字符都是从键盘上输入的),其数据部分明显不会出现像SOH和EOT这样的帧定界控制字符,可见不管从键盘上输入什么字符都可以放在这样的帧中传输过去,因此这样的传输就是透明传输。但是当数据部分是二进制代码的计算机程序或图像时,则数据中的某个字节的二进制代码可能会恰好与SOH或EOT这种控制字符相同,数据链路层就会”错误地“找帧的边界,把部分帧误认为是完整的帧,而把剩下的部分丢弃掉。
错误找到帧边界

为了解决上述的透明传输问题,就必须设法使数据中可能出现的控制字符SOH和EOT在接收端不被解释为控制字符,具体方法是:发送端的数据链路层在数据中出现控制字符SOH或EOT的前面插入一个转义字符ESC(其十六进制编码是1B),而在接收端的数据链路层在将数据送往网络层之前删除这个插入的转义字符,这种方法称为字节填充。如果转义字符也出现在数据当中,那么解决方法仍然是在转义字符的前面插入一个转义字符,因此当接收端收到连续两个转义字符时,就删除其中前面的一个。下图即为用字节填充方法解决透明传输问题:
用字节填充解决透明传输问题


差错检测

在通信时有可能受到电磁干扰,比特在传输时可能会产生差错:1可能变成0,0可能变成1,这就叫做比特差错。比特差错是传输差错中的一种,这里所说的差错如无特殊说明就是指比特差错。在一段时间内传输错误的比特占所传输比特总数的比率称为误码率BER(Bit Error Rate),误码率与信噪比有很大的关系,如果设法提高信噪比,就可减小误码率。例如误码率为1010时,表示平均每传送1010个比特就会出现一个比特的差错。实际通信链路并非理想,所以误码率不可能为0,所以为保证数据传输可靠性,必须采取差错检测措施,目前在数据链路层广泛使用了循环冗余检测CRC(Cyclic Redundancy Check)的检错技术。
循环冗余检验的原理说明
上图中数101001即为要传输的数据,现在要发送一个有帧检验序列的数据(用于在接收端检验序列是否出现错误),为了得到帧检验序列,我们在原数据后加上n个0(图中n=3),然后除以一个任意的四位二进制数(例如图中除数为1101),除后的余数为001(因为n=3,所以为一个3位二进制数),这个001就是为了进行检错而表示的冗余码,称为帧检验序列FCS(Frame Check Sequence)。因此加上FCS后要发送的数据帧是101001001,此时原数据加上FCS后除以刚才的四位数除数1101,后余数若为0,则检验无差错。顺便说一下,循环冗余检验CRC和帧检验序列FCS并不是同一个概念,CRC是一种检错方法,而FCS是添加在数据后面的冗余码,在检错方法上可以选用CRC,但也可不选用CRC。

总之,在接收端对收到的每一帧经过CRC检验后:
(1)若得出的余数R=0,则判定这个帧没有差错,就接受。
(2)若余数R!=0,则判定这个帧有差错(但无法确定究竟是哪一位或哪几位出现了差错),就丢弃。
在数据链路层,发送端帧检验序列FCS的生成和接收端的CRC检验都是用硬件完成的,处理很迅速,因此并不会延误数据的传输。如果我们在传送数据时不以帧为单位来传送,那么就无法加入冗余码以进行差错检验。因此如果要在数据链路层进行差错检验,就必须把数据划分为帧,每一帧都加上冗余码,一帧接一帧地传送,然后在接收方逐帧进行差错检验。最后强调一下,在数据链路层若仅仅使用CRC差错检测技术,则只能做到对帧的无差错接受。传输差错可分为两大类:一类是前面所说的最基本的比特差错,而另一类则是更为复杂的传输差错,就是说收到的帧并没有出现比特差错,但却出现了帧丢失帧重复帧失序
假设原数据为1-2-3
1. 帧丢失:1-3(丢失2)
2. 帧重复:1-2-2-3(2重复)
3. 帧失序:1-3-2(后发送的帧反而先到达接收端)

以上三种情况都属于出现传输差错,但都不是这些帧里的比特差错。总之,我们应当明确,无比特差错与无传输差错并不是同样的概念。在数据链路层使用CRC检验,能够实现无比特差错的传输,但这还不是可靠传输。OSI的观点是必须把数据链路层做成是可靠传输的。因此在CRC检错的基础上,增加了帧编号、确认和重传机制。收到正确的帧就要向发送端发送确认。发送端在一定的期限内若没有收到对方的确认,就认为出现了差错,因而就进行重传,知道收到对方确认为止。但现在的通信线路质量已经大大提高,由通信链路质量不好引起的差错的概率已经大大降低。因此因特网广泛使用的数据链路层协议都不适用确认和重传机制,即不要求数据链路层向上提供可靠传输的服务(代价高,不合算)。如果在数据链路层传输数据时出现了差错并且需要进行改正,那么改正差错的任务就由上层协议(例如运输层的TCP协议)来完成,实践证明这样做可以提高通信效率