计算机网络 (3) 数据链路层-封装成帧、差错检测

本文引用代码及图片均来自 高军: 计算机网络

数据链路层主要解决主机编址以及数据分组的格式问题,使得数据可以在一个网络内流动

链路层涉及以下三个重要概念:

  1. 封装成帧
  2. 差错检测
  3. 可靠传输

本文介绍一和二部分

封装成帧

链路层以帧为单位向下层提供数据,它在网络层提供的数据首尾分别添加帧头和帧尾以便将数据封装成帧,帧头和帧尾中包含控制信息(如目的地址、差错检验码等)

image.png

不同协议帧头和帧尾不同,比如在以太网V2版本的MAC(Media Access Control)帧中,前三个字段是帧头,在PPP(Point to Point Protocol)帧中前四个字段是帧头。帧头和帧尾中间包着的就是网络层交付下来的数据,称为载荷

image.png

image.png

帧边界

物理层将帧所代表的比特流转换成电信号发送出去,接收端接收到信号后再将其转换成比特流,那么接收端如何从比特流中区分出一个个的帧呢?

实际上帧头和帧尾的其中一个作用就是帧定界,如PPP帧中首尾字节都是标志字节,接收端检测到相应的连续比特后就能确定帧的边界

image.png

MAC帧中没有标志信息,物理层会为MAC帧添加前导码,前导码前七个字节用于同步时钟,最后一个字节用作起始标志。另外,由于MAC帧被规定有96比特帧间间隔,所以它不需要结束标志。当然,帧间间隔并不是专门用于省掉这个结束标志的,这个间隔时间可以让接收端有时间执行清除之前的帧缓存之类的操作

image.png

image.png

转义字符

如果帧载荷里有和起止标志(flag)一样的数据怎么办?比如某个帧以0001为起止标志,如果载荷里也有0001,那么接收端在遇到第二个0001时会误认为数据到达了帧的结束边界从而提前结束接收数据导致帧错误

image.png

链路层不能要求上层交付的数据中不包含和起止标志相同的信息,因为要发送什么数据是上层的自由,那么,这个问题只能在链路层解决

链路层检查载荷,如果出现和标志一样的数据就在其前面添加转义字符 ESC(Escape character),接收端在遇到转义字符的时候就知道接下来的标志信息是的,此时不会提前结束,同时会将转义字符丢弃。如果载荷里有和转义字符一样的数据呢?也同样在前面添加转义字符就行了

image.png

上述字符填充方案是面向字节的链路层协议使用的,对于面向比特的协议,它们使用的是比特填充,比如起止位组合01111110时,扫描载荷,每出现连续的5个1就填充0,接收端则将载荷中的每五个1后面的0丢弃

image.png

通过填充数据,链路层就解决了帧边界的识别问题

其他

像这样不对上层交付的数据做约束的行为其实还涉及到透明传输的概念

透明传输是指数据链路层对上层交付的传输数据没有任何限制,就好像链路层不存在一样

在传输时为了提高效率一般都要求帧的载荷部分尽可能大,载荷越大帧的首尾部占的比重就越小。当然了,这个大也是有限度的,每种协议中规定了载荷部分的长度上限,即最大传送单元 MTU (Maximum Transfer Unit)

image.png

差错检测

通信链路由于本身的问题或外界的干扰在传输数据的过程中有可能出现差错,比如0比特在传输过程中变成了1,这称为比特差错,一段时间内传输错误的比特数占总传输比特数的比率称为误码率BER(Bit Error Rate)

链路层怎么知道接收到的数据是否有误呢?其实它可以通过帧尾中的 FCS(Frame Check Sequence 帧校验序列)差错检测算法来判断数据是否有误。FCS是根据帧头和数据载荷算出来的,接收方根据接收到的数据再算一遍然后对比即可

image.png

下面简单介绍两种差错检测方法:

  1. 奇偶校验PC(Parity Check)
  2. 循环冗余校验CRC(Cyclic Redundancy Check)

奇偶校验

奇偶校验就是在待发送数据后面添加一位奇偶校验位,使整个数据(包括所添加的校验位)中比特1的个数为奇数(奇校验)偶数(偶校验)

奇校验位由待发送数据逐比特异或后的值再和1(奇校验)0(偶校验)异或得到,例:

待发送数据:101101
奇校验位 = 1⊕0⊕1⊕1⊕0⊕1⊕1 = 1
偶校验位 = 1⊕0⊕1⊕1⊕0⊕1⊕0 = 0
复制代码

接收方只需对数据整体(包括校验位)进行逐位异或看结果是否等于1(奇校验)0(偶校验)即可

奇偶校验实现起来很简单,但是,当出现多位错误时可能无法检出错误,漏检率很高,因此实际上很少使用

image.png

循环冗余检测

循环冗余检测需要先选定一个多项式,然后根据多项式和数据计算出冗余码,最后将差错检验码拼接到数据尾部

发送方 接收方
构造被除数:待发送数据后面添加生成多项式最高次数个0 构造被除数:接收到的数据就是被除数
构造除数:生成多项式各项系数构成的比特串 构造除数:生成多项式各项系数构成的比特串
做除法:异或 做除法:异或
检查余数:余数位数应于生成多项式做高次数相同,不够则补0 检查余数:余数为0则传输无误,否则有误码

下面直接以实例说明如何计算冗余码,假设待发送数据为101001,生成多项式为 G ( x ) = x 3 + x 2 + 1 {G(x) = x^{3} + x^{2} + 1}

image.png
  1. 构造被除数:多项式最高次为3,直接在待发送数据后面补3个0共同构成被除数 101001000
  2. 构造除数:多项式各项系数分别为:1 1 0 1,构成除数1101
  3. 做除法:二进制除法就是异或
  4. 检查余数:余数为1,多项式最高次为31前面补2个0构成余数(冗余码)

下面的例子多项式不变,接收方接收到的数据为101101001,该例算出来余数不为0,表明检测出错误

image.png

循环冗余检测的漏检率很低,虽然计算复杂,但很容易用硬件实现,因此被广泛用于链路层

链路层检测到帧有错误就直接丢弃该帧,如果链路层提供的是不可靠服务,那么帧丢弃后不会有其他动作。但如果链路层需要提供可靠服务,那么就需要通过其他手段通知发送方重新发送有误的帧

尽管误码不可避免,但若能实现发送方发送什么,接收方就能收到什么,就称为可靠传输

参考文献

猜你喜欢

转载自juejin.im/post/7126713068259639327