数据链路层

ZaynPei Lv6

数据链路层的主要功能是让帧在物理介质上可靠地传输。它位于物理层之上,网络层之下,负责将网络层传下来的数据包封装成帧,并处理帧的传输、差错检测和流量控制等问题。

它使用的通信信道主要有两种:

  • 点对点信道 (Point-to-Point Channel):通信双方通过专用的物理链路直接连接,数据在两点之间一对一传输。例如,串行通信、PPP协议等。
  • 广播信道 (Broadcast Channel):多个设备共享同一物理链路,数据可以被所有连接到该链路的设备接收。例如,以太网(采用CSMA/CD协议)、Wi-Fi(采用CSMA/CA协议)等。

数据链路层的主要功能

数据链路层所处的地位

数据链路层位于OSI模型的第二层,介于物理层和网络层之间。

对下:它接收物理层提供的原始比特流服务,并需要处理这些比特流中可能出现的传输错误。

对上:它向网络层提供服务,其主要作用是将源自网络层的数据包(Packet)可靠地传输到相邻节点的目标网络层。它对网络层隐藏了物理传输中的各种复杂细节和错误。

指的是在两个节点之间建立、维持和释放数据链路的过程。这主要用于点对点的连接。

  • 链路建立:通信双方通过“握手”确认彼此的状态,准备好进行数据传输。
  • 数据传输:在已建立的链路上交换数据。
  • 链路释放:通信结束后,有序地断开连接,释放资源。

在像以太网这样的广播网络中,链路管理通常是自动且隐含的,但在广域网协议中,这是一个非常明确的步骤。

封装成帧与透明传输

物理层传输的是一长串没有明显边界的比特流。为了让接收方能够区分数据的起点和终点,数据链路层必须将网络层传下来的数据包添加首部(Header)尾部(Trailer),将它们封装成一个独立的、可识别的数据单元,这个单元就是帧 (Frame)。

接收方可以通过帧的头部和尾部来准确地确定一帧的开始和结束, 帧头通常包含源和目标的物理地址(MAC地址)等控制信息;帧尾通常包含用于差错校验的字段。

而现在还有一个问题: 如果在帧的数据部分(即网络层的数据包)中,恰好出现了与帧尾定界符完全相同的比特组合,接收方就会错误地认为帧已经结束,导致数据解析错误。

透明传输指的是,无论上层交付什么样的数据,数据链路层都有办法将其封装并成功传输,即使数据中包含了与控制信息(如帧定界符)相同的比特模式。

上述问题的解决方法是, 通过字符填充 (Character Stuffing) 或 比特填充 (Bit Stuffing) 技术来实现。

例如, 以比特填充为例, 假设使用 01111110 作为帧的起始和结束标志。

发送方:在发送数据时,会扫描整个数据部分。一旦发现有连续的5个“1”,就立即在其后填充一个“0”。

接收方:在接收数据时,同样扫描数据。一旦发现连续的5个“1”,就检查其后的比特。 - 如果第6个比特是“0”,就将其删除,恢复原始数据。 - 如果第6个比特是“1”(即组成了01111110),则判断这是一个帧定界符。 - 通过这种方式,确保了数据内部永远不会出现与帧定界符相同的模式,实现了透明传输。

流量控制 (Flow Control)

指的是协调发送方和接收方的速率,防止发送速率过快而导致接收方来不及处理,造成数据丢失。

流量控制是一种点对点的控制,确保发送方只在接收方确认有能力接收时才发送数据。

拥塞控制: 关注的是整个网络宏观上的负载,防止网络因数据过多而瘫痪,这通常是传输层(如TCP)的职责。

常见的方法有:停止-等待协议、滑动窗口协议(如后退N帧协议、选择重传协议)

差错检测 (Error Detection)

物理链路并非绝对可靠,信号在传输过程中可能会因为噪声等因素产生差错(比特翻转,即0变1或1变0)。差错检测就是让接收方有能力发现收到的数据帧是否在传输中出现了错误。

核心思想是:在发送数据时,根据原始数据计算出一个校验码 (Check Code),并将其附加在帧的尾部一起发送。接收方收到后,用同样的方法对数据部分进行计算,比较计算结果和收到的校验码是否一致。

目前使用最广泛的差错检测方法是循环冗余校验 (CRC, Cyclic Redundancy Check)。

组帧(Framing)

