禁止码迷,布布扣,豌豆代理,码农教程,爱码网等第三方爬虫网站爬取!
目录
- 链路层信道
- 网络适配器
- 封装成帧
- 透明传输
- 差错检测
- 奇偶校验
- 校验和方法
- 循环冗余检测
- 参考资料
链路层信道
数据链路层使用的信道主要有两种类型,一种是点对点信道,这种信道使用一对一的点对点通信方式。
链路(link)是一条无源的点到点的物理线路段,中间没有任何其他的交换结点,一条链路只是一条通路的一个组成部分。数据链路(data link)除了物理线路外,还必须有通信协议来控制这些数据的传输。若把实现这些协议的硬件和软件加到链路上,就构成了数据链路。点对点信道的链路层在通信时的步骤为:
- 结点 A 的数据链路层把网络层交付的 IP 数据报添加首部和尾部封装成帧;
- 结点 A 把封装好的帧发给结点 B 的数据链路层;
- 若结点 B 的数据链路层收到的帧无差错,则从收到的帧中提取出 IP 数据报交付给网络层,否则丢包。
数据链路层不必考虑物理层如何实现比特传输的细节,甚至还可以更简单地设想好像是沿着两个数据链路层之间的水平方向把帧直接发送到对方。
网络适配器
数据链路层是在哪里实现呢?链路层的主体部分是在网络适配器,也可以称之为网络接口卡。位于网络配适器的核心是链路层控制器,该控制器是一个实现许多链路层服务的专用芯片。网络适配器是实现链路层协议的硬件和软件的结合体,一般的适配器都包括了数据链路层和物理层这两层的功能。
在发送端,控制器取得了有协议栈较高层生成并存储在主机内存的数据报,在链路层封装数据报,然后遵循链路层接入协议将帧传入链路层中。接收端控制器接收了整个帧,抽取出网络层数据报。
链路层需要解决三个问题:封装成帧、透明传输和差错检测。
封装成帧
封装成帧(framing)就是在一段数据的前后分别添加首部和尾部,然后就构成了一个帧,首部和尾部的一个重要作用就是进行帧定界。
当数据是由可打印的 ASCII 码组成的文本文件时,帧定界可以使用特殊的帧定界符。控制字符 SOH (Start Of Header) 放在一帧的最前面表示帧的首部开始,另一个控制字符 EOT (End Of Transmission) 表示帧的结束。
当帧出现差错时,接收端就可以根据帧界定符判断出收到的数据是不完整的帧,这时就可以主动丢弃了。
透明传输
考虑一个情况,如果数据中的某个字节的二进制代码恰好和 SOH 或 EOT 一样,数据链路层就会错误地“找到帧的边界”。
这个问题的解决方法是字节填充(byte stuffing)或字符填充(character stuffing),发送端的数据链路层在数据中出现控制字符“SOH”或“EOT”的前面插入一个转义字符“ESC” (其十六进制编码是 1B)。接收端的数据链路层在将数据送往网络层之前,删除插入的转义字符。如果转义字符也出现在数据当中,那么应在转义字符前面插入一个转义字符 ESC。当接收端收到连续的两个转义字符时,就删除其中前面的一个。
差错检测
在传输过程中可能会产生比特差错:1 可能会变成 0 而 0 也可能变成 1。在一段时间内,传输错误的比特占所传输比特总数的比率称为误码率 BER (Bit Error Rate)。这种比特差错时由信号衰减和电磁噪声导致了,因此与信噪比有很大的关系。为了保证数据传输的可靠性,在计算机网络传输数据时,必须采用各种差错检测措施,通常是使用差错检测和纠正比特(EDC)实现。当链路层检测到差错时,可以通知发送方重传或直接丢帧来保证可靠。
奇偶校验
奇偶检验是使用单个奇偶校验位实现的校验,是差错检测中最简单的方式。假设发送的信息有 d 个比特,奇偶校验只需要附加一个比特。奇偶校验位的取值,应该使得 d + 1 个比特中 1 的总数是偶数。该方式对于接收方而言操作也很简单,只需要数一下收到的 d + 1 个比特中 1 的数目即可,若数出来 1 的数目是偶数,则知道帧至少出现了一个比特差错。
但如果出现偶数个比特差错,这种方式可能就检查不出了,因此后来就提出了更加健壮的奇偶检验法。二维奇偶校验将 D 中的 d 个比特划分为 i 行 j 列,对每行和每列都计算奇偶值。
当 d 比特信息中信息出现了单个比特差错,则包含比特值改变的行和列都会出现差错。接收方不仅能够发现,而且能通过 i 和 j 索引进行纠正。
校验和方法
校验和方法将 d 比特数据,认为是一个 k 比特整数的序列处理。校验的方法就是将 k 比特整数加起来,并且用得到的和作为差错检验比特。接收方通过对接收的数据(包括校验和)求和取反码,若这些比特中有任何比特是 0 就表示出差错。
然而在实际应用中,链路层广泛使用的是 CRC 检测,而校验和被应用于运输层,为什么这么安排呢?因为运输层的差错检测用软件实现,校验和在软件中实现更为简单而快速。链路层的差错检测在配适器中用专用的硬件实现,它能够快速执行更复杂的 CRC 操作。
循环冗余检测
在数据链路层传送的帧中,广泛使用了循环冗余检验 CRC的检错技术。在发送端先把数据划分为组,假定每组 k 个比特。假设待传送的一组数据 M = 101001(现在 k = 6)。我们在 M 的后面再添加供差错检测用的 n 位冗余码一起发送。用二进制的模 2 运算进行 2n 乘 M 的运算,这相当于在 M 后面添加 n 个 0。得到的 (k + n) 位的数除以事先选定好的长度为 (n + 1) 位的除数 P,得出商是 Q 而余数是 R,余数 R 比除数 P 少 1 位,即 R 是 n 位。将余数 R 作为冗余码拼接在数据 M 后面,然后发送出去。
现在 k = 6, M = 101001,设 n = 3, 除数 P = 1101,被除数是 2nM = 101001000。模 2 运算的结果是:商 Q = 110101,余数 R = 001。把余数 R 作为冗余码添加在数据 M 的后面发送出去,发送的数据是:2nM + R,即:101001001,共 (k + n) 位。
接收端把收到的数据以真为单位进行 CRC 检验,把收到的每一个帧都除以同样的除数 P,检查得到的余数 R:
- 若得出的余数 R = 0,则判定这个帧没有差错,就接受 (accept)。
- 若余数 R != 0,则判定这个帧有差错,就丢弃。
但这种检测方法并不能确定,究竟是哪一个或哪几个比特出现了差错。只要经过严格的挑选,并使用位数足够多的除数 P,那么出现检测不到的差错的概率就很小很小。仅用循环冗余检验 CRC 差错检测技术只能做到无差错接受 (accept),指的是“凡是接受的帧(即不包括丢弃的帧),我们都能以非常接近于 1 的概率认为这些帧在传输过程中没有产生差错”。也就是说,凡是接收端数据链路层接受的帧都没有传输差错(有差错的帧就丢弃而不接受),因此要做到“可靠传输”(即发送什么就收到什么)就必须在上层协议使用确认和重传机制。