计算机网络篇-数据链路层的精华所在

294 阅读15分钟

前言

自从自己第一篇掘金文章到现在已经将近三年,自己也从大学刚毕业时的意气风发,挥斥苍穹,到现在的一名普普通通的社畜。

计算机网络相关知识是我自己在掘金上写的第一篇文章,既然开了头,那就争取把这个系列写完。

计算机网络知识,是软件开发者必备的素质之一,但是由于其知识的复杂程度较高且枯燥无味,科班出身也不敢口出狂言的说自己对计算机网络有比较深刻的见解,况且在日常开发过程中,几乎很少接触到相关知识.

很少有人能把计算机网路知识讲解的津津有味,因为他本身就是一个很繁杂枯燥的底层学科(至少我是这么觉得的,不然也不会在计算机网络课上打游戏了,哈哈)。

概述

image.png

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

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

数据链路层的三个基本问题

image.png

封装成帧

在一段数据的前后分别添加首部和尾部,这样就构成了一个帧。接收端在收到物理层上交的比特流后,就能根据首部和尾部的标记,从收到的比特流中识别帧的开始和结束。

一个帧的帧长等于帧的数据部分长度加上帧首部和帧尾部的长度。首部和尾部的一个重要作用就是进行帧定界(即确定帧的界限),当数据在传输中出现差错时,帧定界符的作用更加明显。

image.png

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

透明传输

  • 透明传输:当传送的帧是用文本文件组成的帧时(文本文件中的字符都是从键盘上输入的),其数据部分显然不会出现像SOH或EOT这样的帧定界控制字符。
  • 非透明传输:当数据部分是非ASCII码的文本文件时(如二进制代码的计算机程序或图像等)

image.png

如果数据中的某个字节的二进制代码恰好和SOH或EOT这种控制字符一样,数据链路层就会错误地“找到帧的边界”,把部分帧收下(误认为是个完整的帧),而把剩下的那部分数据丢弃(这部分找不到帧定界控制字符SOH)。

如何做到透明传输:

image.png

字节填充(byte stuffing)法:发送端的数据链路层在数据中出现控制字符“SOH”或“EOT”的前面插入一个转义字符“ESC”(其十六进制编码是1B,二进制00011011)。而在接收端的数据链 路层在把数据送往网络层之前删除这个插入的转义字符。

如果转义字符也出现在数据当中,那么解决方法仍然是在转义字符的前面插入一个转义字符。因此,当接收端收到连续的两个转义字符时,就删除其中前面的一个。

差错效验

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

误码率:在一段时间内,传输错误的比特占所传输比特总数的比率,误码率与信噪比有很大的关系。如果设法提高信噪比,就可以使误码率减小

实际的通信链路并非是理想的,它不可能使误码率下降到零。为了保证数据传输的可靠性,必须采用各种差错检测措施。目前在数据链路层广泛使用了循环冗余检验CRC(Cyclic Redundancy Check)