组帧是数据链路层的基本任务之一。其核心目标是在一连串的比特流中,准确地标识出“帧”的开始和结束,以便接收方能够完整地提取出每一个数据单元。这个过程也称为帧同步。以下是四种经典的组帧方法。

字符/字节计数法 (Character/Byte Count)

这是一种概念上最简单的方法。它在帧的头部设置一个计数字段,用以标明该帧总共包含的字符(或字节)数

  • 发送方:在帧首部的计数字段填入该帧的长度(例如,长度为5)。
  • 接收方:首先读取计数字段的值(读到5),然后向后数出对应数量(5个)的字符,这就构成了一个完整的帧。读取完毕后,它就知道下一字节将是下一个新帧的计数字段。
5 | A | B | C | D | E | 7 | F | G | H | I | J | K | ↑ 计数字段 ↑ 计数字段

致命缺点:可靠性极差。如果在传输过程中,计数字段的某一位发生了错误(例如,5(二进制00000101)因为噪声变成了7(00000111)),接收方就会错误地读取7个字符。这将导致接收方对后续所有帧的边界判断都发生错误,造成灾难性的失步,且难以恢复。因此,这种方法如今已基本不被使用。

字节填充法 (Byte Stuffing)

使用特定的字符(字节)作为帧的起始和结束定界符,通常称为标志字节 (Flag Byte)。例如,在PPP协议中,标志字节是 01111110(十六进制为 0x7E)。

这种方法容易出现的是透明传输问题:如果帧的数据部分恰好也出现了与标志字节相同的内容,就会造成混淆。解决方法同样是填充:

  • 发送方:在发送前扫描整个数据部分。
  • 如果数据中出现标志字节 (0x7E),就在其前面插入一个转义字节 (0x7D)。
  • 如果数据中出现转义字节 (0x7D),同样在其前面再插入一个转义字节
  • 接收方:在接收时进行反向操作。当读到转义字节时,就删除这个转义字节,并将其后面的字节当作普通数据接收(无论它是什么)。当读到非转义字节的标志字节时,就认为是帧的边界。

示例:原始数据: A | 0x7D | 0x7E | B

填充后发送: FLAG | A | 0x7D | 0x7D | 0x7D | 0x7E | B | FLAG

优点:比字符计数法可靠得多,解决了透明传输问题。

缺点:依赖于以8位字节为单位的数据,不适用于非字符编码的数据流

零比特填充法 (Zero-Bit Stuffing)

这是目前应用最广泛的组帧方法,它同样使用一个特定的比特模式作为帧定界符,即标志字段 01111110。只不过透明传输解决方法有所不同:

  • 发送方:在硬件层面扫描整个数据比特流(除标志字段外)。只要发现连续的5个“1”,就立即在后面强制插入一个“0”
  • 接收方:同样在硬件层面扫描。只要发现连续的5个“1”,就检查其后的第6个比特。
    • 如果第6个比特是“0”,则说明这是一个填充位,必须将其删除以还原原始数据。
    • 如果第6个比特是“1”,则说明这是一个标志字段(结合其后的“0”,构成了 …1111110),表示帧的边界。

示例: - 原始数据: …01111110… - 填充后发送: …011111010…

优点:

高效:由硬件执行,速度非常快。

通用:完全不依赖于数据是否为8位字节的整数倍,可以处理任意长度的比特流

应用:被广泛用于HDLC、SDLC、USB等多种协议中。

违规编码法 (Physical Layer Coding Violations)

这是一种巧妙利用物理层编码冗余性的方法。在某些物理层编码方案中,并非所有信号模式都对应有效的数据。这些“无效”或“违规”的信号模式就可以被借用来定义帧的边界。

示例(以曼彻斯特编码为例): - 有效编码:在曼彻斯特编码中,每个比特的中间时刻都必须有一次电平跳变(高→低 或 低→高)。 - 违规编码:我们可以定义“连续高电平”和“连续低电平”这种没有中间跳变的信号模式作为帧的起始(Start)和结束(End)定界符。

当接收方检测到这种“违规”信号时,就知道这是一个帧边界,而不是数据。

优点:不需要任何填充,不增加数据载荷,实现了带外(out-of-band)的信令,效率很高, 但是不通用。

应用:常用于令牌环网和一些局域网技术中。

差错控制 (Error Control)

差错控制是数据链路层的核心职责之一。它不仅包括我们之前提到的差错检测,还包括检测到错误后应采取的纠正措施。一个完整的差错控制机制,就是一套发现并解决数据传输错误的方法论。

