数据链路层属于计算机网络的底层。数据链路层使用的信道主要有有以下两种类型:
(1)、点对点信道。这种信道使用一对一的点对点通信方式。
(2)、广播信道。这种信道使用一对多的广播通信方式。广播信道上连接的主机很多,因此必须使用专门的共享信道协议来协调这些主机的数据发送。
一、使用点对点信道的数据链路层
链路就是从一个节点到相邻节点的一段物理线路,而中间没有任何其他的交换结点。在进行数据通信时,两个计算之间的通信线路往往要经过许多段这样的链路。
数据链路除了必须有一条物理线路外,还必须有一些必要的通信协议来控制这些数据的传输。若把实现这些协议的硬件和软件加到这些链路上就构成了数据链路。
数据链路层把网络层浇下来的数据构成帧发送到链路上,以及把接收到的帧中的数据取出来并交给网络层。在因特网中,网络层协议数据单元就是IP数据包(或简称为数据报、分组或包)。
如图所示的三层模型,主要采用的点对点信道的数据链路层。在这三层模型中,不管在那一段链路上的通信(主机和路由器之间 或 两个路由器之间),我们都看成是结点和结点的通信(如图中的结点A和B),而每个结点只有下三层——网络层、数据链路层和物理层。
点对点行道的数据链路层在进行通信时的主要步骤如下:
1、结点A的数据链路层把网络层浇下来的IP数据报添加首部和尾部封装成帧。
2、结点A把封装好的帧发送给结点B的数据链路层。
3、若结点B的数据链路层收到的帧无差错,则从收到的帧中提取出IP数据报上交给上面的网络层,否则丢弃这个帧。
数据链路层不必考虑物理层如何实现比特传输的细节,因为他们彼此是分工互不干扰的。所以就好像是沿着两个数据链路层之间的水平方向把帧直接发送到对方。
二、三个基本问题
数据链路层协议有许多种,但有三个基本问题则是共同的,这个三个基本问题是:封装成帧、传输透明和差错检测。
1、封装成帧(framing)就是在一段数据的前后分别添加首部和尾部,这样就构成了一个帧。接收端在收到物理层上交的比特流之后,就能根据首部和尾部的标记,从收到的比特流中识别帧的开始和结束,如下图所示就是封装成帧的过程。
我们知道分组交换的一个重要的概念就是:所有在因特网上传送的数据都是以分组(即IP数据报)为传送单位。网络层的IP数据报传送到数据链路层就成为帧的数据部分。在帧的数据部分的前面和后面分别添加上首部和尾部,就构成了一个完整的帧。帧的首部和尾部的一个重要作用就是进行帧定界(即确定帧的界限)。此外,首部和尾部还包括许多必要的控制信息。在发送帧是,是从帧首部开始发送。各种数据链路层协议都要对帧首部和帧尾部的格式有明确的规定。
当数据在传输中出现差错时,帧定界符的作用更加明显。假定发送端在尚未发送完一个帧时突然出现故障,中断了发送。但随后很快又恢复正常,于是头开始发送刚才未发送完的帧。由于使用了帧定界符。在接收端就知道前面接受的数据是个不完整的帧(只有首部开始符SOH而没有传输结束符EOT),就会丢弃这个帧。而后面收到的数据有明确的帧定界符(SOH和EOT),因此这是一个完整的帧,接收端就会收下这个帧。
2、透明传输
由于帧的开始和借宿的标记是使用专门指明的控制字符,因此,所传输的数据中的任何8比特的组合一定不允许和用作帧定界的控制字符的比特编码一样,否则就会出现帧定界的错误。
当传送的帧是用文本文件组成的帧时,其数据部分显然不会出现像SOH或EOT这样的帧定界控制字符。可见不管从键盘上输入什么字符都可以放在这样的帧中传输过去,因此这样的传输就是透明传输。
但当数据部分时非ASCII码的文本文件时(如二进制代码的计算机程序或图像等)。如果数据中的某个字节的二进制代码恰好和SOH或EOT这种控制字符一样,数据链路层就会错误地“找到帧的边界”,把部分帧手下(误认为这是一个完整的帧),而把剩下的那部分数据丢弃(这部分找不到帧定界控制支付SOH)。
像上图所示的帧传输就不是“透明传输”,中间出现的字符“EOT”并非控制字符而仅仅时二进制数据000001000。为了解决透明传输问题,就必须设法使数据中可能出现的控制字符“SOH”和“EOT”在接收端不被解释为控制字符。
具体的方法是:发送端的数据链路层在数据中出现控制字符的数据链路层在将数据送往网络层之间删除这个插入的转义字符。这种方法称为字节填充或字符填充。如果在数据中也出现转义字符,那么解决的方法仍然是在转义字符的前面插入一个转移字符。因此,当接收端收到连续的两个转义字符时,就删除其中前面的一个。如下图表示用字节填充法解决透明传输的问题。
3、差错检测
数据在链路传输的过程也不是绝对理想的。也就是说,比特在传输过程中可能会产生差错:1、可能会变成0,而0也可能变成1。这就叫做“比特差错”。比特差错时传输差错中的一种。为了保证数据传输的可靠性,在计算机网络传输数据时,必须采用各种差错检测措施。目前在数据链路层广泛使用了“循环冗余检验CRC(Cyclic Redundancy Check)的检错技术”。
顺便说以下,循环冗余检验CRC和帧检验序列FCS并不是同一个概念。CRC是一种检错方法,而FCS是添加在数据后面的冗余码,在检错方法上可以选用CRC,但也可不选用CRC。
在接收端把接收到的数据以帧为单位进行CRC检验:把收到的每一个帧都除以同样的数P(模2运算),然后检查得到的余数R。如果在传输过程中无擦错,那么经过CRC检验后得出的余数R等于零;但如果出现误码,那么余数R不等于零(等于0的概率是非常非常小的)
在数据链路层,发送端帧检验序列FCS的生成和接收端的CRC检验都是用硬件完成的,处理很迅速,因此并不会延误数据的传输。
从以上的讨论不难看出,如果我们在传送数据时不以帧为单位来传送,那么就无法加入冗余码进行差错检验。因此,如果要在数据链路层进行差错检验,就必须把数据划分为帧,每一帧都加上冗余码,一帧接一帧地传送,然后再接收方逐帧进行差错检验。
最后强调以下,再数据链路层若仅仅使用循环冗余检验CRC差错检测技术,则只能做到对帧的无差错接受,即“凡是接收端接数据链路层接受的帧,我们几乎可以认为这些帧再传输过程中没有产生差错”。接收端丢弃的帧虽然曾收到了,但最终还是因为有差错被丢弃,即没有被接受。
注意,我们现在并没有要求数据链路层向网络层提供“可靠传输”的服务。所谓“可靠传输”就是:数据链路层的发送端发送什么,在接收端就收到什么。传输差错可以分为两大类:一类就是前面所说的最基本的比特差错,而另一类传输差错出现帧丢失、帧重复、帧失序。例如发送方连续传送三个帧[01]-[02]-[03]。接收端收到的可能出现下面的情况:
帧丢失:收到[01]-[03] (丢失了一个帧)
帧重复:收到[01]-[02]-[02]-[03] (接收到了重复的帧)
帧失序:收到[01]-[03]-[02] (接收的顺序发生了改变)
所以OSI为了能将数据链路层做成是可靠传输的。因此在CRC检错的基础上,增加了帧编号、确认和重传机制。收到正确的帧就要向发送端发送确认,如果发送端在一定的期限内没有接收到对方的确认帧,就认为传输的过程中出现了差错,因而就进行重传,知道收到对方的确认为止。这种方法在历史上曾经起到很好的作用,但现在的通信线路的质量已经大大提高了。因此,在考虑所符出的代价太高、不合算等原因之后,数据链路层协议都不使用确认和重传机制,即不要求数据链路层向上提供可靠的传输服务。如果在数据链路层传输数据时出现了差错并需要进行改正,那么改正错误的任务就由上层协议(例如,运输层的TCP协议)来完成。实践证明,这样做可以提高通信效率。
三、以太网的MAC层的硬件地址
在局域网中,硬件地址又成为物理地址或MAC地址(这种地址用在MAC帧中)。IEEE 802标准为局域网规定了一种48位的全球地址,是指局域网上的每一台计算机中固化在适配器的ROM中的地址。
常见的以太网MAC帧格式有两种标准,一种是DIX Ethernet V2标准,另一种是IEEE的802.3标准(这里只介绍使用得最多的以太网V2的MAC帧格式)。以太网V2的MAC帧比较为简单,由五个字段组成。前2个字段分别为6个字节长度的目的地址和源地址字段。第三个字段是2字节的类型字段,用来标志上一层使用的是什么协议,以便把收到的MAC帧的数据上交给上一层的这个协议。第四个字段是数据字段,其长度在46~1500字节之间(46字节是最小长度64字节减去18字节的首部和尾部就得出数据字段的最小长度)。最后一个字段是4字节的帧检验序列FCS(使用CRC检验)。