数据链路层差错控制使用的算法详解

1. 引言

在计算机网络中,数据传输难免会受到噪声、干扰等因素的影响,导致接收方收到的数据与发送方不一致,这就是所谓的传输差错 。数据链路层的重要职责之一就是差错控制,它通过一系列算法来检测甚至纠正数据传输过程中出现的错误,确保向上层提供可靠的数据传输服务。

差错控制通常分为两个层面:

  • 差错检测:发现数据在传输过程中是否发生了错误;
  • 差错纠正/重传:发现错误后,通过重传或纠错码恢复正确的数据。

本文将系统梳理数据链路层中常用的差错控制算法,包括检测算法与重传机制两大类。

2. 差错检测算法

2.1 奇偶校验

奇偶校验是最简单的一种差错检测方法。其核心思想是在原始数据后面附加一个校验位,使得整个数据单元中"1"的个数为奇数或偶数。

  • 奇校验:保证数据中"1"的总数为奇数;
  • 偶校验:保证数据中"1"的总数为偶数。

示例 :假设要传输的数据为 1011001(其中"1"的个数为 4)。

  • 若采用偶校验,校验位应为 0,使"1"的总数保持偶数;
  • 若采用奇校验,校验位应为 1,使"1"的总数变为奇数。

局限性:奇偶校验只能检测出奇数个比特错误,当发生偶数个比特错误时(如两个比特同时翻转),校验结果仍然正确,无法发现错误,因此在实际网络中已较少单独使用。

2.2 循环冗余校验

2.2.1 基本原理

CRC的核心思想是将待发送的数据看作一个二进制多项式,然后用一个事先约定的生成多项式 G(x) 去除这个数据多项式(模 2 除法),得到的余数作为冗余码 附加在数据末尾一同发送。接收方收到数据后,用同一个生成多项式对收到的数据做模 2 除法,若余数为 0,则认为传输无差错;否则判定发生了错误。

2.2.2 模 2 除法

模 2 除法与普通除法类似,但减法是按位异或运算(相同为 0,不同为 1),不存在借位。

计算步骤:

假设数据为 101001,生成多项式为 1101(对应 x³ + x² + 1,阶数为 3)。

  1. 在数据末尾补 阶数个 0:101001 → 101001000;
  2. 用生成多项式对补零后的数据做模 2 除法;
  3. 得到的余数即为冗余码,附加到原始数据后发送。