通常,差错控制的实现策略主要有两种:

自动重传请求 (ARQ - Automatic Repeat reQuest)

策略:接收方检测到错误后,直接丢弃这个错误的帧,然后通过一个反馈机制(如发送一个否认信息NAK,或不发送确认信息ACK)通知发送方,要求其重新发送该帧。

特点:这种策略实现相对简单,额外开销小。它依赖于检错编码来发现错误。这是目前有线网络(如以太网)中最主流的策略。

前向纠错 (FEC - Forward Error Correction)

策略:接收方不仅能检测到错误,还能根据编码中包含的冗余信息,直接确定错误的位置并加以纠正,无需发送方重传。

特点:这种策略实现复杂,冗余信息开销大。它依赖于纠错编码。常用于实时性要求高或单向通信(如广播)以及信道质量差、重传代价高的场景(如无线通信、卫星通信)。

检错编码 (Error-Detecting Codes)

检错编码的目标是让接收方有能力判断收到的数据是否在传输过程中发生了改变,但不能确定错误的位置。

核心思想:在原始数据 k 位的后面,附加 r 位的冗余信息(校验码),构成一个 n=k+r 位的码字进行传输。这 r 位的冗余信息根据 k 位的数据通过某种算法计算得出的。

奇偶校验码 (Parity Code)

是最简单的检错码。通过增加1位校验位,使得整个码字中“1”的个数为奇数或偶数。它只能检测出奇数个比特的错误,对于偶数个比特的错误则无能为力。

  • 奇检验码: 加入一位校验位,使得整个码字中“1”的个数为奇数。
  • 偶检验码: 加入一位校验位,使得整个码字中“1”的个数为偶数。
循环冗余码 (CRC - Cyclic Redundancy Check)

这是目前应用最广泛的检错码。它利用生成多项式模2除法,可以生成检错能力极强的校验码,尤其擅长检测计算机网络中常见的突发错误(即连续多个比特出错)。

其核心思想可以概括为:在 k 位的原始数据后面,附加 r 位的校验码(也称为 帧检验序列 FCS, Frame Check Sequence),构成一个总长为 n=k+r 位的帧。这个构造过程有一个精巧的数学保证:最终生成的这个 n 位帧,作为一个二进制数,一定能被一个预先选定的、长度为 r+1 位的特定二进制数“整除”

接收方收到帧后,只需用这个约定的“除数”去除以收到的帧。如果余数为零,则认为数据正确;如果余数不为零,则说明数据在传输中已损坏。

下面以一个具体的例子来说明CRC的编码和检验过程:假设数据 M = 101001, 生成多项式(除数)G = 1101, 此时 r = 3 (G的位数-1)

  1. 编码过程

    • 在数据 M 后面添加 r 个0,得到 M’ = 101001000
    • 用 M’ 除以 G,得到余数 R (这里的除法是模2除法,即不考虑进位的二进制除法, 也可以看作是按位异或操作, 只要位数够就一直做异或)
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
                110100
      1101 ) 101001000
      1101
      ----
      1110
      1101
      ----
      1110
      1101
      ----
      1100
      1101
      ----
      001 (余数, 要保留r位, 因此还要考虑前面的0)
  2. 附加校验码

    • 将余数 R = 001 附加在 M 的后面,得到最终的码字 C = 101001001
  3. 检验过程

    • 接收方收到码字 C’ = 101001001 后,用 G 除以 C’,如果余数为0,则数据正确;否则数据有误。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
                110100
      1101 ) 101001001
      1101
      ----
      1110
      1101
      ----
      1110
      1101
      ----
      1100
      1101
      ----
      000 (余数为0, 数据正确)
      假如在传输过程中, 第3位(从左向右)发生了错误, 接收方收到的码字变为 C’ = 101101001, 此时再用 G 除以 C’:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
                110100
      1101 ) 101101001
      1101
      ----
      1110
      1101
      ----
      1110
      1101
      ----
      1100
      1101
      ----
      101 (余数不为0, 数据有误)

纠错编码 (Error-Correcting Codes)

纠错编码不仅能发现错误,还能定位错误并自动修复。

核心思想是:通过增加更多的冗余位,使得码字中任意两个有效码字之间存在足够的“差异”。即使某个码字在传输中发生了少量错误,它在“形态”上依然离原始的正确码字“最近”,而离其他的有效码字“很远”,从而让接收方可以推断出原始的正确码字。

