• 【计算机网络系列】数据链路层①:数据链路层的三个基本问题(封装成帧、透明传输和差错检测)



    数据链路层最重要的内容是:

    • 数据链路层的点对点信道广播信道的特点,以及这两种信道所使用的协议(PPP协议以及CSMA/CD协议)的特点。
    • 数据链路层的三个基本问题:封装成帧透明传输差错检测
    • 以太网MAC层硬件地址
    • 适配器转发器集线器网桥以太网交换机的作用以及使用场合。

    本文主要介绍数据链路层的三个基本问题,包括封装成帧、透明传输和差错检测。


    由于是数据链路层的第一篇文章,我们首先来简单学习一些数据链路层的基础的知识,先对数据链路层有一定的了解。

    数据链路层属于计算机网络低层。数据链路层使用的信道主要有以下两种类型:

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

    局域网虽然是个网络,但我们并不把局域网放在网络层中讨论。这是因为在网络层要讨论的问题是多个网络互连的问题,是讨论分组怎样从一个网络,通过路由器,转发到另一个网络。在本章中我们研究的是在同一个局域网中,分组怎样从一台主机传送到另一台主机,但并不经过路由器转发

    从整个互联网来看,局域网仍属于数据链路层的范围

    下面看一下两台主机通过互联网进行通信时数据链路层(简称为链路层)所处的地位。
    在这里插入图片描述

    上图表示用户主机 H 1 H_1 H1通过电话线上网,中间经过三个路由器( R 1 R_1 R1 R 2 R_2 R2 R 3 R_3 R3)连接到远程主机 H 2 H_2 H2。所经过的网络可以是多种的,如电话网、局域网和广域网。当主机 H 1 H_1 H1 H 2 H_2 H2发送数据时,从协议的层次上看,数据的流动如上图下方所示。主机 H 1 H_1 H1 H 2 H_2 H2都有完整的五层协议栈,但路由器在转发分组时使用的协议栈只有下面的三层。数据进入路由器后要先从物理层上到网络层,在转发表中找到下一跳的地址后,再下到物理层转发出去。因此,数据从主机 H 1 H_1 H1传送到主机 H 2 H_2 H2需要在路径中的各节点的协议栈向上和向下流动多次,如图中箭头所示。

    然而当我们专门研究数据链路层的问题时,在许多情况下我们可以只关心在协议栈中水平方向的各数据链路层。于是,当主机 H 1 H_1 H1 H 2 H_2 H2发送数据时,我们可以想象数据就是在数据链路层从左向右沿水平方向传送,通过以下这样的链路:

    H 1 H_1 H1的链路层→ R 1 R_1 R1的链路层→ R 2 R_2 R2的链路层→ R 3 R_3 R3的链路层→ H 2 H_2 H2的链路层

    在这里插入图片描述

    上图指出,从数据链路层来看, H 1 H_1 H1 H 2 H_2 H2的通信可以看成由四段不同的链路层通信组成,即: H 1 → R 1 H_1\rightarrow R_1 H1R1 R 1 → R 2 R_1\rightarrow R_2 R1R2 R 2 → R 3 R_2\rightarrow R_3 R2R3 R 3 → H 2 R_3\rightarrow H_2 R3H2这四段不同的链路层可能采用不同的数据链路层协议

    数据链路层的几个共同问题

    数据链路和帧

    我们在这里要明确一下,“链路”和“数据链路”并不是一回事。

    • 所谓链路(link)就是从一个节点到相邻节点的一段物理线路(有线或无线),而中间没有任何其他的交换节点。在进行数据通信时,两台计算机之间的通信路径往往要经过许多段这样的链路。可见链路只是一条路径的组成部分
    • 数据链路(data link)则是另一个概念。这是因为当需要在一条线路上传送数据时,除了必须有一条物理线路外,还必须有一些必要的通信协议来控制这些数据的传输。若把实现这些协议的硬件和软件加到链路上,就构成了数据链路。现在最常用的方法是使用网络适配器(既有硬件,也包括软件)来实现这些协议。一般的适配器都包括了数据链路层和物理层这两层的功能。

    也有人采用另外的术语。这就是把链路分为物理链路和逻辑链路。

    • 物理链路就是上面所说的链路,
    • 逻辑链路就是上面的数据链路,是物理链路加上必要的通信协议。

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

    点对点信道数据链路层协议数据单元

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

    为了把主要精力放在点对点信道的数据链路层协议上,可以采用如下图(a)所示的三层模型。在这种三层模型中,不管在哪一段链路上的通信(主机和路由器之间或两个路由器之间),我们都看成是节点和节点的通信(如图中的节点A和节点B),而每个节点只有下三层—网络层数据链路层物理层
    在这里插入图片描述

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

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

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

    三个基本问题

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

    封装成帧

    封装成帧(framing)就是在一段数据的前后分别添加首部和尾部,这样就构成了一个帧

    接收端在收到物理层上交的比特流后,就能根据首部和尾部的标记,从收到的比特流中识别帧的开始和结束。下图表示用帧首部和帧尾部封装成帧的一般概念。

    • 分组交换的一个重要概念就是:所有在互联网上传送的数据都以分组(即IP数据报)为传送单位。网络层的IP数据报传送到数据链路层就成为帧的数据部分
    • 在帧的数据部分的前面和后面分别添加上首部和尾部,构成了一个完整的帧。这样的就是数据链路层的数据传送单元
    • 一个帧的帧长等于帧的数据部分长度加上帧首部和帧尾部的长度。
    • 首部和尾部的一个重要作用就是进行帧定界(即确定帧的界限)。
    • 此外,首部和尾部还包括许多必要的控制信息
    • 在发送帧时,是从帧首部开始发送的。
    • 各种数据链路层协议都对帧首部和帧尾部的格式有明确的规定。

    显然,为了提高帧的传输效率,应当使帧的数据部分长度尽可能地大于首部和尾部的长度。但是,每一种链路层协议都规定了所能传送的帧的数据部分长度上限——最大传送单元MTU (Maximum Transfer Unit)。下图给出了帧的首部和尾部的位置,以及帧的数据部分与MTU的关系。
    在这里插入图片描述

    当数据是由可打印的ASCI码组成的文本文件时,帧定界可以使用特殊的帧定界符。我们知道,ASCI码是7位编码,一共可组合成128个不同的ASCII码,其中可打印的有95个,而不可打印的控制字符有33个。下图的例子可说明帧定界的概念。

    • 控制字符SOH(Start Of Header)放在一帧的最前面,表示帧的首部开始
    • 控制字符EOT(End Of Transmission)表示帧的结束

    请注意,SOHEOT都是控制字符的名称。它们的十六进制编码分别是01(二进制是00000001)和04(二进制是00000100)。SOH(或EOT)并不是S,O,H(或E,O,T)三个字符。
    在这里插入图片描述

    当数据在传输中出现差错时,帧定界符的作用更加明显。假定发送端在尚未发送完一个帧时突然出故障,中断了发送。但随后很快又恢复正常,于是重新从头开始发送刚才未发送完的帧。由于使用了帧定界符,接收端就知道前面收到的数据是个不完整的帧(只有首部开始符SOH而没有传输结束符EOT),必须丢弃。而后面收到的数据有明确的帧定界符(SOHEOT),因此这是一个完整的帧,应当收下。

    透明传输

    由于帧的开始和结束的标记使用专门指明的控制字符,因此,所传输的数据中的任何8比特的组合一定不允许和用作帧定界的控制字符的比特编码一样,否则就会出现帧定界的错误

    • 当传送的帧是用文本文件组成的帧时(文本文件中的字符都是从键盘上输入的),其数据部分显然不会出现像SOHEOT这样的帧定界控制字符。可见不管从键盘上输入什么字符都可以放在这样的帧中传输过去,因此这样的传输就是透明传输
    • 但当数据部分是非ASCII码的文本文件时(如二进制代码的计算机程序或图像等),情况就不同了。如果数据中的某个字节的二进制代码恰好和SOHEOT这种控制字符一样(如下图所示),数据链路层就会错误地“找到帧的边界”,把部分帧收下(误认为是个完整的帧),而把剩下的那部分数据丢弃(这部分找不到帧定界控制字符SOH)。

    在这里插入图片描述

    像上图所示的帧的传输显然就不是“透明传输”,因为当遇到数据中碰巧出现字符“EOT”时就传不过去了。数据中的“EOT”将被接收端错误地解释为“传输结束”的控制字符,而在其后面的数据因找不到“SOH”被接收端当作无效帧而丢弃。

    但实际上在数据中出现的字符“EOT”并非控制字符而仅仅是二进制数据00000100。前面提到的“透明”是一个很重要的术语。它表示:某一个实际存在的事物看起来却好像不存在一样(例如,你看不见在你前面有块100%透明的玻璃的存在)。“在数据链路层透明传送数据”表示无论什么样的比特组合的数据,都能够按照原样没有差错地通过这个数据链路层。因此,对所传送的数据来说,这些数据就“看不见”数据链路层有什么妨碍数据传输的东西。或者说,数据链路层对这些数据来说是透明的

    为了解决透明传输问题,就必须设法使数据中可能出现的控制字符“SOH”和“EOT"在接收端不被解释为控制字符。具体的方法是:发送端的数据链路层在数据中出现控制字符“SOH”或“EOT”的前面插入一个转义字符“ESC”(其十六进制编码是1B,二进制是00011011)。而在接收端的数据链路层在把数据送往网络层之前删除这个插入的转义字符。这种方法称为字节填充(byte stuffing)或字符填充(character stuffing)。

    如果转义字符也出现在数据当中,那么解决方法仍然是在转义字符的前面插入一个转义字符。因此,当接收端收到连续的两个转义字符时,就删除其中前面的一个。下图表示用字节填充法解决透明传输的问题。
    在这里插入图片描述

    差错控制

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

    在一段时间内,传输错误的比特占所传输比特总数的比率称为误码率BER(Bit Error Rate)。实际的通信链路并非是理想的,它不可能使误码率下降到零。

    因此,为了保证数据传输的可靠性,在计算机网络传输数据时,必须采用各种差错检测措施。目前在数据链路层广泛使用了循环冗余检验CRC(Cyclic Redundancy Check)的检错技术。

    • 本小节所说的“差错”,如无特殊说明,就是指“比特差错”。
    • 误码率为 1 0 − 10 10^{-10} 1010时,表示平均每传送 1 0 10 10^{10} 1010个比特就会出现一个比特的差错。误码率与信噪比有很大的关系。如果设法提高信噪比,就可以使误码率减小。

    下面我们通过一个简单的例子来说明循环冗余检验的原理。

    在发送端,先把数据划分为组,假定每组 k k k个比特。现假定待传送的数据 M = 101001 M = 101001 M=101001( k = 6 k = 6 k=6)。CRC运算就是在数据 M M M的后面添加供差错检测用的 n n n位冗余码,然后构成一个帧发送出去,一共发送 k + n k + n kn位。在所要发送的数据后面增加 n n n位的冗余码,虽然增大了数据传输的开销,但却可以进行差错检测。当传输可能出现差错时,付出这种代价往往是很值得的。

    n n n位冗余码可用以下方法得出:用二进制的模2运算进行 2 n 2^n 2n M M M的运算,这相当于在 M M M后面添加 n n n个0。得到的 k + n k + n kn位的数除以收发双方事先商定的长度为 n + 1 n + 1 n+1位的除数 P P P,得出商是 Q Q Q而余数是 R R R( n n n位,比 P P P少一位)。

    在下图所示的例子中, M = 101001 M = 101001 M=101001(即 k = 6 k=6 k=6)。假定除数 P = 1101 P= 1101 P=1101(即 n = 3 n = 3 n=3)。经模2除法运算后的结果是:

    • Q = 110101 Q= 110101 Q=110101(这个商并没有什么用处),
    • 而余数 R = 001 R = 001 R=001,这个余数 R R R就作为冗余码拼接在数据 M M M的后面发送出去。

    这种为了进行检错而添加的冗余码常称为帧检验序列FCS(Frame Check Sequence)。因此加上FCS后发送的帧是101001001(即 2 n M + FCS 2^nM + \text{FCS} 2nMFCS),共有 k + n k+ n kn位。
    在这里插入图片描述

    注意:

    • 用模2运算进行加法时不进位,例如,1111+1010=0101。减法和加法一样,按加法规则计算。
    • 循环冗余检验CRC和帧检验序列FCS并不是同一个概念。CRC是一种检错方法,而FCS是添加在数据后面的冗余码,在检错方法上可以选用CRC,但也可不选用CRC。

    在接收端把接收到的数据以帧为单位进行CRC检验:把收到的每一个帧都除以同样的除数 P P P(模2运算),然后检查得到的余数 R R R

    • 如果在传输过程中无差错,那么经过CRC检验后得出的余数 R R R肯定是0。被除数现在是101001001,而除数是 P = 1101 P=1101 P=1101,看余数 R R R是否为0)。
    • 但如果出现误码,那么余数 R R R仍等于零的概率是非常非常小的。

    总之,在接收端对收到的每一帧经过CRC检验后,有以下两种情况:

    • 若得出的余数 R = 0 R=0 R=0,则判定这个帧没有差错,就接受(accept)。
    • 若余数 R ≠ 0 R≠0 R=0,则判定这个帧有差错(但无法确定究竟是哪一位或哪几位出现了差错),就丢弃。

    一种较方便的方法是用多项式来表示循环冗余检验过程。在上面的例子中,用多项式 P ( X ) = X 3 + X 2 + 1 P(X) = X^{3}+X^2+1 P(X)=X3+X2+1表示上面的除数 P = 1101 P= 1101 P=1101 (最高位对应于 X 3 X^3 X3,最低位对应于 X 0 X^0 X0)。多项式 P ( X ) P(X) P(X)称为生成多项式。现在广泛使用的生成多项式 P ( X ) P(X) P(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-16=X16+X15+X2+1CRC-CCITT=X16+X12+X5+1CRC-32=X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X+1" role="presentation">CRC-16=X16+X15+X2+1CRC-CCITT=X16+X12+X5+1CRC-32=X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X+1
    CRC-16CRC-CCITTCRC-32=X16+X15+X2+1=X16+X12+X5+1=X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X+1

    在数据链路层,发送端帧检验序列FCS的生成接收端的CRC检验都是用硬件完成的,处理很迅速,因此并不会延误数据的传输。

    从以上的讨论不难看出,如果我们在传送数据时不以帧为单位来传送,那么就无法加入冗余码以进行差错检验。因此,如果要在数据链路层进行差错检验,就必须把数据划分为帧,每一帧都加上冗余码,一帧接一帧地传送,然后在接收方逐帧进行差错检验

    最后再强调一下, 在数据链路层若仅仅使用循环冗余检验CRC差错检测技术,则只能做到对帧的无差错接受,即:“凡是接收端数据链路层接受的帧,我们都能以非常接近于1的概率认为这些帧在传输过程中没有产生差错”。接收端丢弃的帧虽然曾收到了,但最终还是因为有差错被丢弃,即没有被接受。以上所述的可以近似地表述为(通常都是这样认为):“凡是接收端数据链路层接受的帧均无差错”。

    请注意,我们现在并没有要求数据链路层向网络层提供“可靠传输”的服务。所谓“可靠传输”就是:数据链路层的发送端发送什么,在接收端就收到什么。传输差错可分为两大类:一类就是前面所说的最基本的比特差错;另一类传输差错则更复杂些,这就是收到的帧并没有出现比特差错,但却出现了帧丢失帧重复帧失序。例如,发送方连续传送三个帧: [#1]-[#2]-[#3]。 假定接收端收到的每一个帧都没有比特差错,但却出现下面的几种情况:

    • 帧丢失:收到[#1]-[#3](丢失[#2])。
    • 帧重复:收到[#1]-[#2]-[#2]-[#3](收到两个[#2])。
    • 帧失序:收到[#1]-[#3]-[#2](后发送的帧反而先到达了接收端,这与一般数据链路层的传输概念不一样)。

    以上三种情况都属于“出现传输差错”,但都不是这些帧里有“比特差错”。我们应当明确,“无比特差错”与“无传输差错”并不是同样的概念。在数据链路层使用CRC检验,能够实现无比特差错的传输,但这还不是可靠传输。

    我们知道,过去OSI的观点是:必须让数据链路层向上提供可靠传输。因此在CRC检错的基础上,增加了帧编号确认重传机制。收到正确的帧就要向发送端发送确认。发送端在一定的期限内若没有收到对方的确认,就认为出现了差错,因而就进行重传,直到收到对方的确认为止。这种方法在历史上曾经起到很好的作用。但现在的通信线路的质量已经大大提高了,由通信链路质量不好引起差错的概率已经大大降低。因此,现在互联网就采取了区别对待的方法:

    • 对于通信质量良好的有线传输链路,数据链路层协议不使用确认和重传机制,即不要求数据链路层向上提供可靠传输的服务。如果在数据链路层传输数据时出现了差错并且需要进行改正,那么改正差错的任务就由上层协议(例如,运输层的TCP协议)来完成
    • 对于通信质量较差的无线传输链路,数据链路层协议使用确认和重传机制,数据链路层向上提供可靠传输的服务

    实践证明,这样做可以提高通信效率。

  • 相关阅读:
    数据库的基本操作
    《算法竞赛进阶指南》 临值查找
    pcba完整新工艺流程来了
    Kotlin高仿微信-第21篇-个人信息-修改头像
    任务长期不释放和占用单节点持续的cpu,导致hivesever2本身内存泄漏造成
    基于自监督学习的多模态推荐算法
    这是什么代码帮我看看
    集合Set
    HDFS工作流程和机制
    v-bind动态绑定style(数组)
  • 原文地址:https://blog.csdn.net/qq_37085158/article/details/127959708