整个过程的图解如下:
#mermaid-svg-AGIjhvSMITmoKuR2{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-AGIjhvSMITmoKuR2 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-AGIjhvSMITmoKuR2 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-AGIjhvSMITmoKuR2 .error-icon{fill:#552222;}#mermaid-svg-AGIjhvSMITmoKuR2 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-AGIjhvSMITmoKuR2 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-AGIjhvSMITmoKuR2 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-AGIjhvSMITmoKuR2 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-AGIjhvSMITmoKuR2 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-AGIjhvSMITmoKuR2 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-AGIjhvSMITmoKuR2 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-AGIjhvSMITmoKuR2 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-AGIjhvSMITmoKuR2 .marker.cross{stroke:#333333;}#mermaid-svg-AGIjhvSMITmoKuR2 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-AGIjhvSMITmoKuR2 p{margin:0;}#mermaid-svg-AGIjhvSMITmoKuR2 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-AGIjhvSMITmoKuR2 .cluster-label text{fill:#333;}#mermaid-svg-AGIjhvSMITmoKuR2 .cluster-label span{color:#333;}#mermaid-svg-AGIjhvSMITmoKuR2 .cluster-label span p{background-color:transparent;}#mermaid-svg-AGIjhvSMITmoKuR2 .label text,#mermaid-svg-AGIjhvSMITmoKuR2 span{fill:#333;color:#333;}#mermaid-svg-AGIjhvSMITmoKuR2 .node rect,#mermaid-svg-AGIjhvSMITmoKuR2 .node circle,#mermaid-svg-AGIjhvSMITmoKuR2 .node ellipse,#mermaid-svg-AGIjhvSMITmoKuR2 .node polygon,#mermaid-svg-AGIjhvSMITmoKuR2 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-AGIjhvSMITmoKuR2 .rough-node .label text,#mermaid-svg-AGIjhvSMITmoKuR2 .node .label text,#mermaid-svg-AGIjhvSMITmoKuR2 .image-shape .label,#mermaid-svg-AGIjhvSMITmoKuR2 .icon-shape .label{text-anchor:middle;}#mermaid-svg-AGIjhvSMITmoKuR2 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-AGIjhvSMITmoKuR2 .rough-node .label,#mermaid-svg-AGIjhvSMITmoKuR2 .node .label,#mermaid-svg-AGIjhvSMITmoKuR2 .image-shape .label,#mermaid-svg-AGIjhvSMITmoKuR2 .icon-shape .label{text-align:center;}#mermaid-svg-AGIjhvSMITmoKuR2 .node.clickable{cursor:pointer;}#mermaid-svg-AGIjhvSMITmoKuR2 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-AGIjhvSMITmoKuR2 .arrowheadPath{fill:#333333;}#mermaid-svg-AGIjhvSMITmoKuR2 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-AGIjhvSMITmoKuR2 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-AGIjhvSMITmoKuR2 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-AGIjhvSMITmoKuR2 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-AGIjhvSMITmoKuR2 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-AGIjhvSMITmoKuR2 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-AGIjhvSMITmoKuR2 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-AGIjhvSMITmoKuR2 .cluster text{fill:#333;}#mermaid-svg-AGIjhvSMITmoKuR2 .cluster span{color:#333;}#mermaid-svg-AGIjhvSMITmoKuR2 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-AGIjhvSMITmoKuR2 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-AGIjhvSMITmoKuR2 rect.text{fill:none;stroke-width:0;}#mermaid-svg-AGIjhvSMITmoKuR2 .icon-shape,#mermaid-svg-AGIjhvSMITmoKuR2 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-AGIjhvSMITmoKuR2 .icon-shape p,#mermaid-svg-AGIjhvSMITmoKuR2 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-AGIjhvSMITmoKuR2 .icon-shape .label rect,#mermaid-svg-AGIjhvSMITmoKuR2 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-AGIjhvSMITmoKuR2 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-AGIjhvSMITmoKuR2 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-AGIjhvSMITmoKuR2 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是
否
原始数据
补零(补生成多项式阶数个 0)
模 2 除法(异或运算)
得到余数(冗余码)
拼接:原始数据 + 余数
发送至接收方
接收方再次模 2 除法
余数为 0?
数据正确,接收
检测到错误,丢弃或请求重传

2.2.3 常用生成多项式
标准 生成多项式
CRC-8 x⁸ + x² + x + 1
CRC-16 x¹⁶ + x¹⁵ + x² + 1
CRC-CCITT x¹⁶ + x¹² + x⁵ + 1
CRC-32(以太网) x³² + x²⁶ + x²³ + x²² + x¹⁶ + x¹² + x¹¹ + x¹⁰ + x⁸ + x⁷ + x⁵ + x⁴ + x² + x + 1

CRC 的检错能力很强,能检测出所有单比特错误、所有双比特错误、所有奇数个错误以及所有长度不超过生成多项式阶数的突发错误。

2.3 校验和

校验和算法常见于 IP、TCP、UDP 等网络层和传输层协议。其基本思想是将数据划分为若干固定长度的单元(如 16 位),将所有单元按二进制反码加法累加,最后取反码得到校验和。接收方将数据和校验和一起进行同样的累加,若结果全为 1,则说明数据无误。

校验和实现简单、计算开销小,但检错能力弱于 CRC,主要用于上层协议中。

3. 差错纠正与重传机制

单纯依靠检测算法只能"发现"错误,无法"修复"错误。数据链路层通过自动重传请求机制,在检测到错误后通知发送方重新发送数据,从而保证可靠传输。

3.1 停止等待 ARQ

停止等待 ARQ 是最基础的重传机制:发送方每发送一帧后就必须停下来,等待接收方的确认帧(ACK)。