在介绍具体的纠错码之前,我们需要了解一个重要概念:海明距离 (Hamming Distance)或者码距(Distance)。

它的定义是指两个等长码字之间,对应位置上比特不同的位数。例如,10101 和 10011 之间的海明距离是2(第三位和第四位不同), 这可以通过异或操作实现。在一个编码集中, 编码级的海明距离是指该编码方案中,任意两个有效码字之间海明距离的最小值

根据纠错理论, 海明距离的大小直接决定了该编码的检错和纠错能力: - 编码方案的纠错能力(c), 检错能力(d)和码距(l)的关系: l = d + c + 1, 其中 d>=c (能纠错必然能检错) - 若要检测 d 个比特的错误,则编码的海明距离(l)至少需要为 d+1。(c=0的边界情况) - 若要纠正 t 个比特的错误,则编码的海明距离(l)至少需要为 2t+1。(d=t的边界情况)

例如, 当海明距离为 2t+1 时,如果一个码字发生了 t 位错误,它会变成一个无效码字。但这个无效码字与原始正确码字的海明距离为 t,而与其他任何一个正确码字的海明距离都至少为 t+1。因此,接收方可以通过“选择最近的有效码字”的原则,成功纠正错误。

一个典型的例子是海明码 (Hamming Code), 它是设计最精巧的纠错编码之一,它不仅能发现错误,还能精确定位单个比特的错误位置。通过设置多个校验位,并且让每个校验位都对一组不同的数据位进行校验。这样,当某个数据位出错时,会同时导致多个校验位的值发生变化。通过观察是哪些校验位“不匹配”,就可以像查字典一样反推出是哪一位数据出错了。

海明码的码距至少为3,因此它能够纠正单个比特错误检测双比特错误

公式为: 若信息位有k位, 设需要r位校验位, 则需满足 2r >= k + r + 1.

编码过程示例(以数据1010为例):

  1. 确定海明码的位数 若信息位有k位, 设需要r位校验位, r位校验位可以表示2r种状态, 且总位数为k+r, 单个比特位出错的情况有k+r种, 再加上一种正确状态, 则需满足 2r >= k + r + 1, 代入k=4, 可得r=3, 则总位数n=7 则海明码的位数为7位, 其中4位是数据位, 3位是校验位.
  • 数据位: d4 d3 d2 d1
  • 校验位: p3 p2 p1
  • 海明码: h7 h6 h5 h4 h3 h2 h1
  1. 确定校验位的位置 规定校验位 pi 必须放在2的幂次位置 2i − 1 上, 因此p1放在h1, p2放在h2, p3放在h4 此时, 海明码的位数为: | h7 | h6 | h5 | h4 | h3 | h2 | h1 | | d4 | p3 | d2 | p3 | d1 | p2 | p1 |

  2. 分组以形成校验关系 每个校验位负责校验一组特定位置的数据位, 具体规则如下: 具体来说, 校验位根据其二进制位置的1所处位置位来决定它负责校验哪些数据位:

  • p1 (h1) 负责校验位置 1, 3, 5, 7 (二进制位中第1位为1的位置), 也就是这里的 h1, h3, h5, h7
  • p2 (h2) 负责校验位置 2, 3, 6, 7 (二进制位中第2位为1的位置), 也就是这里的 h2, h3, h6, h7
  • p3 (h4) 负责校验位置 4, 5, 6, 7 (二进制位中第3位为1的位置), 也就是这里的 h4, h5, h6, h7
  1. 计算校验位的值 校验位的值通过对其负责校验的数据位进行异或操作来确定:
  • p1 = d1 ⊕ d2 ⊕ d4 = 0 ⊕ 1 ⊕ 1 = 0
  • p2 = d1 ⊕ d3 ⊕ d4 = 0 ⊕ 0 ⊕ 1 = 1
  • p3 = d2 ⊕ d3 ⊕ d4 = 1 ⊕ 0 ⊕ 1 = 0 因此, 最终的海明码为: 1010010
  1. 错误检测与纠正 每个检验组分别利用检验位和参与检验的数据位进行异或运算, 构成r个检验方程. 如果结果全部为0, 则表示数据无误; 如果某一组方程结果为1, 则表示该组数据有误.

