网络 | 03. 数据链路层(以太网MAC帧、PPP协议)

/image/%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82MindMap1.png
数据链路层框架之三个核心问题
/image/image-20250619210110-f1nlq2y.png
  • 链路(Link)就是从一个结点到相邻结点的一段物理线路,中间没有任何其他的交换结点
  • 数据链路(Data Link)是指把实现通信协议的硬件和软件加到链路上,就构成了数据链路
  • 数据链路层以为单位传输和处理数据
  • 将上层交付的网络层数据单元添加数据链路层协议首部(帧头)和帧尾的操作称为封装成帧

  • 其目的是为了在链路上以帧为单位传送数据

  • 如以太网第二版本的MAC帧格式如下

    /image/image-20250619210611-hwshttl.png
  • 如点对点协议PPP协议

    /image/image-20250619211921-z34p3b8.png
  • 如何从比特流种提取出帧
    • 使用帧头和帧尾来定界(1字节的标志字段,用于帧定界)
    • 不是所有的帧都有定界符,如MAC格式
      • MAC帧会在物理层添加8字节的前导码,然后再将其转化为电信号发送
      • 前导码的前7个字节为前同步码,用于接收方的时钟同步,随后1字节为帧开始定界符,表示随后紧跟MAC帧
      • 另外,以太网还规定了帧间间隔时间为96比特的发送时间,因此MAC帧并不需要帧结束定界符
  • 透明传输是指数据链路层对上层交付的传输数据没有任何限制,就好像数据链路层不存在一样

    • 但实际上,数据中不能包含帧定界符号,否则会扰乱接收方对帧的开始、结束识别

    • 为了实现透明传输,解决方法是在封装过程中,对数据进行扫描,每发现一个定界符或转义字符,就在其前面插入一个转义字符,确保能够正确识别

    • 转义字符为特殊的控制字符,占1个字节,十进制数为27

    • 面向字节的物理链路,使用字节填充(或字符填充)的方法实现透明传输

    • 面向比特的物理链路使用比特填充的方法实现透明传输,如每五个连续1之后就自动插入0

    • 例如下练习

      /image/image-20250619213252-wzgiu95.png
      • 高级数据链路控制协议HDLC采用帧头和帧尾中标志字段作为帧定界符,其值为01111110
      • HDLC为了实现透明传输,采用零比特填充法(每5个连续1后面插入1个比特0)
      • 答案为A
    • 为了提高帧的传输效率,应当尽可能使帧的数据部分长度尽可能大一些(远大于帧头和帧尾长度)

    • 但考虑到实际差错控制,每一种数据链路层协议也都规定了帧的数据部分长度上限,即最大传送单元MTU(Maximum Transfer Unit)

  • 帧在传输过程中可能出现误码,需要接收端能够识别和检测

    • 比特流在传输过程中可能发生差错,1变为0或0变为1,这称为比特差错
    • 一段时间内,传输错误的比特占四瓶传输比特总数的比例称为误码率BER(Bit Error Rate)
  • 检错码是封装在帧尾的一个信息(根据数据和检错算法计算得到的一个码),如在以太网v2的MAC帧的帧尾种,包含了4字节的帧检验序列FCS,用于接收端检测是否存在误码(PPP协议的FCS为2字节)

  • 奇偶检验

    • 在待发送数据后面添加1位奇偶校验位,使整个数据(包含所添加的校验位在内)中“1”的个数为奇数(奇校验)或偶数(偶校验)
    • /image/image-20250620041056-fs1if5e.png
    • 如果有偶数个位发生误码,则不能检查出误码(漏检)
  • 循环冗余校验CRC(Cyclic Redundancy Check)

    • 收发双方约定好一个生成多项式$G(X)$
    • 发送方基于待发送数据和生成多项式计算出差错检测码(冗余码),将其添加到待传输数据的后面一起传输
    • 接受方通过生成多项式来计算收到的数据是否产生了误码
    • 比如
      • /image/image-20250620041456-chstdvx.png

      • /image/image-20250620041527-qkbdmfy.png
      • /image/image-20250620041756-panlrwq.png
      • 图上的⊕表示异或运算,即相同时为0,不同时为1

      • /image/image-20250620041832-3l7c8bx.png
      • CRC具有很好的检错能力(漏检率非常低),虽然计算比较复杂,但非常利于硬件的实现,因此被广泛应用于数据链路层

  • 检错码只能检查是否出错,但不能定位出错误,无法纠正错误

    • 如果想要在传输过程中纠正错误,可以使用冗余信息更多的纠错码进行前向纠错,如海明码

    • 但纠错码的开销比较大,在计算机网络中较少使用

    • 实际中,计算机网络往往使用检错重传的方式来纠正传输种的差错,或者仅仅丢弃检测到差错的帧,(取决于向上层提供可靠传输服务还是不可靠传输服务)

  • 接收端在检测出误码之后,不会接受该帧,将其丢弃
    • 如果数据链路层向上层提供不可靠服务,则在丢弃后不会有其他行为
    • 但如果数据链路层想上层提供可靠服务,则需要其他措施来确保接收方主机能够重新收到该帧的副本
  • 可靠传输服务是指:想办法实现发送端发送什么,接收端就收到什么
    • 简单的策略,是接收端发送一个通知帧给发送端,告诉他之前的帧有误码,请重发;发送端接受到之后重发之前的帧即可
      • 但通知帧仍旧有可能出现误码
    • 一般情况下,有线链路的误码率比较低,为减小开销,并不要求数据链路层向上提供可靠的传输服务,即使出现了误码,可靠传输的问题可以有其上层处理
    • 但是在无线链路中,其易受干扰,误码率比较高,因此数据链路层必须向上层提供可靠传输服务
  • 比特差错只是传输差错的一种情况,从整个计算机网络体系结构来看,传输差错还包括分组丢失、分组失序以及分组重复(在当前语境下,分组即指代帧)
    • 路由器将数据丢失
    • 发送了3个分组,可能由于传输的路径不同,导致3个数据到达的顺序不同
    • 发送的分组由于某些原因滞留,导致了发送端超时重发,但之后原滞留的分组又到达接收端
    • 这三种情况一般不会出现在数据链路层,而会出现在其上层
  • 可靠传输不仅仅局限于数据链路层,其他各层均可选择实现可靠传输
    • /image/image-20250620043304-v0fr4jp.png
    • 可靠传输的开销和代价比较大,需要根据实际应用选择是否需要可靠传输