工作流程:

  1. 发送方发送一帧数据,并启动超时定时器;
  2. 接收方收到帧后校验:
    • 若无误,回复 ACK;
    • 若出错,直接丢弃,不回复(或回复 NAK);
  3. 发送方在超时前收到 ACK,继续发送下一帧;
  4. 若超时未收到 ACK,重发该帧。

接收方 发送方 接收方 发送方 #mermaid-svg-UYyrQ0fWl8Aa3P3s{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-UYyrQ0fWl8Aa3P3s .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-UYyrQ0fWl8Aa3P3s .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-UYyrQ0fWl8Aa3P3s .error-icon{fill:#552222;}#mermaid-svg-UYyrQ0fWl8Aa3P3s .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-UYyrQ0fWl8Aa3P3s .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-UYyrQ0fWl8Aa3P3s .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-UYyrQ0fWl8Aa3P3s .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-UYyrQ0fWl8Aa3P3s .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-UYyrQ0fWl8Aa3P3s .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-UYyrQ0fWl8Aa3P3s .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-UYyrQ0fWl8Aa3P3s .marker{fill:#333333;stroke:#333333;}#mermaid-svg-UYyrQ0fWl8Aa3P3s .marker.cross{stroke:#333333;}#mermaid-svg-UYyrQ0fWl8Aa3P3s svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-UYyrQ0fWl8Aa3P3s p{margin:0;}#mermaid-svg-UYyrQ0fWl8Aa3P3s .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-UYyrQ0fWl8Aa3P3s text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-UYyrQ0fWl8Aa3P3s .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-UYyrQ0fWl8Aa3P3s .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-UYyrQ0fWl8Aa3P3s .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-UYyrQ0fWl8Aa3P3s .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-UYyrQ0fWl8Aa3P3s #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-UYyrQ0fWl8Aa3P3s .sequenceNumber{fill:white;}#mermaid-svg-UYyrQ0fWl8Aa3P3s #sequencenumber{fill:#333;}#mermaid-svg-UYyrQ0fWl8Aa3P3s #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-UYyrQ0fWl8Aa3P3s .messageText{fill:#333;stroke:none;}#mermaid-svg-UYyrQ0fWl8Aa3P3s .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-UYyrQ0fWl8Aa3P3s .labelText,#mermaid-svg-UYyrQ0fWl8Aa3P3s .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-UYyrQ0fWl8Aa3P3s .loopText,#mermaid-svg-UYyrQ0fWl8Aa3P3s .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-UYyrQ0fWl8Aa3P3s .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-UYyrQ0fWl8Aa3P3s .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-UYyrQ0fWl8Aa3P3s .noteText,#mermaid-svg-UYyrQ0fWl8Aa3P3s .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-UYyrQ0fWl8Aa3P3s .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-UYyrQ0fWl8Aa3P3s .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-UYyrQ0fWl8Aa3P3s .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-UYyrQ0fWl8Aa3P3s .actorPopupMenu{position:absolute;}#mermaid-svg-UYyrQ0fWl8Aa3P3s .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-UYyrQ0fWl8Aa3P3s .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-UYyrQ0fWl8Aa3P3s .actor-man circle,#mermaid-svg-UYyrQ0fWl8Aa3P3s line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-UYyrQ0fWl8Aa3P3s :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 帧 1 出错,丢弃 超时未收到 ACK 发送帧 0ACK 0发送帧 1重发帧 1ACK 1

特点:

  • 实现简单,缓冲区开销小;
  • 信道利用率低:发送方在等待 ACK 的期间处于空闲状态,不适用于高速或高延迟链路。

3.2 回退 N 帧 ARQ

为了克服停止等待 ARQ 效率低的问题,回退 N 帧 ARQ 采用流水线方式,允许发送方在未收到确认的情况下连续发送多个帧。

核心机制:

  • 发送方维护一个大小为 N 的发送窗口,窗口内的帧可连续发送;
  • 接收方只按序接收,若某帧出错,则丢弃该帧及之后的所有帧;
  • 发送方超时后,从出错的帧开始重传窗口内所有后续帧。