假设在传输过程中, 第3位发生了错误, 接收方收到的码字变为: 1010110, 此时在接收方不知道的情况下, 接收方重新计算校验位: - p1’ = h1 ⊕ h3 ⊕ h5 ⊕ h7 = 0 ⊕ 1 ⊕ 1 ⊕ 1 = 1 - p2’ = h2 ⊕ h3 ⊕ h6 ⊕ h7 = 1 ⊕ 1 ⊕ 0 ⊕ 1 = 1 - p3’ = h4 ⊕ h5 ⊕ h6 ⊕ h7 = 0 ⊕ 1 ⊕ 0 ⊕ 1 = 0 将校验结果组合成一个二进制数, p3’p2’p1’ = 011, 并非全部是0, 说明出现了错误. 转换为十进制为3, 表示第3位出错, 接收方直接将第3位从1改回0, 成功纠正了错误.

即使是校验位本身出错, 也能通过同样的方法定位并纠正. 校验子(Syndrome)的计算和解码过程,对所有比特一视同仁。无论是数据位还是校验位出错,都会破坏其所在校验组的平衡,从而产生一个精确指向其位置的、独一无二的校验子,使得接收方能够完美地完成定位和纠正。

需要注意的是, 海明码只能纠正单个比特错误, 如果同时有多个比特出错, 则可能无法正确定位和纠正.

例如, 如果第3位和第5位同时出错, 则收到的码字为: 1010010, 此时重新计算校验位: - p1’ = h1 ⊕ h3 ⊕ h5 ⊕ h7 = 0 ⊕ 1 ⊕ 0 ⊕ 1 = 0 - p2’ = h2 ⊕ h3 ⊕ h6 ⊕ h7 = 1 ⊕ 1 ⊕ 0 ⊕ 1 = 1 - p3’ = h4 ⊕ h5 ⊕ h6 ⊕ h7 = 0 ⊕ 0 ⊕ 0 ⊕ 1 = 1 将校验结果组合成一个二进制数, p3’p2’p1’ = 110, 转换为十进制为6, 但实际上出错的位是3和5, 因此无法正确定位和纠正.

背后的原因在于, 海明码的设计初衷是为了纠正单个比特错误, 它确保了任意两个有效码字之间的海明距离至少为3. 但当有多个比特同时出错时, 可能会导致收到的码字与另一个有效码字之间的距离更近, 从而使得接收方无法正确判断原始码字.

再例如, 第3位, 第5位和第6位同时出错, 则收到的码字为: 10101010, 此时重新计算校验位: - p1’ = h1 ⊕ h3 ⊕ h5 ⊕ h7 = 0 ⊕ 1 ⊕ 0 ⊕ 1 = 0 - p2’ = h2 ⊕ h3 ⊕ h6 ⊕ h7 = 1 ⊕ 1 ⊕ 1 ⊕ 1 = 0 - p3’ = h4 ⊕ h5 ⊕ h6 ⊕ h7 = 0 ⊕ 0 ⊕ 1 ⊕ 1 = 0 将校验结果组合成一个二进制数, p3’p2’p1’ = 000, 误以为数据无误, 实际上数据已经损坏.

这是因为三个码字之间的距离关系导致的. 第三位被p1所检验, 第五位被p1和p3所检验, 第六位被p2和p3所检验. 当这三位同时出错时, 三个校验位的错误相互抵消, 导致校验结果全部为0, 使得接收方误以为数据无误.

流量控制与可靠传输

在数据链路层,我们的目标是将物理层提供的原始、可能出错的比特流,转变为一条对网络层来说高效、无差错的链路。要实现这个目标,必须解决两个核心问题:

流量控制 (Flow Control):如何防止速度快的发送方用数据“淹没”速度慢的接收方?这关乎效率和协调。

可靠传输 (Reliable Transmission):如何确保发送的数据帧最终能被接收方准确无误地收到,即使在传输过程中发生了丢失或损坏?这关乎正确性和完整性。

这两个问题通常使用同一套协议框架来解决,其中最核心的就是滑动窗口机制。

流量控制与滑动窗口机制

如果发送方发送数据的速率,超过了接收方处理数据的速率,接收方的缓冲区(缓存)就会被填满。此时,后续到达的数据帧将因为无处存放而被丢弃,从而造成数据丢失和网络资源的浪费。

而我们的目标是在发送方和接收方之间建立一种协调机制,让发送方根据接收方的实际接收能力来调整自己的发送速率。

一个简单的起点:停止-等待协议 (Stop-and-Wait)