另一类传输差错则更复杂些,这就是收到的帧并没有出现比特差错,但却出现了帧丢失、帧重复或帧失序。例如,发送方连续传送三个帧:[#1]-[#2]-[#3]。假定接收端收到的每一个帧都没有比特差错,但却出现下面的几种情况:

  • 帧丢失:收到[#1]-[#3](丢失[#2])。
  • 帧重复:收到[#1]-[#2]-[#2]-[#3](收到两个[#2])。
  • 帧失序:收到[#1]-[#3]-[#2](后发送的帧反而先到达了接收端,这与一般数据链路层的传输概念不一样)。 以上三种情况都属于“出现传输差错”,但都不是这些帧里有“比特差错”。

无比特差错无传输差错并不是同样的概念。在数据链路层使用CRC检验,能够实现无比特差错的传输,但这还不是可靠传输。

解决方案:

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

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

点对点协议PPP

在通信线路质量较差的年代,在数据链路层使用可靠传输协议曾经是一种好办法。

因此,能实现可靠传输的高级数据链路控制 HDLC(High-level Data Link Control)就成为当时比较流行的数据链路层协议。但现在HDLC已很少使用了。对于点对点的链路,简单得多的点对点协议 PPP(Point-to-Point Protocol)是目前使用得最广泛的数据链路层协议.

PPP协议的特点

互联网用户通常都要连接到某个ISP才能接入到互联网。PPP协议就是用户计算机和ISP进行通信时所使用的数据链路层协议

image.png

PPP协议应满足的需求:

  1. 简单:接收方每收到一个帧,就进行CRC检验。如CRC检验正确,就收下这个帧;反之,就丢弃这个帧,其他什么也不做
  2. 封装成帧:PPP协议必须规定特殊的字符作为帧定界符(即标志一个帧的开始和结束的字符),以便使接收端从收到的比特流中能准确地找出帧的开始和结束位置。

image.png

首部的第一个字段和尾部的第二个字段都是标志字段F(Flag),规定为0x7E(符号“0x”表示它后面的字符是用十六进制表示的。十六进制的7E的二进制表示是01111110)。标志字段表示一个帧的开始或结束。因此标志字段就是PPP帧的定界符。连续两帧之间只需要用一个标志字段。如果出现连续两个标志字段,就表示这是一个空帧,应当丢弃 ,尾部中的第一个字段(2字节)是使用CRC的帧检验序列FCS。

  1. 透明性:PPP协议必须保证数据传输的透明性。如果数据中碰巧出现了和帧定界符一样的比特组合时,就要采取有效的措施来解决这个问题

image.png

解决方式

  1. 字节填充:  当PPP使用异步传输时,它把转义符定义为0x7D(即01111101),并使用字节填充,RFC 1662规定了如下所述的填充方法:
  • 把信息字段中出现的每一个0x7E字节转变成为2字节序列(0x7D,0x5E)。
  • 若信息字段中出现一个0x7D的字节(即出现了和转义字符一样的比特组合),则把0x7D转变成为2字节序列(0x7D,0x5D)。
  • 若信息字段中出现ASCII码的控制字符(即数值小于0x20的字符),则在该字符前面要加入一个0x7D字节,同时将该字符的编码加以改变。例如,出现0x03(在控制字符中是“传输结束”ETX)就要把它转变为2字节序列(0x7D,0x23)。发送端进行了字节填充,链路上传送的信息字节数就超过了原来的信息字节数。接收端在收到数据后再进行与发送端字节填充相反的变换,就可以正确地恢复出原来的信息
  1. 零比特填充: 在发送端,先扫描整个信息字段(通常用硬件实现,但也可用软件实现,只是会慢些)。只要发现有5个连续1,则立即填入一个0。因此经过这种零比特填充后的数据,就可以保证在信息字段中不会出现6个连续1。接收端在收到一个帧时,先找到标志字段F以确定一个帧的边界,接着再用硬件对其中的比特流进行扫描。每当发现5个连续1时,就把这5个连续1后的一个0删除,以还原成原来的信息比特流。这样就保证了透明传输:在所传送的数据比特流中可以传送任意组合的比特流,而不会引起对帧边界的错误判断。
  1. 多种网络层协议PPP协议必须能够在在同一条物理链路上同时支持多种网络层协议(如IP和IPX等)的运行。当点对点链路所连接的是局域网或路由器时,PPP协议必须同时支持在链路所连接的局域网或路由器上运行的各种网络层协议
  2. 多种类型链路除了要支持多种网络层的协议外,PPP还必须能够在多种类型的链路上运行。例如,串行的(一次只发送一个比特)或并行的(一次并行地发送多个比特),同步的或异步的,低速的或高速的,电的或光的,交换的(动态的)或非交换的(静态的)点对点链路
  3. 差错检测(error detection) PPP协议必须能够对接收端收到的帧进行检测,并立即丢弃有差错的帧 。若在数据链路层不进行差错检测,那么已出现差错的无用帧就还要在网络中继续向前转发,因而会白白浪费许多的网络资源。
  4. 检测连接状态PPP协议必须具有一种机制能够及时(不超过几分钟)自动检测出链路是否处于正常工作状态。当出现故障的链路隔了一段时间后又重新恢复正常工作时,就特别需要有这种及时检测功能。
  5. 最大传送单元PPP协议必须对每一种类型的点对点链路设置最大传送单元MTU的标准默认值,这样做是为了促进各种实现之间的互操作性。如果高层协议发送的分组过长并超过MTU的数值,PPP就要丢弃这样的帧,并返回差错。需要强调的是,“MTU是数据链路层的帧可以载荷的数据部分的最大长度,而不是帧的总长度
  6. 网络层地址协商PPP协议必须提供一种机制使通信的两个网络层(例如,两个IP层)的实体能够通过协商知道或能够配置彼此的网络层地址。协商的算法应尽可能简单,并且能够在所有的情况下得出协商结果。这对拨号连接的链路特别重要,因为如果仅仅在链路层建立了连接而不知道对方网络层地址,则还不能够保证网络层可以传送分组。
  7. 数据压缩协商PPP协议必须提供一种方法来协商使用数据压缩算法。但PPP协议并不要求将数据压缩算法进行标准化。

在TCP/IP协议族中,可靠传输由运输层的TCP协议负责,因此数据链路层的PPP协议不需要进行纠错,不需要设置序号,也不需要进行流量控制。PPP协议不支持多点线路(即一个主站轮流和链路上的多个从站进行通信),而只支持点对点的链路通信。此外,PPP协议只支持全双工链路

PPP协议的工作状态

image.png

PPP链路的起始和终止状态永远是上图中的“链路静止”(Link Dead)状态,这时在用户个人电脑和ISP的路由器之间并不存在物理层的连接。

当用户个人电脑通过调制解调器呼叫路由器时(通常是在屏幕上用鼠标点击一个连接按钮),路由器就能够检测到调制解调器发出的载波信号。

在双方建立了物理层连接后,PPP就进入“链路建立”(Link Establish)状态,其目的是建立链路层的LCP连接。 这时LCP开始协商一些配置选项--即发送LCP的配置请求帧(Configure-Request)。这是个PPP帧,其协议字段置为LCP对应的代码,而信息字段包含特定的配置请求。

链路的另一端可以发送以下几种响应中的一种:

  1. 配置确认帧(Configure-Ack)所有选项都接受。
  2. 配置否认帧(Configure-Nak)所有选项都理解但不能接受。
  3. 配置拒绝帧(Configure-Reject)选项有的无法识别或不能接受,需要协商。

LCP配置选项包括链路上的最大帧长、所使用的鉴别协议(authentication protocol)的规约(如果有的话),以及不使用PPP帧中的地址和控制字段(因为这两个字段的值是固定的,没有任何信息量,可以在PPP帧的首部中省略这两个字节)

协商结束后双方就建立了LCP链路,接着就进入“鉴别”(Authenticate)状态

在这一状态,只允许传送LCP协议的分组、鉴别协议的分组以及监测链路质量的分组。 若使用口令鉴别协议PAP(Password Authentication Protocol),则需要发起通信的一方发送身份标识符和口令。 系统可允许用户重试若干次。如果需要有更好的安全性,则可使用更加复杂的口令握手鉴别协议CHAP(Challenge-Handshake Authentication Protocol)。 若鉴别身份失败,则转到“链路终止”(Link Terminate)状态。若鉴别成功,则进入“网络层协议”(Network-Layer Protocol)状态

在“网络层协议”状态,PPP链路的两端的网络控制协议NCP根据网络层的不同协议互相交换网络层特定的网络控制分组。 这个步骤是很重要的,因为现在的路由器都能够同时支持多种网络层协议。

总之,PPP协议两端的网络层可以运行不同的网络层协议,但仍然可使用同一个PPP协议进行通信。 如果在PPP链路上运行的是IP协议, 则对PPP链路的每一端配置IP协议模块(如分配IP地址)时就要使用NCP中支持IP的协议——IP控制协议IPCP(IP Control Protocol)。IPCP分组也封装成PPP帧(其中的协议字段为0x8021)在PPP链路上传送。在低速链路上运行时,双方还可以协商使用压缩的TCP和IP首部,以减少在链路上发送的比特数。

当网络层配置完毕后,链路就进入可进行数据通信的“链路打开”(Link Open)状态。链路的两个PPP端点可以彼此向对方发送分组。 两个PPP端点还可发送回送请求LCP分组(Echo-Request)和回送回答LCP分组(Echo-Reply),以检查链路的状态。

数据传输结束后, 可以由链路的一端发出终止请求LCP分组(Terminate-Request)请求终止链路连接,在收到对方发来的终止确认 LCP分组(Terminate-Ack)后,转到“链路终止”状态。如果链路出现故障,也会从“链路打开”状态转到“链路终止”状态。当调制解调器的载波停止后,则回到“链路静止”状态