示例:假设发送窗口大小为 4,发送了帧 0、1、2、3;帧 1 出错被丢弃。接收方即使正确收到了帧 2、3,也会将其丢弃。发送方超时后,从帧 1 开始重传帧 1、2、3。

这种机制应使用累计确认:ACK n 表示"帧 n 及之前的所有帧均已正确收到",减少了确认帧的数量。

特点:

  • 提高了信道利用率;
  • 但出错时会重传大量已经正确接收的帧,造成带宽浪费。

3.3 选择重传 ARQ

选择重传 ARQ 是回退 N 帧 ARQ 的改进版本。接收方对出错帧之后的正确帧不再丢弃,而是缓存起来,只要求发送方重传出错的那一帧。

核心机制:

  • 接收方维护一个接收窗口,缓存失序但正确的帧;
  • 发送方只为损坏或丢失的帧单独重传;
  • 接收方收齐所有帧后,按序交付给上层。

特点:

  • 带宽利用率最高,只重传真正出错的帧;
  • 但接收方需要更大的缓冲区来缓存失序帧,实现复杂度更高。

4. 纠错编码:海明码

除了"检测 + 重传"的思路,还有一种思路是让接收方直接纠正 错误,即使用纠错码。海明码就是其中的代表,由 Richard Hamming 提出。

4.1 基本原理

海明码通过在数据中插入多个冗余校验位 ,使得每个校验位覆盖不同的数据位组合。当某个比特出错时,根据校验结果的组合可以定位到具体出错的比特,从而直接翻转该位完成纠正。

  • 若数据位为 m 位,冗余位为 r 位,需满足:2^r >= m + r + 1;
  • 例如:4 位数据需要 3 位冗余(2³ = 8 >= 4 + 3 + 1 = 8)。

4.2 计算步骤

以 4 位数据 1011 为例。由 2^r >= m + r + 1 可知:m=4 时 r=3,因此码字总长度为 7 位。

第 1 步:确定码字位置

冗余位需要放在 2 的幂次位置,即第 1、2、4 位;则数据位依次放到第 3、5、6、7 位:

复制代码
位置编号:1  2  3  4  5  6  7
码字内容:_  _  1  _  0  1  1

第 2 步:计算冗余位的值

每个冗余位按位置编号的二进制特征,负责校验特定位置的数据位:

冗余位 所在位置 位置二进制 负责校验的位置 覆盖的数据位
r1 1 001 1、3、5、7 D1、D2、D4
r2 2 010 2、3、6、7 D1、D3、D4
r4 4 100 4、5、6、7 D2、D3、D4

规律是:某冗余位负责校验「位置编号二进制中对应位为 1」的所有位置。例如 r1 的二进制是 001,最低位为 1,因此它校验所有二进制最低位为 1 的位置(1、3、5、7)。

采用偶校验 计算每个冗余位,使该校验组中 1 的总数为偶数(异或和为 0):

  • r1 :覆盖 D1、D2、D4 = 1、0、1,异或结果为 1 ⊕ 0 ⊕ 1 = 0,因此 r1 取 0;
  • r2 :覆盖 D1、D3、D4 = 1、1、1,异或结果为 1 ⊕ 1 ⊕ 1 = 1,为凑成偶数个 1,r2 取 1;
  • r4 :覆盖 D2、D3、D4 = 0、1、1,异或结果为 0 ⊕ 1 ⊕ 1 = 0,因此 r4 取 0。

最终得到的 7 位海明码为:

复制代码
位置编号:1  2  3  4  5  6  7
码字内容:0  1  1  0  0  1  1

所以数据 1011 编码后的海明码是 0110011。

第 3 步:接收方校验与纠错

接收方重新计算三个校验组,得到三个校验结果 S1、S2、S4:

  • S1 = r1 ⊕ D1 ⊕ D2 ⊕ D4(对应位置 1、3、5、7)
  • S2 = r2 ⊕ D1 ⊕ D3 ⊕ D4(对应位置 2、3、6、7)
  • S4 = r4 ⊕ D2 ⊕ D3 ⊕ D4(对应位置 4、5、6、7)