这是最简单的流量控制协议。工作方式是发送方每发送一帧后,就必须停止发送,并等待接收方返回对该帧的确认(ACK)。只有收到确认后,才能发送下一帧。

优点:机制简单,天然地实现了流量控制和可靠传输(因为接收方不确认,发送方就不会发送)。

缺点:信道利用率极低。在发送方等待确认信号返回的漫长时间里,整个信道都处于空闲状态,造成了巨大的浪费,尤其是在卫星通信这种高延迟的场景下。

高效的解决方案:滑动窗口协议 (Sliding Window)

为了克服停止-等待协议的低效,滑动窗口协议应运而生。其核心思想是允许发送方在收到确认之前,连续发送多个数据帧。

窗口 (Window):

  • 发送窗口:在发送方,维持一个允许连续发送的帧的序号范围,称为“发送窗口”。窗口内所有帧都可以被发送出去,而无需等待确认。
  • 接收窗口:在接收方,维持一个允许接收的帧的序号范围,称为“接收窗口”。

滑动 (Sliding):

当发送方收到一个确认帧(例如,确认了窗口内的第一个帧)时,它就知道该帧已被成功接收,于是发送窗口就可以向前“滑动”,从而可以发送新的数据帧。

当接收方成功接收并向上层交付数据后,接收窗口也会向前“滑动”,准备接收后续的数据帧。

流量控制的关键在于接收窗口的大小。接收方可以通过确认帧(ACK)告诉发送方自己当前还能接收多少数据帧(即接收窗口的大小)。如果接收方缓冲区已满,它可以将接收窗口大小设为0,发送方收到这个信息后就会暂停发送,直到接收方处理完数据,重新开放窗口。这是一种非常灵活且高效的流量控制方式。

alt text

可靠传输机制

可靠传输机制必须确保数据不丢失、不重复、无差错、按顺序地交付给上层。这通常通过以下技术组合实现:

  • 帧编号 (Sequence Numbers):为每个帧分配一个唯一的序号,接收方可以据此判断是否有帧丢失或失序。
  • 确认 (Acknowledgements, ACKs):接收方通过发送ACK来告知发送方哪些帧已成功收到。
  • 超时重传 (Timeout Retransmission):发送方在发送一个帧后会启动一个计时器。如果在规定时间内没有收到对该帧的确认,就认为该帧(或其ACK)在途中丢失,并重新发送该帧。

基于滑动窗口,最主流的两种可靠传输协议是回退N帧协议选择重传协议。他们都属于ARQ(自动重传请求)协议的范畴。

此外, 前面提到的停止-等待协议也可以看作是滑动窗口协议的一种特殊情况, 其发送窗口和接收窗口大小均为1. 这意味着发送方在发送一帧后必须等待确认, 直到收到确认后才能发送下一帧. 在这样的情况下, 帧的编号只需要1位(0或1)即可, 因为在任何时刻, 发送方和接收方都只需要区分当前帧和下一帧.

回退N帧协议 (Go-Back-N, GBN)

工作方式: - 发送方可以连续发送多个帧(发送窗口大小 > 1)。 - 接收方只按顺序接收数据帧(接收窗口大小 = 1)。如果它期望收到第 n 帧,但却收到了第 n+1 帧,它会直接丢弃第 n+1 帧以及后续所有到达的帧,并反复发送对第 n−1 帧的确认。当发送方发现第 n 帧超时后,它会从第 n 帧开始,重新发送它后面所有已发送过的帧(即“回退N帧”)。

优缺点:接收方逻辑简单,无需缓存失序的帧。但效率较低,因为一次超时可能会导致大量本已正确到达的帧被重传。

alt text

需要注意的是, 回退N帧协议要求发送窗口的大小 WT <= 2k − 1 (k为帧序号位数), 以避免序号混淆. 例如, 如果序号位数为3位, 则序号范围为0~7, 发送窗口大小最大只能为7. 这是因为, 如果发送窗口大小等于8, 则在发送方发送完8个帧后, 第一个帧的序号将再次变为0, 此时接收方无法区分这是第一个帧还是第二轮发送的第一个帧, 导致序号混淆.

选择重传协议 (Selective Repeat, SR)

工作方式: - 发送方可以连续发送多个帧(发送窗口大小 > 1)。 - 接收方可以接收并缓存失序的帧(接收窗口大小 > 1)。如果它期望收到第 n 帧,但却收到了第 n+1 帧,它会先将 n+1 帧缓存起来,并发送一个对第 n−1 帧的确认(或专门的否定确认NAK),等待第 n 帧的到来。当发送方发现第 n 帧超时后,它只重新发送第 n 帧,而不会重传那些已经被确认或已经发送过的后续帧。