值得一提的是,这三种协议不仅仅适用于数据传输层,其他层也可以使用同样的思路确保可靠传输)

  • 收发双方基于互联网传输

  • /image/image-20250621194448-ce14t4t.png
  • 接受方每次接受到数据之后都需要进行确认,在确认无误之后,发送确认信息ACK给发送方,随后发送方才会继续发送下一个分组数据

  • 如果接受方检测数据出现误码,则将数据丢失,且发送报错信息NAK给发送方,要求重新发送该数据

  • 潜在问题1 超时重传:如果数据只是在发送传输过程中丢失,接收方则始终收不到信息并回报确认信息,那么传输则会中断

    • 为了解决这个问题,发送方可以在发送过一个数据分组时,启动一个超时计时器
    • 如果到了超时计时器所设定的重传时间,且发送方并没有收到接收方的任何ACK或NAK信息,则重新发送原来的数据分组,这称为超时重传
    • /image/image-20250621195027-c9u8w8g.png
    • 一般重传时间选择为略大于双方通信平均往返时间
  • 潜在问题2 确认丢失:不仅仅发送的数据可能丢失,接收方回传的确认信息也可能丢失,此时会触发发送方的超时重传,接收方会收到重复的数据,这需要接受方对该数据进行辨识和确认

    • 简单的思路,发送的数据需要带上序号(一个比特就够了),接受方只要检测新的数据与原来数据的编号不一致即可
    • /image/image-20250621195417-rc5p6jo.png
  • 潜在问题3 迟到确认:既然发送的数据需要编号,回传的确认信息是否有必要编号呢?

    • /image/image-20250621195703-ah9isr9.png
    • 如果确认迟到,则会发生重复确认的问题,如果确认信息没有编号,则会让发送端错误地判断确认,此时是有必要给确认信息加上编号的
    • 但通常而言,对于数据链路层的点对点信道,往返时间比较固定,不会出现确认迟到的问题;因此,如果只在数据链路层实现停止-等待协议,可以不用给确认分组编号
  • 小结:

    • 接收端检测到数据分组有误码时,将其丢弃并等待发送方的超时重传。但对于误码率较高的点对点链路,为使发送方尽早重传,也可给发送方发送NAK分组(否认分组)
    • 为了让接收方能够判断所收到的数据分组是否是重复的,需要给数据分组编号。由于停止-等待协议的停等特性,只需1个比特编号就够了,即编号0和1
    • 为了让发送方能够判断所收到的ACK分组(确认分组)是否是重复的,需要给ACK分组编号,所用比特数量与数据分组编号所用比特数量一样
    • 数据链路层一般不会出现ACK分组迟到的情况,因此在数据链路层实现停止-等待协议可以不用给ACK分组编号
    • 超时计时器设置的重传时间应仔细选择,一般可将重传时间选为略大于“从发送方到接收方的平均往返时间”
    • 在数据链路层点对点的往返时间比较确定,重传时间比较好设定;然而在运输层,由于端到端往返时间非常不确定,设置合适的重传时间有时并不容易
  • 信道利用率:

    • 假设收发双方是直通的信道,该协议可以表示如下

    • /image/image-20250621200502-3mriijj.png
    • 假设信道长度是2000km,数据分组长度是1500B,发送速率为10Mbit/s,忽略$T_A$,其通常远小于$T_D$​

    • 此时的信道利用率为

      • $$ U \approx \frac{T_D}{T_D+RTT} = \frac{\frac{1500 \times 8 bit}{10\times 10^6 bit/s}}{\frac{1500 \times 8 bit}{10\times 10^6 bit/s} + \frac{2000 km}{2 \times 10^8 m/s}} = \frac{1.2 ms}{1.2ms + 20ms} \approx 5.66 % $$
      • ​#Q#​ 这里的$2\times 10^8 m/s$是一个什么常数吗?
    • 如果将发送速度提高到100Mb/s,则信道利用率则为0.6%

    • 当往返时延RTT远大于数据帧发送时延$T_D$时(例如使用卫星链路),信道利用率非常低

    • 若出现重传,则对于传送有用的数据信息来说,信道利用率还要降低

    • 为了克服停止-等待协议信道利用率低的缺点,出现了其他两种协议

  • 习题

    /image/image-20250621201755-crr6c57.png
    • $40=\frac{x/3kbps}{x/3kbpx+200ms\times2}$
    • 方程解得800bit
  • 停止等待协议的信道利用率很低,其原因在于每个数据分组发送都需要停下来等回传信息
  • 如果能够连续发送多个信息(流水线传输),则可以大大提高信道利用率
  • /image/image-20250621202939-xg2tg6e.png
  • 回退N帧协议在流水线传输的基础上,利用发送窗口来限制发送方可以连续发送的数据分组个数
  • 例如使用3个比特给分组编号,即序号0-7($2^N-1$),由此可以选择大于0且小于等于7个的分组一同发送,称为发送窗口,比如这里选择5
    • /image/image-20250621203415-fku4yxa.png
    • 如果发送窗口的大小超过了分组编号的上限,接收方就无法分辨新、旧数据分组,会出现分组重复的错误
  • 而接收方的接收窗口,保持和停止-等待协议一样,只能为1
  • 无差错情况
    • 发送方可以将发送窗口内的数据连续发送出去,经过互联网传输,正确到达接收方
    • 在没有乱序和误码的情况下,接收方依次接受数据,每接受一个数据,接受窗口向前滑动一个位置,并向发送端反馈确认信息
    • 确认信息到达发送方后,发送方每确认一个,发送窗口向前滑动一个位置,此时会有新的序号落入发送窗口,发送方可以将确认收到的分组在缓存中删除
  • 累计确认
    • 接收方不一定要逐个发送确认信息,二十可以在收到几个分组之后,对按序到达的最后一个分组发送确认(ACKn表示序号为n及以前的所有数据分组都已经正确接收)
    • 哪怕ACK1丢失,只要发送方接收到ACK4,就说明1号分组的数据也已经被正确接收了,可以将发送窗口向前滑动5个位置
    • 累计确认的好处是,即使确认分组丢失,发送方也可能不必重传;减小接收方的开销,减小对网络资源的占用
    • 缺点是不能及时反馈出接收方的确认信息
  • 有差错的情况(数据出现误码)
    • 如连续发送的第一个数据分组出现误码,接收方在检测之后发现错误,随后的几个数据由于序号与接受窗口不一致,数据也会随之丢弃
    • 每丢弃一个分组数据,接收方则会发送前一个ACK信息给发送方(如5号分组数据出现误码,6、7、0、1号数据都会被丢弃,并发送ACK4给发送方)
    • 发送方接收到重复的确认信息之后,即可知道新发送的数据出现错误,可以不等超时计时器就立刻重传数据
      • 至于收到几个重复确认信息之后再立刻重传,由具体实现决定
    • 这里就解释了为什么这个协议叫做回退N帧协议,因为即使后面的信息是正确到达接收方的,但由于接受窗口的限制,这些数据仍旧会被回退回来,重新发送
    • 由此可见,当信道质量不好时,退回N帧协议的信道利用率也并不比停止-等待协议高
  • 小结
    • /image/image-20250622020438-usc2gua.png
    • 回退N帧协议在流水线传输的基础上利用发送窗口来限制发送方连续发送分组的数量,是一种连续ARQ协议
    • 在协议的工作过程中,发送窗口和接受窗口不断向前滑动,因此此类协议又称为滑动窗口协议
    • 由于回退N帧协议的特性,当通信线路质量不好时,其信道利用率并不比停止-等待协议高
  • 练习题
    • /image/image-20250622020500-uv06pzv.png
    • 收到3号确认,意味着至少4号发生错误,但4、5、6、7都需要重新发送
  • 在退回N帧协议的基础上,为了进一步提高性能,可以设法只重传出现误码的数据分组
  • 即使是,接收窗口的尺寸$W_R$不应再是1,而应该大于1,以便接收方先收下失序到达但无误码且序号在接收窗口之内的数据分组,等到所缺失分组收齐后再一并提交上层,这就是选择重传协议的基本思路
  • 在该协议中,为了使发送方仅重传出现差错的分组,接收方不能再采用累计确认,而需要对每个正确接收到的数据分组进行逐一确认
  • 基本工作原理
    • 例如使用3比特进行分组编号,发送和接受窗口都选择4个
    • 发送方接受到确认窗口之后,关闭超时重发的计时器,如果此时是按顺序的确认,发送窗口向前滑动,否则需要等待超时重发最末尾的分组
  • 窗口尺寸问题
    • 发送窗口必须满足$1 \lt W_T \le 2^{n-1}$,超过该大小会导致接收方无法区分新旧分组
      • 接收方确认信息如果丢失,则会导致分组重复错误
    • 接收窗口必须满足$1\lt W_R \le W_T$,超过该数字则没有意义,该数据始终不会到达
  • 小结
  • 练习
    • /image/image-20250622022921-2dc447l.png
    • 答案是B,只需要重传0号和2号数据,3号仍旧没有超时,并不确认接收方是否收到,目前不需要重传

  • 以上三个问题都是点对点数据链路层上出现的问题,对于广播信道的数据链路层,还有其他问题需要解决

    • (编址问题)接收端如何确定是否接受该数据,需要提供原地址和目的地址
    • (碰撞检测)同时传输数据时,信号会发生碰撞,需要避免数据同时出现在总线上,如以太网的媒体接入控制协议CSMA/CD协议(载波监听、多点接入/碰撞检测)
  • 随着交换技术的成熟、成本的降低,具有更高性能的、使用点对点链路和链路层交换机的交换式局域网在有线领域(局域网)已经完全取代了共享式局域网

    • 网络交换机如何交换帧
    • 由于无线信道的广播天性,无线局域网仍旧使用共享信道技术,如802.11局域网采用的媒体控制协议是CSMA/CA
  • 点对点协议PPP(Point-to-Point Protocol)是目前使用最广泛的点对点数据链路层协议

    • 例如用户在接入因特网时,需要选择因特网服务提供者ISP,如中国移动、中国电信、中国联通,他们已经从因特网管理机构申请到了一批IP地址,用户需要获取到ISP所分配的合法IP地址后,才能称为因特网上的主机
    • 用户计算机与ISP进行通信时,所使用的数据链路层协议通常就是PPP协议
    • 1999年公布的,在以太网上运行的PPP协议,即PPP over Ethernet,简称PPPoE,它使得ISP可以通过DSL、电路调制解调器、以太网等宽带接入技术,以以太网接口的形式为用户提供接入服务
    • 另外,PPP协议也广泛应用于广域网路由器之间的专用线路
    • PPP协议是因特网工程任务组IETF在1992年制定的,经过1993年和1994年的修订,现在的PPP协议已成为因特网的正式标准RFC1661,RFC1662
  • PPP协议为在点对点链路传输各种协议数据报提供了一个标准方法,主要由以下三部分构成:

    • /image/image-20250622030450-ndxr14z.png
    • 对各种协议数据报的封装方法(封装成帧)
    • 链路控制协议LCP:用于建立、配置以及测试数据链路的连接
    • 一套网络控制协议NCPs:其中的每一个协议支持不同的网络层协议
  • PPP帧的格式

    • /image/image-20250622030732-42757el.png
    • 实现透明传输的方法
      • 如果数据帧的部分中,出现了帧定界符0x7E(01111110),则需要进行处理
      • 如果是面向字节传输的异步链路,则使用字节填充法,在该处前插入转移字符
      • 如果是面向比特的同步链路,则采用比特填充法,即插入比特0
    • 差错检测方法
      • CRC-CCITT = $X^{16}+X^{12}+X^5+1$
      • RFC1662的附录部分给出了FCS计算方法的C语言实现(查表法)
      • 接收方每收到一个PPP帧,就进行CRC检验
        • 若检验正确,就收下这个帧
        • 若检验不正确,就丢弃这个帧(使用PPP协议的数据链路层向上不提供可靠传输服务)
  • PPP协议的工作状态