如果没有错误,这三个表达式的值全为 0。

假设传输过程中第 6 位发生翻转(D3 由 1 变成 0),收到的码字变为 0110001。重新计算:

  • S1 = 0 ⊕ 1 ⊕ 0 ⊕ 1 = 0
  • S2 = 1 ⊕ 1 ⊕ 0 ⊕ 1 = 1
  • S4 = 0 ⊕ 0 ⊕ 0 ⊕ 1 = 1

将结果按 S4 S2 S1 排列得到二进制数 110,转换为十进制正好是 6,说明第 6 位出错。接收方只需把第 6 位翻转回来(0 → 1),即可恢复正确的海明码 0110011。

如果 S4 S2 S1 = 000,则说明传输无错误。这就是海明码「不仅能检错,还能定位并纠正单比特错误」的核心过程。

海明码属于前向纠错技术,适用于实时性要求高、不适合频繁重传的场景(如深空通信、实时音视频)。

5. LDPC

5.1 基本原理

LDPC(Low-Density Parity-Check,低密度奇偶校验码)由 Gallager 于 1962 年提出,但因当时硬件条件限制长期未被重视,直到后来才被重新发现并广泛应用于现代通信系统。它的核心是用一个稀疏校验矩阵 H 来描述码字:矩阵中绝大多数元素为 0,只包含少量 1,因此称为"低密度"。

以一个最简单的 (6, 3) LDPC 码为例:码字长度为 6,包含 3 个信息位和 3 个校验位。假设其校验矩阵 H 为:

复制代码
      v1 v2 v3 v4 v5 v6
c1 [  1  1  0  1  0  0 ]
c2 [  0  1  1  0  1  0 ]
c3 [  1  0  1  0  0  1 ]

矩阵的每一行对应一个校验节点 ,每一列对应一个变量节点。第 1 行表示校验节点 c1 连接变量节点 v1、v2、v4,因此它给出的校验方程是:

  • c1:v1 ⊕ v2 ⊕ v4 = 0
  • c2:v2 ⊕ v3 ⊕ v5 = 0
  • c3:v1 ⊕ v3 ⊕ v6 = 0

也就是说,任何合法码字都必须同时满足上面三个异或方程。