优缺点:信道效率极高,因为它最大限度地避免了不必要的重传。但实现起来更复杂,要求接收方有足够的缓存空间和更复杂的逻辑来处理失序的帧。

alt text

如上, 这里的选择重传协议还使用了NAK(否定确认)机制, 即接收方在发现某个帧有误或丢失时, 会立即发送一个NAK给发送方, 要求其重传该帧. 这样可以更快地触发重传, 提高传输效率.

不同的是, SR协议对接受窗口和发送窗口的大小都有要求. 具体来说, 发送窗口大小 WT 和接受窗口大小 WR 加起来必须满足 WT + WR <= 2k (k为帧序号位数), 否则, 当确认(ACK)信息丢失时,新旧窗口的序号发生重叠,从而导致接收方无法区分一个收到的帧究竟是“旧帧的重传”还是“新发送的帧”。

一般来说, 因为接受窗口必然<=发送窗口, 因此通常会设置 WT = WR = 2k − 1., 这样可以最大化窗口利用率, 同时避免序号混淆的问题.

假如违反这种规则

我们设定一个最简单的场景:帧序号用 k=2 位来表示。那么序号空间就是 2^k = 4,也就是说,序号范围为 0, 1, 2, 3,然后循环回 0。

我们设定发送窗口 W_T=3,接收窗口 W_R=3。这样 W_T+W_R=6 > 4。让我们一步步来看会发生什么:

第一步:初始状态 - 发送方的发送窗口是 {0, 1, 2}。 - 接收方的接收窗口也是 {0, 1, 2}。

第二步:发送与接收 - 发送方将窗口内的帧 0, 1, 2 全部发送出去。 - 接收方成功收到了这三个帧。因为它期望的就是 {0, 1, 2},所以它将这三个帧的数据交付给上层。

第三步:接收方滑动窗口并发回确认 - 接收方成功接收了 0, 1, 2,于是它的接收窗口向前滑动3个位置。 - 新的接收窗口变成了 {3, 0, 1}。它现在准备接收新一轮的帧了。 - 同时,接收方为 0, 1, 2 这三个帧都发回了确认信息 ACK(0), ACK(1), ACK(2)。

第四步:灾难发生——所有ACK全部丢失 - 假设网络出现问题,接收方发出的三个ACK信号在传输过程中全部丢失了。

第五步:发送方超时重传 - 发送方苦苦等待,但始终没有收到对帧 0, 1, 2 的任何确认。 - 最终,帧 0 的计时器超时。 - 发送方认为帧 0 在传输过程中丢失了,于是它重新发送帧 0。

第六步:接收方收到重传的帧 0 - 接收方此刻的接收窗口是 {3, 0, 1} (如第三步所示)。 - 它收到了一个序号为 0 的帧 (来自第五步发送方的重传)。 - 从接收方的视角看,序号 0 正好在它的接收窗口 {3, 0, 1} 内。它完全有理由认为,这是一个全新的、属于下一轮传输的帧 0,而不是对上一轮旧帧 0 的重传。它无法分辨这两种情况!最终导致了数据重复,协议的可靠性被彻底打破。

信道利用率 (Channel Utilization)

信道利用率是衡量数据链路层协议效率的一个重要指标。它表示在一个发送周期(从发送方开始发送分组收到第一个确认分组的时间)内,实际用于传输有用数据的时间占总时间的比例。

停止-等待协议的信道利用率

这是最简单的协议,但也是效率最低的。

停止-等待协议的一个完整“发送周期”包含以下几个部分:

  • TD数据帧发送时延):发送方发送一个数据分组(帧)所需的时间。
  • RTT往返传播时延):信号在信道中往返一次所需的时间,包括数据分组从发送方到接收方的传播时间,以及确认帧(ACK)从接收方回到发送方的传播时间。
  • TA(确认帧发送时延):接收方发送一个确认帧所需的时间。

在一个周期内,发送方只有在最初的 TD 时间内是在发送有效数据,其余的 RTT + TA 时间里,信道都在空闲等待。因此,其总周期为 TD + RTT + TA

将上述分析代入利用率的定义,我们得到停止-等待协议的信道利用率公式:

通常情况下,确认帧 TA 很短,可以忽略不计,公式可简化为:

