计算机网络是很重要的一部分知识,之前也认为很难,因为要分那么多层(五层或七层),而且每一层还有自己的功能和协议,一大堆的东西很不好学;但是后来发现了一个很好的学习方法,就是先熟悉每一层的作用,然后再顺着思考他为了实现这个功能要怎么办?要使用哪些协议?这样不仅能帮助很好的理解,也能很高效的去学习。
首先,了解过计算机网络的同学都知道,计算机网络的每一层都是基于下层提供的服务为上层提供服务的,所以数据链路层是在物理层提供的服务上向网络层提供服务的;因此数据链路层的作用是将源自网络层来的数据可靠地传输到相邻节点的目标机网络层,简单的说就是把上层(网络层)给我数据传输给目标计算机的网络层。那么,为了达到这一目的,数据链路层应该具备一系列的功能:如何将数据组合成数据块;如何控制帧在物理信道上的传输,包括如何处理传输差错,如何调节发送速率以使之与接收方相匹配;在两个网路实体之间提供数据链路通路的建立、维持和释放管理。其具体表现为一下这些方面。
封装成帧
组合成数据块?我们都知道数据链路层的传输单位是帧,那么解决的办法就是将网络层传来的数据封装成帧。
封装成帧就是在一段数据的前后分别添加首部和尾部,让其构成一个帧。接收端在收到物理层上交的比特流后,就可以根据帧首部和尾部的标记找到帧;如图所示:
从图中我们可以看出来,帧的数据部分越是大于帧首部和帧尾部传输的效率就会越高;因此, 为了提高帧的传输效率,通常会使使帧的数据部分长度尽量大于首部和尾部的长度,但是帧数据的部分也不是无限大的,肯定要有一个最大值来对其进行限制,那就是MTU(最大传输单元),决定了帧数据部分长度上限。
当数据是由可打印的ASCII码组成的文本文件时,帧定界可以使用特殊的帧定界符。通常,帧首部和帧尾部也会有特定的控制字符,控制字符**SOH(start of header,二进制是00000001)放在一帧的最前面,表示帧的首部开始。另一个控制字符EOT(end of transmission,二进制是00000100)**表示帧的结束。
采用帧传输方式的好处是,在发现有数据传送错误时,只需将有差错的帧再次传送,而不需要将全部数据的比特流进行重传,这就在传送效率上将大大提高。
透明传输
透明传输也是数据链路层的一个重点,但是什么是透明传输?又该怎么理解呢?这个定义看似简单,如果不明白的话就会疑惑为什么是透明?是怎样透明的?透明传输表示无论什么样的比特组合的数据,都能按照原样没有差错的通过这个数据链路层,就是无论所传的数据是什么样的比特组合,都可以进行传送;并不是说传送数据的是“透明的”,就好像现在现在的快递一样,快递小哥负责给你派送包裹,但是他并不管你的包裹里面是什么东西(前提必须是合法的呀)。
那么问题来了,这样难道就不会出现问题吗?当然是会的。通常会出现这两个问题:
- 由于帧的开始和结束的标记是使用专门指明的控制字符,如果所传的数据中存在一个和帧定界字符比特编码一样的,那么读取的时候就会出现错误;
- 当传送的帧使用文本文件组成的帧时(文本文件中的字符都是从键盘上输入的),其数据部分显然不会出现像SOH或EOT这样的帧定界控制字符。
既然透明传输会出现问题,那我们就一定要有防范的措施,那就是在组帧的时候进行一些处理,避免这些情况,具体方法有四种。
字符计数法
帧首部使用一个计数字段( 第一个字节,八位 )来标明帧内字符数
使用这种方法一定要确保计数字段的准确性,否则将造成严重的后果
字符填充法
当传送的帧是由非ASCI码的文本文件组成时( 二进制代码的程序或图像等 )。就要采用 字符填充 方法实现透明传输;如果所传的数据中有与帧定界符一样时,就在前面填充ESC,这种方式和 Java 里面的的转义字符很相似,具体实现过程如下;
零比特填充法
在发送端,扫描整个信息字段,只要连续5个1,就立即填入1个0;在接收端收到一个帧时,先找到标志字段确定边界,再用硬件对比特流进行扫描。发现连续5个1时,就把后面的0删除。
违规编码法
由于字节计数法中Count字段的脆弱性(其值若有差错将导致灾难性后果)及字符填充实现上的复杂性和不兼容性,目前较普遍使用的帧同步法是比特填充和违规编码法。
差错控制
前面我们说了将数据封装成帧和透明传输,但是传输的时候还是会不可避免的产生一些问题,所以接下来就要进行差错控制。既然要进行差错控制,我们就要先知道会出错的情况:传输过程中可能会产生比特差错(1 可能会变成 0 而 0 也可能变成 1),帧(包括发送帧和响应帧)出错或者帧(包括发送帧和响应帧)丢失。具体的检错措施有以下几种。
循环冗余检验CRC
CRC运算实际上就是在长为 k 的数据后面添加供差错检测用的 n 位冗余码,然后构成 k+n 位的帧发送出去。在了解 CRC 之前要先知道几个概念:
- 模2运算:实际上是按位异或运算,即相同为0,相异为1,也就是不考虑进位、借位的二进制加减运算。如:1111+1010 = 0101 ;
- FCS:就是冗余码,帧检验序列(Frame Check Sequence) ;
- 生成多项式:其实就是除数,比如10011表示成多项式为 ,则其阶 r = 4;
计算过程
现假定待传输数据 M=101001(k=6),生成多项式为 1101,计算其最终应该发送的数据:
- 计算应该加多少个0, ,所以 ;
- 用添加完 0 的数 M=101001000 除以除数(多项式),得到商Q(不关心)和余数 R=001,则 R 就是冗余码FCS;
- 最后加上 FCS 后发送的帧是101001001 ;
在接收端把接收到的数据 M = 101001001 以帧为单位进行CRC检验:把收到的每一个帧都除以相同的除数p,然后检查得到的余数R,如果数据没有出错所得到的余数R一定等于0,就接收数据;如果 ,说明帧有差错,直接丢弃。
海明码(汉明码)
- 编码(以1010110为例):
1. 确定校验码的位数x
设数据有n位,校验码有x位。则校验码一共有 种取值方式。其中需要一种取值方式表示数据正确,剩下 种取值方式表示有一位数据出错。因为编码后的二进制串有n+x位,因此x应该满足 ,使不等式成立的x的最小值就是校验码的位数。在本例中,n=7,解得x=4。
2. 确定校验码的位置
校验码在二进制串中的位置为2的整数幂。剩下的位置为数据。如图所示。
位置 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
---|---|---|---|---|---|---|---|---|---|---|---|
内容 | x1 | x2 | 1 | x3 | 0 | 1 | 0 | x4 | 1 | 1 | 0 |
3. 求出校验位的值
以求x2的值为例。为了直观,将表格中的位置用二进制表示。
位置 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 | 1000 | 1001 | 1010 | 1011 |
---|---|---|---|---|---|---|---|---|---|---|---|
内容 | x1 | x2 | 1 | x3 | 0 | 1 | 0 | x4 | 1 | 1 | 0 |
为了求出x2,要使所有位置的第二位是1的数据(即形如1 的位置的数据)的异或值为0。即x2^ 1^ 1^ 0^ 1^0 = 0。因此x2 = 1。
同理可得x1 = 0, x3 = 1, x4 = 0。
位置 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 | 1000 | 1001 | 1010 | 1011 |
---|---|---|---|---|---|---|---|---|---|---|---|
内容 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 0 |
因此1010110的海明码为01110100110。
- 校验:
假设位置为1011的数据由0变成了1,校验过程为:
将所有位置形如 的数据分别异或。
: 0^ 1^ 0^ 0^ 1^ 1 = 1
: 1^ 1^ 1^ 0^ 1^ 1 = 1
: 1^ 0^ 1^ 0 = 0
: 0^ 1^ 1^ 1 = 1
以上四组中,如果一组异或值为1,说明该组中有数据出错了。 的异或都为1,说明出错数据的位置为1011。
流量控制
上面我们已经解决了数据传输前和接收到数据后验证的工作,接下来就要对数据传输的过程进行控制;主要是对传输过程进行流量控制,就好像我们的公路一样,路已经建好了,如果不制定交通规则(靠右行驶、红绿灯),那么即使再好的路、再好的车一天你也不可能走的很远,因为大家都按照自己的想法来行驶,所以都被堵在了路上。具体流量控制的方法有下面这几种。
停止等待协议
停止-等待协议(发送窗口=1,接收窗口=1):每发送完一个帧就停止发送,等待对方的确认,在收到确认之后再发送下一个帧;接收方每接收一帧 , 都要反馈一个应答信号 ,表示可接收下一帧,如果接收方不反馈应答信号,则发送方必须一直等待。每次只允许发送一帧 ,然后就陷入等待接收方确认信息的过程中 ,因而传输效率很低 。具体的几种情况如图所示
- 无差错的情况
- 数据帧丢失或检测到帧出错‘’
- ACK丢失(确认帧丢失)
- ACK迟到
滑动窗口协议
1、**后退N帧协议(GBN):**发送窗口>1,接收窗口=1;若采用n个比特对帧编号,那么发送窗口的尺寸WT应该满足:1≤WT≤2n-1,因为发送窗口过大,就会使得接收方窗口无法区别新帧和旧帧。发送方要做的三件事:
- 上层的调用:上层要发送数据时,发送方先检查发送窗口是否已满,如果未满,则产生一个帧并将其发送;如果窗口已满,发送方只需将数据返回给上层,暗示上层窗口已满。上层等一会再发送(实际实现中, 发送方可以缓存这些数据,窗口不满时再发送帧);
- 收到了一个ACK:GBN协议中,对 n 号帧的确认采用累积确认的方式,标明接收方已经收到n号帧和它之前的全部帧;
- 超时事件:协议的名字为后退N帧/回退N帧,来源于出现丢失和时延过长帧时发送方的行为。就像在停等协议中一样,定时器将再次用于恢复数据帧或确认帧的丢失。如果出现超时,发送方重传所有已发送但未被确认的帧;
接收方要做的事情:
- 如果正确收到n号帧,并且按序,那么接收方为n帧发送一个ACK,并将该帧中的数据部分交付给上层;
- 其余情况都丢弃帧,并为最近按序接收的帧重新发送ACK。接收方无需缓存任何失序帧,只需要维护一个信息: expectedseqnum (下一个按序接收的帧序号);
2、**选择重传协议(SR):**发送窗口>1,接收窗口>1; 若采用n比特对帧编号,为了保证接收方向向前移动窗口后,新窗口序号与旧窗口序号没有重叠部分,需要满足条件:接受窗口+发送窗<=2^ n;由此我们可以推得:发送(或接收)窗口大小 <= 2^(n-1)。发送方必须做的三件事:
- 上层的调用:从上层收到数据后,SR发送方检查下一个可用于该帧的序号,如果序号位于发送窗口内,则发送数据帧;否则就像GBN一样,要么将数据缓存,要么返回给上层之后再传输;
- 收到一个ACK:如果收到ACK,加入该帧序号在窗口内,则SR发送方将那个被确认的帧标记为已接收。如果是该帧序号是窗口的下界(最左边第一个窗口对应的序号),则窗口向前移动到具有最小序号的未确认帧处。如果窗口移动了并且有序号在窗口内的未发送帧,则发送这些帧。
- 超时事件:每个帧都有自己的计时器,一个超时事件发生后只重传一个帧;
接收方要做的事情:
- 来者不拒(窗口内的帧):SR接收方将确认一个正确接收的帧而不管其是否按序。失序的帧将被缓存,并返回给发送方一个该帧的确认帧(收谁确认谁),直到所有帧(即序号更小的帧)皆被收到为止,这时才可以将一批帧按序交付给上层,然后向前移动滑动窗口;如果收到了窗口序号外(小于窗口下界)的帧,就返回一个ACK;其他情况则忽略该帧。
可靠传输
我们都知道数据链路层进行的传输也是可靠传输,那么他是如何实现可靠传输的呢?
数据链路层的可靠传输通常使用确认和超时重传两种机制来完成 。确认是一种无数据的控制帧,这种控制帧使得接收方可以让发送方知道哪些内容被正确接收。有些情况下为了提高传输效率,将确认捎带在一个回复帧中,称为捎带确认 。超时重传是指发送方在发送某一个数据帧以后就开启一个计时器 ,在一定时间内如果没有得到发送的数据帧的确认帧 ,那么就重新发送该数据帧,直到发送成功为止 。
传输数据使用的链路
前面我们已经讨论了很多东西,但是关于数据传输的链路我们还是不太清楚,是点对点的?还是广播的?当然是点对点和广播的都有,不同的链路所使用的的协议肯定是不一样的,我们再来学习一下这两种方式以及所使用的的协议吧。
使用点对点信道(PPP协议)
首先,我们要先了解PPP协议,ppp协议不需要纠错,不需要设置序号,不需要进行流量控制,不支持多点线路(既一个主站轮流和链路上的多个从站进行通信),只支持点对点的链路通信,只支持全双工链路。PPP协议是由三部分组成的:
- 一个将IP数据报封装到串行链路的方法。PPP既支持异步链路,也支持面向比特的同步链路;
- 一个用来建立、配置和测试数据链路连接的链路控制协议LCP;
- 一套网络控制协议NCP;
然后,我们要来认识一下PPP协议下的帧格式
- 标志字段F:0x7E(01111110):表示一个帧的开始或者结束。标志字段就是PPP帧的定界符。
- 地址字段A:0xFF(11111111)
- 控制字段C:0x03(00000011)
- 协议字段:为0x0021时,PPP协议帧就是IP数据报;为0xC021时,信息字段就是PPP链路控制协议LCP的数据;为0x8021时表示网络层的控制信息。
- FCS:使用CRC帧检验的冗余码。
使用广播信道(CSDA/CD协议)
CSDA/CD协议的主要内容有三方面,载波监听、多点接入和碰撞检测;下面就分别进行解释:
- 载波监听:不管在发送前还是在发送中,每个站都必须不停的检测信道。如果检测到已经有其他站在发送,则自己就暂时不需发送数据,必须要等到信道边为空闲时才能发送数据。在发送中检测信道,是为了及时发现有没有其他站在发送和本站发送的碰撞。
- 多点接入:总线型网,许多计算机以多点接入的方式连接在一根总线上。
- 碰撞检测:边发送边监听,即适配器边发送数据边检测信道上的信号电压的变化情况,以便判断自己在发送数据时其他站是否也在发送数据。
这些均为个人总结,只是采用这种方式去理解数据链路层的功能,还有很多别的重要的知识点没有提及,如果有兴趣欢迎相互交流;也欢迎提出问题。
转载:https://blog.csdn.net/pp_l_ly/article/details/106372019