LDPC 码可以通过 Tanner 图来描述变量节点与校验节点之间的关系。上例对应的 Tanner 图如下:
#mermaid-svg-IU2gjADf5c90QEhZ{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-IU2gjADf5c90QEhZ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-IU2gjADf5c90QEhZ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-IU2gjADf5c90QEhZ .error-icon{fill:#552222;}#mermaid-svg-IU2gjADf5c90QEhZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-IU2gjADf5c90QEhZ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-IU2gjADf5c90QEhZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-IU2gjADf5c90QEhZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-IU2gjADf5c90QEhZ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-IU2gjADf5c90QEhZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-IU2gjADf5c90QEhZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-IU2gjADf5c90QEhZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-IU2gjADf5c90QEhZ .marker.cross{stroke:#333333;}#mermaid-svg-IU2gjADf5c90QEhZ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-IU2gjADf5c90QEhZ p{margin:0;}#mermaid-svg-IU2gjADf5c90QEhZ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-IU2gjADf5c90QEhZ .cluster-label text{fill:#333;}#mermaid-svg-IU2gjADf5c90QEhZ .cluster-label span{color:#333;}#mermaid-svg-IU2gjADf5c90QEhZ .cluster-label span p{background-color:transparent;}#mermaid-svg-IU2gjADf5c90QEhZ .label text,#mermaid-svg-IU2gjADf5c90QEhZ span{fill:#333;color:#333;}#mermaid-svg-IU2gjADf5c90QEhZ .node rect,#mermaid-svg-IU2gjADf5c90QEhZ .node circle,#mermaid-svg-IU2gjADf5c90QEhZ .node ellipse,#mermaid-svg-IU2gjADf5c90QEhZ .node polygon,#mermaid-svg-IU2gjADf5c90QEhZ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-IU2gjADf5c90QEhZ .rough-node .label text,#mermaid-svg-IU2gjADf5c90QEhZ .node .label text,#mermaid-svg-IU2gjADf5c90QEhZ .image-shape .label,#mermaid-svg-IU2gjADf5c90QEhZ .icon-shape .label{text-anchor:middle;}#mermaid-svg-IU2gjADf5c90QEhZ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-IU2gjADf5c90QEhZ .rough-node .label,#mermaid-svg-IU2gjADf5c90QEhZ .node .label,#mermaid-svg-IU2gjADf5c90QEhZ .image-shape .label,#mermaid-svg-IU2gjADf5c90QEhZ .icon-shape .label{text-align:center;}#mermaid-svg-IU2gjADf5c90QEhZ .node.clickable{cursor:pointer;}#mermaid-svg-IU2gjADf5c90QEhZ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-IU2gjADf5c90QEhZ .arrowheadPath{fill:#333333;}#mermaid-svg-IU2gjADf5c90QEhZ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-IU2gjADf5c90QEhZ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-IU2gjADf5c90QEhZ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-IU2gjADf5c90QEhZ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-IU2gjADf5c90QEhZ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-IU2gjADf5c90QEhZ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-IU2gjADf5c90QEhZ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-IU2gjADf5c90QEhZ .cluster text{fill:#333;}#mermaid-svg-IU2gjADf5c90QEhZ .cluster span{color:#333;}#mermaid-svg-IU2gjADf5c90QEhZ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-IU2gjADf5c90QEhZ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-IU2gjADf5c90QEhZ rect.text{fill:none;stroke-width:0;}#mermaid-svg-IU2gjADf5c90QEhZ .icon-shape,#mermaid-svg-IU2gjADf5c90QEhZ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-IU2gjADf5c90QEhZ .icon-shape p,#mermaid-svg-IU2gjADf5c90QEhZ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-IU2gjADf5c90QEhZ .icon-shape .label rect,#mermaid-svg-IU2gjADf5c90QEhZ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-IU2gjADf5c90QEhZ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-IU2gjADf5c90QEhZ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-IU2gjADf5c90QEhZ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} v1
c1
v2
v4
c2
v3
v5
c3
v6

图中左侧为变量节点,右侧为校验节点。每个校验节点要求与其相连的变量节点异或和为 0,从而构成一组校验约束。

5.2 编码与译码

编码示例

编码时,根据校验矩阵 H 构造生成矩阵 G,将信息位映射为满足所有校验约束的码字。实际系统中常采用系统化编码,即码字前半部分保持信息位不变,后半部分为计算出的校验位。

继续使用上面的 (6, 3) LDPC 码。信息位为 v1、v2、v3,校验位为 v4、v5、v6。根据校验方程可以反推出校验位的计算公式:

  • v4 = v1 ⊕ v2
  • v5 = v2 ⊕ v3
  • v6 = v1 ⊕ v3

假设信息位为 1 0 1,代入计算:

  • v4 = 1 ⊕ 0 = 1
  • v5 = 0 ⊕ 1 = 1
  • v6 = 1 ⊕ 1 = 0

最终得到码字 1 0 1 1 1 0。接收方收到码字后,只需重新计算三个校验方程,若结果全为 0,则说明传输无误。

置信传播译码步骤

译码是 LDPC 码的核心。接收方通常使用置信传播算法,在变量节点与校验节点之间迭代传递软信息,逐步修正错误。基本流程如下:

  1. 初始化:根据接收到的每个比特,计算初始概率(或对数似然比),作为变量节点的初始信息;
  2. 变量节点更新:每个变量节点把「来自信道的信息」和「来自校验节点的信息」合并后,传递给相连的校验节点;
  3. 校验节点更新:每个校验节点根据其他连接变量节点的信息,更新自己要传回的信息;
  4. 硬判决:根据变量节点汇总的全部信息,对每个比特做 0 或 1 的判决;
  5. 迭代校验:用校验矩阵检查判决结果。若所有校验方程均满足,译码结束;否则回到第 2 步继续迭代,直到满足条件或达到最大迭代次数。