从公式可以看出, 对于停止-等待协议,当往返时延 RTT 远大于数据帧发送时延 TD ​时,信道利用率会非常低。

连续ARQ协议(滑动窗口)的信道利用率

为了解决停止-等待协议的效率问题,引入了连续ARQ协议,它采用流水线传输 (Pipelining) 的方式,允许发送方在收到确认前连续发送多个分组。

设发送窗口大小为 n(即一次最多可以连续发送 n 个分组)。根据 n 是否能“填满”信道,分为两种情况。

一个完整的发送周期(从发送第1个分组到收到它的确认)总时长仍然是 TD + RTT + TA。我们需要看在这个周期内,发送方究竟发送了多少数据。

情况一:n ⋅ TD < TD + RTT + TA(窗口较小,无法填满信道)

此时发送方把窗口内的 n 个分组全部发完后,第一个分组的 ACK 还没有回来,因此发送方必须停下来等待,造成信道空闲。

利用率计算:在一个发送周期内,发送方有效发送数据的时间是 n ⋅ TD


情况二:n ⋅ TD ≥ TD + RTT + TA(窗口足够大,可以填满信道)

条件解读:当第一个分组的 ACK 返回时,发送方还没发完窗口内的 n 个分组,因此它可以继续不间断地发送新的分组,信道始终处于忙碌状态。

利用率计算:由于信道没有空闲,发送方一直在发送有效数据。

U = 1


结论: 连续 ARQ 协议通过流水线技术,极大地提高了信道利用率。只要发送窗口 n 足够大(满足 n ⋅ TD ≥ TD + RTT + TA),在不考虑差错的情况下,理论上可以达到 100% 的信道利用率,完全克服了停止-等待协议的效率瓶颈。

一般我们取发送窗口 n 为:

局域网 (Local Area Network, LAN)

局域网 (LAN) 是指在一个较小的地理范围内(如一栋建筑、一个校园或一个办公室),将各种计算机、服务器、打印机等设备互联起来组成的私有网络。

其特点是覆盖范围小, 但是通常具有高传输速率、低时延、低误码率

局域网的技术标准主要集中在OSI参考模型的最低两层:物理层和数据链路层。IEEE 802系列标准为了适应不同的局域网技术,将数据链路层进一步划分为两个子层:

逻辑链路控制 (LLC - Logical Link Control) 子层: 负责向上层(网络层)提供一个统一的接口,隐藏了不同MAC协议的差异。它也负责处理一些确认、流量控制等逻辑功能。

介质访问控制 (MAC - Medium Access Control) 子层: 这是局域网技术的核心。它负责数据帧的封装物理地址(MAC地址)的寻址,以及最重要的——如何协调对共享物理介质的访问(即我们前面讨论的CSMA/CD、CSMA/CA等协议)。

他们之间的结构关系为: 网络层 (L3) <–> LLC子层 (L2上) <–> MAC子层 (L2下) <–> 物理层 (L1)

局域网的三个决定性要素是拓扑结构、传输介质和介质访问控制方式,其中介质访问控制方式最为重要 。

以太网与 IEEE 802.3

以太网 (Ethernet) 是当今应用最广泛的有线局域网技术,其技术标准由 IEEE 802.3 规范定义。

MAC地址(或称物理地址)是一个48位(6字节)的全球唯一地址,固化在网卡的ROM中。它通常用12个十六进制数表示,如 02-60-8c-e4-b1-21 。前24位是厂商代码,后24位是厂商分配的序列号。

网卡通过硬件检查收到的MAC帧,如果目的地址是本机地址(单播)、广播地址(全1)或本机所在的多播组地址,则接收该帧,否则丢弃。

IEEE 802.11 无线局域网

VLAN 基本概念与基本原理

虚拟局域网 (VLAN) 是一种将一个大型物理局域网分割成多个逻辑上独立的虚拟网络的技术 。VLAN的作用主要有以下几个方面:

  • 隔离广播域:一个大型局域网是一个广播域,大量的广播帧(如ARP)会严重影响网络性能 。VLAN将网络分割成多个小的广播域,广播帧被限制在各自的VLAN内部 。

  • 增强安全性和管理:可以将不同部门或用户组划分到不同的VLAN中,即使他们物理上连接在同一台交换机,也无法直接通信,从而提高安全性 。

广域网(Wide Area Network, WAN)

广域网的基本概念

点对点协议

数据链路层设备

网桥

以太网交换机