继续用上面的例子说明:假设发送码字 1 0 1 1 1 0,传输过程中 v2 发生翻转,接收方收到 1 1 1 1 1 0。此时校验方程 c1 = 1 ⊕ 1 ⊕ 1 = 1,不再为 0,说明出现错误。置信传播算法会通过校验节点与变量节点之间的信息交换,逐步提高"v2 出错"的可信度,最终将其判决修正为 0,恢复正确码字 1 0 1 1 1 0。

相比海明码主要纠正单比特错误,LDPC 码通过稀疏校验矩阵和迭代译码能够纠正更多随机错误,性能可以接近香农极限。

5.3 特点与应用

  • 纠错能力强,性能接近信道容量;
  • 校验矩阵稀疏,适合高效存储与并行硬件实现;
  • 采用迭代译码,复杂度可控。

LDPC 码已广泛应用于 Wi-Fi(802.11n/ac/ax) 、5G NR 数据信道、数字电视、深空通信等场景。与 5G 控制信道采用的 Polar 码不同,LDPC 码通常用于数据信道,因为它们适合长码块和高吞吐量场景。

6. 数据链路层差错控制的实际应用

协议/技术 采用的算法
以太网 CRC-32
Wi-Fi(802.11) CRC-32
HDLC / PPP CRC-16 / CRC-CCITT
蓝牙 ARQ + CRC
5G NR LDPC 码 + Polar 码(信道编码)

现代数据链路层普遍采用 CRC 检测 + ARQ 重传 的组合方案:CRC 负责高效地发现错误,ARQ 机制负责在发现错误后可靠地恢复数据。而在对时延极度敏感或无法回传确认的场景中,则倾向于使用海明码、LDPC 码等纠错编码。

7. 总结

数据链路层的差错控制是保障网络通信可靠性的基石。本文围绕"检测"与"纠正/重传"两条主线,梳理了以下核心内容:

  • 检测算法:奇偶校验(简单但能力有限)、CRC(检错能力强、应用最广)、校验和(实现简单、用于上层协议);
  • 重传机制:停止等待 ARQ(简单低效)、回退 N 帧 ARQ(流水线 + 批量重传)、选择重传 ARQ(只重传出错帧,效率最高);
  • 纠错编码 :海明码可以直接定位并纠正单比特错误;LDPC 码通过稀疏校验矩阵和迭代译码实现接近香农极限的性能,适用于高可靠性通信场景。
    理解这些算法的原理与适用场景,不仅有助于深入掌握数据链路层的工作原理,也为学习传输层 TCP 的可靠传输机制打下了坚实基础。
相关推荐
努力努力再努力wz2 小时前
【C++ 高阶系列】C++ 高性能网络编程:当 Reactor 遇见协程:从 epoll 回调到异步 MySQL,彻底打通任务挂起与恢复
网络·c++·mysql
loulanyue_2 小时前
当AI学会自主攻击与渗透破壁:Agent行为链失控与Mythos级攻防颠覆下的安全范式重构——读CNCC2026第六届网络生态治理论坛实录
网络·人工智能·安全
2401_868534782 小时前
英语演讲:麻省理工校长2024年毕业典礼演讲
服务器·网络
码完就睡3 小时前
Linux——以太网协议
运维·服务器·网络·1024程序员节
CV爱数码3 小时前
论文精读|RED-CNN:残差编解码网络,低剂量 CT 去噪的经典基线
网络·人工智能·算法·cnn·ct·重建·x-ray
星恒讯工业路由器3 小时前
Modbus透传和Modbus网关有什么区别?从字节转发到协议翻译的选型思路
网络·物联网·modbus·工业物联网·工业网关·rs485·协议转换
李&@杰3 小时前
交换机PoE供电不足导致AP反复重启故障处理
网络·华为
香蕉大香蕉(06敬畏市场)3 小时前
高频八股 · Java 并发编程(10):异步、ThreadLocal 与虚拟线程(收官)
java·开发语言·网络·jvm·python·ai·实习
钱工的门窗技术笔记4 小时前
铝木复合门窗中木材的角色分类与界面可分解性:结构判定、失效路径与维护设计
网络·物联网·数据分析