计算机网络自顶向下方法第九版学习:# 第7章 无线与移动网络(Wireless and Mobile Networks)详细解析
fill:#333;important;important;fill:none;color:#333;color:#333;important;fill:none;fill:#333;height:1em;第7章 无线与移动网络7.1 网络基本构成7.2 物理层特性无线接入网RAN / WLAN无线核心网服务器/路由器基站切换 Handoff电磁波参数幅度/频率/相位/波长功率与带宽功率谱密度噪声
继续回顾一下各层的作用加深印象

应用层——直接面向用户和应用程序,定义数据的格式与含义。浏览器用 HTTP/HTTPS,邮件用 SMTP,域名解析用 DNS,都在这一层完成。
传输层——负责"端到端"的连接,也就是从你的进程到对方的进程。TCP 提供可靠传输(确认、重传、顺序),UDP 则舍弃可靠性换取低延迟,适合实时音视频等场景。
网络层——负责跨越多个网络把数据包从源头路由到目的地。IP 地址就在这一层,路由器依据路由表在这一层做转发决策。
链路层——负责同一段物理链路上的相邻节点之间传输数据帧,使用 MAC 地址而非 IP 地址寻址,以太网和 Wi-Fi 都属于这一层。
数据发送时,每经过一层就会被"封装"加上该层的头部(Frame → Packet → Segment → Message);接收时逐层"解封装",直到交给应用程序。这个过程叫做协议封装 (Encapsulation)。
ALOHA — 最原始的"想发就发"协议。多人共用一条信道,谁想说话就直接说,撞上了(冲突)就等个随机时间再重发。就像一群人在黑暗里同时喊话,撞上了就各自闭嘴数秒再试。
CSMA/CD — 以太网用的"先听后说,边说边听"。发之前先听信道有没有人在用,没人才发;发的过程中如果检测到冲突,立刻停止,等随机时间再重发。比 ALOHA 聪明很多,是有线以太网的基础。
TDM / FDM — 两种共享信道的方式。TDM(时分复用):大家轮流用,每人分一个时间片,就像共用一台打印机排队。FDM(频分复用):把频率切成多份,大家各占一段频率同时传,就像 FM 广播里不同电台占不同频率互不干扰。
MPLS — 给数据包贴"快递面单"走高速公路。普通 IP 路由每跳都要查路由表(很慢),MPLS 在包外面贴一个短标签,路由器只看标签直接转发,速度极快。电信骨干网大量使用。
MDC — 模块化数据中心(Module Data Center)。把服务器、网络、制冷、电源全打包成一个集装箱式模块,需要扩容就再拉一个模块过来接上,像积木一样。
SDN — 软件定义网络。传统路由器/交换机"脑子(控制逻辑)和身体(转发硬件)“是一体的,改配置很麻烦。SDN 把控制逻辑抽出来放到一个中央"大脑”(控制器)里,用软件统一管理所有设备的转发规则,灵活得多。
VXLAN — 在 IP 网络上"套壳"出一个虚拟二层网络。云计算里成千上万台虚拟机需要像在同一局域网里互通,但物理网络根本不是这么布的。VXLAN 把二层以太网帧塞进 UDP 包里跨网传输,让虚拟机"以为"自己在同一个大局域网——就像快递套娃,外面是 IP 包,里面藏着以太网帧。
章节导读
过去15年,无线网络爆炸式增长。2025年,无线互联网用户数量是有线用户的5倍,约60%的网页流量来自移动设备。无线网络的挑战与有线网络截然不同,因此需要专门一章来研究。
7.1 无线网络的基本构成
网络整体架构
用户设备 (User Devices)
手机/无人机/笔记本/汽车
|
| (无线电波)
|
[基站 Base Station]
|
| (有线/无线)
|
┌─────────────────────┐
| 无线核心网 |
| 路由器/交换机/服务器 |
└─────────────────────┘
|
互联网 (Internet)
Mermaid 拓扑图:
五大核心组成要素
1. 无线接入网(Wireless Access Network)
位于整个网络的最外边缘,负责把用户设备通过无线信道连接进来。
- 蜂窝网络中叫做:RAN(Radio Access Network,无线接入网)
- WiFi 网络中叫做:WLAN(Wireless Local Area Network,无线局域网)
可以类比为"小区门卫"——你进小区必须先经过门卫。
2. 无线核心网(Wireless Core Network)
位于接入网之后,由服务器、存储、路由器和(通常是有线的)链路组成,负责:
- 用户身份管理
- 移动性管理
- 数据转发到互联网
WiFi 没有专属核心网,企业 WiFi 复用有线局域网基础设施。
3. 无线设备(Wireless Devices)
手机、平板、笔记本、IoT 传感器等——这些就是跑应用的终端。
4. 基站(Base Station)
无线网络中最独特、最关键的组件,有线网络中没有对应物。
- 负责与所有关联设备收发数据包
- 一个基站通常管理多个设备
- 4G 基站叫 eNodeB(eNB)
- 5G 基站叫 gNodeB(gNB)
- WiFi 基站叫 接入点(AP, Access Point)
传输方向定义: - 基站 → 设备:下行链路(Downlink)
- 设备 → 基站:上行链路(Uplink)
5. 基础设施模式 vs 自组织模式
| 模式 | 说明 | 例子 |
|---|---|---|
| 基础设施模式(Infrastructure) | 设备通过基站接入网络,由网络提供地址、路由等服务 | WiFi、5G |
| 自组织模式(Ad Hoc) | 设备之间直接通信,自行组织,自己处理路由 | 蓝牙网络 |
切换(Handoff/Handover):当移动设备从一个基站的覆盖范围移动到另一个基站的范围时,会发生基站切换。就像你从一个小区走到另一个小区,换了一个"接待员"。
7.2 无线网络物理层
7.2.1 无线信道特性
电磁波基本参数(图7.2)
无线通信的本质是:发射天线中变化的电流产生电磁波,电磁波在空间传播,在接收天线中感应出电流。
一个正弦电磁波由以下参数描述:
幅度(Amplitude):波的"高度",代表信号强度(功率)
波长(Wavelength) λ \lambda λ:相邻两个波峰之间的距离(单位:米)
周期(Cycle time):相邻两个波峰之间的时间间隔(单位:秒)
频率(Frequency) f f f:每秒完成的完整周期数,单位赫兹(Hz)
f = 1 周期时间 f = \frac{1}{\text{周期时间}} f=周期时间1
电磁波以近似光速传播:
c ≈ 3 × 10 8 m/s c \approx 3 \times 10^8 \text{ m/s} c≈3×108 m/s
波长与频率的关系:
λ = c f \lambda = \frac{c}{f} λ=fc
相位(Phase):波在某时刻处于一个周期中的哪个位置,用 0 ° 0° 0° 到 360 ° 360° 360° 表示。
- 如果相位为 270 ° 270° 270°,就意味着已经完成了 270 360 = 75 % \frac{270}{360} = 75\% 360270=75% 的周期。
一个正弦波的示意(ASCII):
幅度
| /\ /\
| / \ / \
--+------/----\----/----\----> 时间/空间
| / \ / \
| / \/ \
|
0° 90° 180° 270° 360° (相位)
|<------一个波长λ------->|
功率与带宽
功率(Power):发射机每单位时间放入电磁波的能量,单位瓦(W)或毫瓦(mW)。可以理解为信号的"强度"。
工程师有时用**分贝毫瓦(dBm)**来表示功率:
P d B m = 10 log 10 ( P m W 1 mW ) P_{dBm} = 10 \log_{10}\left(\frac{P_{mW}}{1 \text{ mW}}\right) PdBm=10log10(1 mWPmW)
功率谱密度(Power Spectral Density):信号的功率如何分布在不同频率上(图7.3a)。
带宽(Bandwidth):信号所占频率范围的宽度,单位赫兹(Hz)。
图7.3b 的例子:WiFi 信道6,载波频率 2.438 2.438 2.438 GHz,带宽 22 22 22 MHz,范围从 2.427 2.427 2.427 GHz 到 2.449 2.449 2.449 GHz。
注意区分两种"带宽":
- 物理带宽:频率范围宽度,单位 Hz
- 链路带宽:数据传输速率,单位 bps
两者相关但不同:物理带宽越大,通常可以支持更高的数据传输速率。
带宽与传输速率的例子:
- 20 MHz 宽的 802.11n WiFi 信道:最大 72.2 Mbps
- 40 MHz 宽的 802.11n WiFi 信道:最大 150 Mbps
噪声(图7.4)
接收到的信号 = 原始信号 + 噪声
噪声来源:
- 干扰发射机:同频段的其他设备(邻居的 WiFi、婴儿监视器、车库门遥控器)
- 电磁辐射体:电动机、微波炉
- 热噪声和电子噪声:发射/接收端硬件本身的电子噪声
原始信号: /\/\/\/\/\/\/\/\/\/\/\/\
噪声: ~^~~^~^^^^~~^~~~^~~^^~~~
接收信号: /\/^/\^/\/\^/\/\/^^\/\/\
↑ 中间某段信号被噪声严重干扰,波形变形
信噪比(SNR)和香农定理
信噪比(Signal-to-Noise Ratio, SNR):信号功率与噪声功率之比,用分贝(dB)表示:
SNR d B = 10 log 10 ( 接收信号功率 噪声功率 ) \text{SNR}_{dB} = 10 \log_{10}\left(\frac{\text{接收信号功率}}{\text{噪声功率}}\right) SNRdB=10log10(噪声功率接收信号功率)
- SNR = 0 dB 表示信号功率等于噪声功率(很差)
- WiFi 最低可接受 SNR 约 20 dB
- LTE 最低可接受 SNR 约 -5 至 18 dB(视调制方式而定)
香农容量定理(Shannon’s Capacity Theorem):
给定信道带宽 B B B(Hz)和信噪比 SNR,该信道理论上能无错误传输的最大速率为:
C = B log 2 ( 1 + 接收信号功率 噪声功率 ) (bps) C = B \log_2\left(1 + \frac{\text{接收信号功率}}{\text{噪声功率}}\right) \quad \text{(bps)} C=Blog2(1+噪声功率接收信号功率)(bps)
其中 C C C 是信道容量(Channel Capacity)上界。
两个重要推论:
- 带宽 B B B 加倍 → 容量 C C C 加倍(线性关系)
- SNR 很高时,继续增加 SNR 对容量提升效果递减(对数关系,边际收益下降)
7.2.2 无线信道的三大物理特性
1. 路径损耗(Path Loss / Attenuation)
信号在传播过程中会衰减。在无障碍直线传播(自由空间)情况下:
P 接收 P 发送 ∼ 1 ( f ⋅ d ) 2 \frac{P_{\text{接收}}}{P_{\text{发送}}} \sim \frac{1}{(f \cdot d)^2} P发送P接收∼(f⋅d)21
其中 f f f 是频率, d d d 是距离。
直觉解释(图7.5):
发射点 ●
\
\──── 距离 d ────> [面积1份]
\
\─── 距离 2d ──> [面积4份]
\
\── 距离 3d ─> [面积9份]
同样的能量,扩散到更大的面积上,单位面积的功率就更小了。
面积按距离的平方增长 → 功率按距离的平方减小
路径损耗指数(Path Loss Exponent):
- 自由空间(空旷):指数 = 2
- 城市室外环境:指数 ≈ 3
- 室内建筑内:指数 ≥ 4
频率越高,衰减越大: - 低频(kHz级):传播距离远,速率低 → 用于无线导航、航海
- 高频(GHz级):传播距离近,速率高 → 用于蜂窝网络、WiFi
2. 隐藏终端问题(Hidden Terminal Problem,图7.6)
由于路径损耗,可能出现:
- A 和 B 能互相听到
- B 和 C 能互相听到
- A 和 C 互相听不到(A 和 C 对彼此是"隐藏的")
信号强度
| 检测阈值
| A的信号 B的信号 C的信号
| \ / \ / /
| \ / \ / /
|------\/-------X---/------> 空间位置
| / \ / \ /
| / \ / X
| A B到达 C
| →← (A和B互达) →←(B和C互达)
| A到C信号已低于检测阈值,A和C互不可见
后果:A 和 C 同时向 B 发送数据时,它们各自监听信道发现"没人在发"(因为听不到对方),但它们的信号会在 B 处发生碰撞。这就是为什么 WiFi 使用 CSMA/CA 而不是 CSMA/CD。
3. 多径效应(Multipath,图7.7 和 图7.8)
发射的无线电波会沿多条路径到达接收方:
- 直线路径(Line-of-Sight, LoS):最短最快
- 反射路径:经过建筑物、地面等反射,路程更长,到达更晚
发射塔 接收汽车
●──── LoS 直线路径 ──────> ●
●──→ 建筑物反射 ──────────> ● (稍晚到达)
●──→ 另一建筑反射 ─────────> ● (更晚到达)
时间轴上收到的信号:
[LoS脉冲][反射脉冲1][反射脉冲2]
←───────────────────────────────→ 时间
相干时间(Coherence Time T c T_c Tc):
发射方必须把相邻两个脉冲(符号)间隔足够大,保证第一个脉冲的所有反射都到达完毕后,第二个脉冲的 LoS 信号才到达。
符号间隔 > T c \text{符号间隔} > T_c 符号间隔>Tc
如果不满足这个条件,相邻脉冲的反射会混叠在一起,接收方无法分辨。
7.2.3 天线技术:MIMO
从单天线到 MIMO
MIMO = Multiple-Input Multiple-Output:发射端和接收端都用多根天线。
优势:N 根接收天线 → 总接收功率约为单天线的 N 倍。
MIMO 利用多径的两种方式(图7.9):
方式一:空间分集(Spatial Diversity)(图7.9a)
目标:提高可靠性,对抗多径衰落。
原理:同一份信息通过多个天线/路径发送,接收方获得多份略有不同的副本,可以合并取最优。
发射机 接收机
[x] ─────── H1,1() ──── y1 = H1,1(x)
[x] ─────── H1,2() ──── y2 = H1,2(x)
两个接收天线收到同一信号x经过不同路径的版本,
接收机选择SNR更好的那个,或者两者加权合并。
方式二:空间复用(Spatial Multiplexing)(图7.9b)
目标:提高吞吐量,同时发送多路不同数据。
原理:发射端的不同天线同时发送不同的数据流,接收端用信号处理解出各路信号。
发射机 接收机
[x1] ─── H1,1() ─────────── y1 = H1,1(x1) + H2,1(x2)
\─── H2,1() ─────────/
[x2] ─── H1,2() ─────────── y2 = H1,2(x1) + H2,2(x2)
\─── H2,2() ─────────/
接收机有两个方程两个未知数(x1, x2),可以求解。
用联立方程组理解:
y 1 = H 1 , 1 ( x 1 ) + H 2 , 1 ( x 2 ) y_1 = H_{1,1}(x_1) + H_{2,1}(x_2) y1=H1,1(x1)+H2,1(x2)
y 2 = H 1 , 2 ( x 1 ) + H 2 , 2 ( x 2 ) y_2 = H_{1,2}(x_1) + H_{2,2}(x_2) y2=H1,2(x1)+H2,2(x2)
已知 y 1 , y 2 y_1, y_2 y1,y2,估计信道响应 H H H,求 x 1 , x 2 x_1, x_2 x1,x2。
波束赋形(Beamforming,图7.10)
普通天线:向四面八方均匀发射信号(类比:点灯泡,360°发光)
波束赋形:通过调整天线阵列中各天线的相位和幅度,在特定方向形成"波束",集中能量(类比:手电筒,定向照射)
实现原理:
- 在想要增强的方向:各天线信号相长干涉(Constructive Interference)
- 在其他方向:各天线信号相消干涉(Destructive Interference)
四大优势:
- 目标方向信号强度提升 → 更高速率
- 减少对其他方向用户的干扰
- 扩大覆盖范围
- 支持更多用户同时接入
SU-MIMO vs MU-MIMO(图7.10)
| 类型 | 全称 | 说明 | 应用 |
|---|---|---|---|
| SU-MIMO | Single-User MIMO | 多天线服务一个设备,提升该设备的速率或可靠性 | WiFi(2-4根天线) |
| MU-MIMO | Multi-User MIMO | 多天线同时服务多个设备,每个方向一个波束 | 5G基站(最多64个波束单元) |
SU-MIMO(图7.10a):
基站 ──多天线──> 一个手机(多路信号全给同一个用户)
MU-MIMO(图7.10b):
基站 ──波束1──> 手机A(红色波束)
──波束2──> 手机B(蓝色波束)
──波束3──> 汽车C(绿色波束)
...(同时服务多个用户,互不干扰)
7.2.4 无线电频谱
无线电频谱 = 3 3 3 Hz 到 3 3 3 THz 的电磁频谱范围。
频谱是国家资产,由各国政府分配管理,联合国 ITU 提供协调(但无监管权)。
两类频谱使用类型:
授权频谱(Licensed Spectrum):
- 商业蜂窝运营商通过频谱拍卖获得使用权
- 美国、英国、印度的频谱拍卖金额高达数百亿美元
- 因此蜂窝服务必须收费以覆盖成本
非授权频谱(Unlicensed Spectrum): - 任何人可以买设备使用,无需申请许可证
- 必须遵守功率限制等规定
- WiFi、蓝牙、Zigbee 等都在非授权频段工作
- 缺点:多方共用,相互干扰
常用频谱总结(表7.1):
| 频段 | 频率范围 | 用途 | 授权类型 | 特点 |
|---|---|---|---|---|
| 2.4 GHz | 2.40–2.49 GHz | WiFi/蓝牙/Zigbee | 非授权 | 覆盖广,但干扰多 |
| 5 GHz | 5.17–5.83 GHz | WiFi | 非授权 | 速率更高,干扰少 |
| 6 GHz | 5.9–7.12 GHz | WiFi | 非授权 | 最新WiFi6E使用 |
| <1 GHz(低频) | 各种低频 | 蜂窝2G/3G/4G/5G | 授权 | 覆盖距离远(数十英里),速率50-250 Mbps |
| 中频段 | 1.8/3.3-3.8 GHz | 蜂窝2G/3G/4G/5G | 授权 | “黄金频段”,平衡距离(5英里)和速率(100-900 Mbps) |
| 毫米波高频 | 26/40/50/66 GHz | 5G | 授权 | 距离极短(<1英里),速率极高(>3 Gbps) |
| 915 MHz | 902-928 MHz | LoRa/IoT | 非授权 | 低功耗,远距离,低速率 |
频率与应用的直觉对应:
低频 (kHz–MHz) 高频 (GHz–THz)
←────────────────────────────────────────────────────→
| |
覆盖距离远 覆盖距离近
速率低 速率高
穿透力强 穿透力弱
(AM广播/导航) (FM广播) (WiFi/蜂窝) (毫米波5G/卫星)
核心公式汇总
波长与频率:
λ = c f , c ≈ 3 × 10 8 m/s \lambda = \frac{c}{f}, \quad c \approx 3 \times 10^8 \text{ m/s} λ=fc,c≈3×108 m/s
信噪比(dB):
SNR d B = 10 log 10 ( P signal P noise ) \text{SNR}_{dB} = 10 \log_{10}\left(\frac{P_{\text{signal}}}{P_{\text{noise}}}\right) SNRdB=10log10(PnoisePsignal)
香农信道容量:
C = B log 2 ( 1 + SNR ) (bps) C = B \log_2\left(1 + \text{SNR}\right) \quad \text{(bps)} C=Blog2(1+SNR)(bps)
自由空间路径损耗(接收/发送功率比):
P received P transmitted ∼ 1 ( f ⋅ d ) 2 \frac{P_{\text{received}}}{P_{\text{transmitted}}} \sim \frac{1}{(f \cdot d)^2} PtransmittedPreceived∼(f⋅d)21
C++ 代码演示:香农定理计算器
#include <iostream>
#include <cmath>
#include <iomanip>
#include <string>
// 将 dBm 转换为 mW(线性功率)
// dBm = 10 * log10(P_mW / 1mW)
// => P_mW = 10^(dBm/10)
double dBm_to_mW(double dBm) {
return std::pow(10.0, dBm / 10.0);
}
// 将线性功率比(如 SNR 线性值)转换为 dB
double linear_to_dB(double linear_ratio) {
return 10.0 * std::log10(linear_ratio);
}
// 将 dB 转换为线性比值
double dB_to_linear(double dB) {
return std::pow(10.0, dB / 10.0);
}
// 香农信道容量公式:C = B * log2(1 + SNR_linear)
// 参数:
// bandwidth_Hz - 信道带宽,单位 Hz
// snr_linear - 信噪比(线性值,非dB)
// 返回:最大信道容量,单位 bps
double shannon_capacity(double bandwidth_Hz, double snr_linear) {
return bandwidth_Hz * std::log2(1.0 + snr_linear);
}
// 自由空间路径损耗(Friis公式,简化版)
// 返回:接收功率 / 发射功率 的比值
// 参数:
// freq_Hz - 信号频率,单位 Hz
// dist_m - 距离,单位 m
double free_space_path_loss_ratio(double freq_Hz, double dist_m) {
// P_received / P_transmitted = (c / (4*pi*f*d))^2
const double c = 3e8; // 光速 m/s
const double pi = 3.14159265358979;
double ratio = c / (4.0 * pi * freq_Hz * dist_m);
return ratio * ratio;
}
// 打印分隔线
void print_separator() {
std::cout << std::string(50, '-') << std::endl;
}
int main() {
std::cout << std::fixed << std::setprecision(2);
// ================================================
// 演示1:香农容量定理
// 计算不同SNR和带宽下的最大信道容量
// ================================================
std::cout << "=== 香农容量定理演示 ===" << std::endl;
print_separator();
// WiFi信道6:22 MHz带宽
double wifi_bandwidth = 22e6; // 22 MHz = 22 * 10^6 Hz
// 不同SNR值对应的最大容量
double snr_dB_values[] = {10.0, 20.0, 30.0, 40.0};
std::string snr_labels[] = {"10 dB", "20 dB", "30 dB", "40 dB"};
std::cout << "WiFi信道,带宽 = 22 MHz" << std::endl;
std::cout << std::setw(10) << "SNR(dB)"
<< std::setw(15) << "SNR(线性)"
<< std::setw(20) << "最大容量(Mbps)" << std::endl;
print_separator();
for (int i = 0; i < 4; i++) {
double snr_linear = dB_to_linear(snr_dB_values[i]); // dB转线性
double capacity = shannon_capacity(wifi_bandwidth, snr_linear);
std::cout << std::setw(10) << snr_labels[i]
<< std::setw(15) << snr_linear
<< std::setw(20) << capacity / 1e6 // 转换为Mbps
<< std::endl;
}
// ================================================
// 演示2:带宽加倍对容量的影响(线性关系)
// ================================================
std::cout << std::endl;
std::cout << "=== 带宽加倍对容量的影响(SNR固定=20dB)===" << std::endl;
print_separator();
double fixed_snr_linear = dB_to_linear(20.0); // 20 dB SNR
double bandwidths[] = {20e6, 40e6, 80e6}; // 20/40/80 MHz
std::string bw_labels[] = {"20 MHz (802.11n单信道)",
"40 MHz (802.11n双信道)",
"80 MHz (802.11ac)"};
std::cout << std::setw(25) << "带宽"
<< std::setw(20) << "最大容量(Mbps)" << std::endl;
print_separator();
for (int i = 0; i < 3; i++) {
double capacity = shannon_capacity(bandwidths[i], fixed_snr_linear);
std::cout << std::setw(25) << bw_labels[i]
<< std::setw(20) << capacity / 1e6
<< std::endl;
}
// ================================================
// 演示3:自由空间路径损耗
// 同一发射功率,不同距离的接收功率
// ================================================
std::cout << std::endl;
std::cout << "=== 自由空间路径损耗演示 ===" << std::endl;
print_separator();
double freq_wifi = 2.4e9; // WiFi 2.4GHz
double tx_power_mW = 100.0; // 发射功率 100 mW
double distances[] = {1.0, 10.0, 100.0, 1000.0}; // 1m, 10m, 100m, 1km
std::string dist_labels[] = {"1 m", "10 m", "100 m", "1000 m"};
std::cout << "频率 = 2.4 GHz,发射功率 = 100 mW" << std::endl;
std::cout << std::setw(10) << "距离"
<< std::setw(20) << "接收功率(mW)"
<< std::setw(20) << "路径损耗(dB)" << std::endl;
print_separator();
for (int i = 0; i < 4; i++) {
// 计算路径损耗比
double loss_ratio = free_space_path_loss_ratio(freq_wifi, distances[i]);
double rx_power = tx_power_mW * loss_ratio; // 接收功率
double path_loss_dB = -10.0 * std::log10(loss_ratio); // 路径损耗dB(正值表示损耗)
std::cout << std::setw(10) << dist_labels[i]
<< std::setw(20) << rx_power
<< std::setw(20) << path_loss_dB
<< std::endl;
}
// ================================================
// 演示4:频率对路径损耗的影响(相同距离)
// 5G毫米波 vs 4G中频 vs WiFi 2.4G
// ================================================
std::cout << std::endl;
std::cout << "=== 频率对路径损耗的影响(距离固定=100m)===" << std::endl;
print_separator();
double fixed_dist = 100.0; // 100米
double frequencies[] = {900e6, 2.4e9, 5e9, 28e9}; // 0.9G/2.4G/5G/28G Hz
std::string freq_labels[] = {"900 MHz (4G低频)",
"2.4 GHz (WiFi/4G)",
"5 GHz (WiFi)",
"28 GHz (5G毫米波)"};
std::cout << std::setw(25) << "频率"
<< std::setw(20) << "路径损耗(dB)" << std::endl;
print_separator();
for (int i = 0; i < 4; i++) {
double loss_ratio = free_space_path_loss_ratio(frequencies[i], fixed_dist);
double path_loss_dB = -10.0 * std::log10(loss_ratio);
std::cout << std::setw(25) << freq_labels[i]
<< std::setw(20) << path_loss_dB
<< std::endl;
}
// ================================================
// 演示5:SNR计算
// ================================================
std::cout << std::endl;
std::cout << "=== SNR计算示例 ===" << std::endl;
print_separator();
// 假设接收信号功率 10 mW,噪声功率 0.01 mW
double signal_mW = 10.0;
double noise_mW = 0.01;
double snr_linear_val = signal_mW / noise_mW;
double snr_dB_val = linear_to_dB(snr_linear_val);
std::cout << "接收信号功率: " << signal_mW << " mW" << std::endl;
std::cout << "噪声功率: " << noise_mW << " mW" << std::endl;
std::cout << "SNR (线性): " << snr_linear_val << std::endl;
std::cout << "SNR (dB): " << snr_dB_val << " dB" << std::endl;
std::cout << "WiFi最低可接受SNR约20dB,当前状态: "
<< (snr_dB_val >= 20.0 ? "合格" : "不合格") << std::endl;
return 0;
}
预期输出
=== 香农容量定理演示 ===
--------------------------------------------------
WiFi信道,带宽 = 22 MHz
SNR(dB) SNR(线性) 最大容量(Mbps)
--------------------------------------------------
10 dB 10.00 73.26
20 dB 100.00 146.52
30 dB 1000.00 219.79
40 dB 10000.00 293.05
=== 带宽加倍对容量的影响(SNR固定=20dB)===
--------------------------------------------------
带宽 最大容量(Mbps)
--------------------------------------------------
20 MHz (802.11n单信道) 133.20
40 MHz (802.11n双信道) 266.40 ← 加倍!
80 MHz (802.11ac) 532.80 ← 再加倍!
...
知识点总结(Mermaid 思维导图)
各概念类比总结
| 无线网络概念 | 生活类比 |
|---|---|
| 基站 | 小区门卫/收发室,所有快递必须经过它 |
| 下行/上行链路 | 快递派送(基站→你)/ 寄快递(你→基站) |
| 切换(Handoff) | 从一个小区走到另一个小区,换了管辖区 |
| 路径损耗 | 声音传远了就变小,距离越远越衰减 |
| 隐藏终端 | 两个人隔着一堵厚墙,互相听不到,但都在对中间人说话 |
| 多径效应 | 在山谷里喊话,直接声音和多个回声先后到达 |
| 相干时间 | 两次说话之间要等回声消散再说,否则混在一起 |
| SNR | 嘈杂餐厅里说话的清晰度,信噪比越高越清楚 |
| 香农容量 | 在一定带宽和SNR下,信道理论上的最大数据传输速率 |
| 波束赋形 | 手电筒 vs 灯泡:手电筒把光集中到一个方向 |
| MU-MIMO | 一个转台同时给多个方向的人服务(不同方向各一个波束) |
| 授权频谱 | 需要买牌照才能用的频道(贵但独占,不受他人干扰) |
| 非授权频谱 | 公共频道,人人可用,但容易互相干扰(类比公共场所) |
第7章 7.2.2 编码与调制 + 7.3.1 无线信道共享 详细解析
7.2.2 编码与调制:从比特到符号到波形
整体流程概览
物理层的核心任务:把上层链路层交来的0/1比特,变成能在空气中传播的电磁波,并在接收端还原回来。
发射端(Transmitter):
链路层比特
|
v
[1. 编码 Coding] ← 加冗余、打乱顺序,抗噪声
|
v
[2. 调制 Modulation] ← 把比特/符号映射到波形(幅度/频率/相位)
|
v
电磁波 ~~~> 无线信道 ~~~>
接收端(Receiver):
~~~> 电磁波
|
v
[解调 Demodulation] ← 从波形中提取符号
|
v
[解码 Decoding] ← 去冗余,还原比特
|
v
链路层比特
还有一条反馈通道:接收端把当前信道质量(SNR/误码率)反馈给发射端,让发射端动态选择最合适的调制方式(这就是自适应调制)。
一、物理层编码(Physical-layer Coding)
为什么要编码?
无线信道有噪声,噪声会把某些比特"打坏"(1变0,0变1)。编码的目的是加保护,让接收端即使收到损坏的比特也能恢复原始数据。
注意:这里的编码和第6章讲的链路层CRC是两回事!
- 链路层CRC:用来检测帧是否出错
- 物理层编码:用来纠正比特错误(加冗余位)
- 物理层会对链路层帧(包括CRC位)一视同仁地进行保护
编码方法:冗余 + 交织
步骤1:加冗余(复制比特)
原始8个比特:
d1 d2 d3 d4 d5 d6 d7 d8
每个比特复制一份,扩展为16个比特( d i ′ d_i' di′ 表示 d i d_i di 的副本):
d1 d1' d2 d2' d3 d3' d4 d4' d5 d5' d6 d6' d7 d7' d8 d8'
步骤2:交织(打乱顺序)
将冗余位分散开来:
d1 d5 d2 d6 d3 d7 d4 d8 d5' d1' d6' d2' d7' d3' d8' d4'
为什么要交织? 防止**突发错误(Burst Error)**把一个比特的所有副本都打坏。
类比:
- 不交织:把鸡蛋都放一个篮子,篮子摔了全坏
- 交织后:鸡蛋分散放,一个篮子摔了,每个种类的鸡蛋还剩一个
步骤3:发送,假设中间3个连续比特被噪声打坏(用x表示)
发出的信号:
d1 d5 d2 d6 d3 d7 [x x x] d1' d6' d2' d7' d3' d8' d4'
↑连续3个比特损坏(突发错误)
步骤4:接收端反向解交织
接收端把顺序还原:
d1 d1' d2 d2' d3 d3' [x] d4 d5 [x] d6 d6' d7 d7' d8 [x]
虽然 d 4 , d 5 , d 8 d_4, d_5, d_8 d4,d5,d8 各自少了一个副本,但因为它们的另一个副本还在,接收端仍然能恢复全部原始比特!
交织编码的防突发错误原理(ASCII示意):
不交织:
[d1][d1'][d2][d2'][d3][d3']...
↑↑↑↑↑↑
连续噪声把d1'、d2、d2'全打坏,d2彻底丢失
交织后:
[d1][d5][d2][d6][d3][d7]...
连续噪声打坏的是d5、d2、d6,
但d2的副本d2'还完好,可以恢复!
二、调制(Modulation)
调制 = 把比特"写"进载波信号的过程。有三种基本方式,分别改变载波的幅度、频率、相位。
2.1 三种基本调制方式
幅度调制(ASK,Amplitude Shift Keying)
用信号的高低来区分0和1:
- 幅度 = 0 → 表示比特 “0”
- 幅度 = 1 → 表示比特 “1”
比特: 0 1 1 0 1
幅度:
1| ___ ___ ___
| | | | | | |
0|______| |__| |________| |___
↑"0"时幅度为0,"1"时幅度为1
频率调制(FSK,Frequency Shift Keying)
用信号的**疏密(频率高低)**来区分0和1:
- 低频(疏) → 表示比特 “0”
- 高频(密) → 表示比特 “1”
比特: 0 1 0
/\/\/\ /\/\/\/\/\ /\/\/\
↑稀疏(低频) ↑密集(高频) ↑稀疏(低频)
相位调制(PSK,Phase Shift Keying)
用信号的**起始方向(相位)**来区分0和1:
- 从零点上升开始( 0 ° 0° 0°) → 表示 “0”
- 从零点下降开始( 180 ° 180° 180°,反相) → 表示 “1”
比特 "0"(相位0°): 比特 "1"(相位180°):
/\ \/
/ \ / \
--/----\--/--- ---\----/---\
\/ \/
↑从零上升开始 ↑从零下降开始(反相)
2.2 QPSK:一次传2个比特
基本思路:为什么只用2个相位值传1个比特?用4个相位值,每次可以传2个比特!
每次把2个连续比特打包成1个符号(Symbol):
| 比特对 | 符号 | 相位 |
|---|---|---|
| 00 | “00” | 45° |
| 01 | “01” | 135° |
| 10 | “10” | 225° |
| 11 | “11” | 315° |
这就是 QPSK(Quadrature Phase Shift Keying,正交相移键控)。
优势:符号速率 = 比特速率的 1 2 \frac{1}{2} 21,每个符号有更多时间处理,信号质量更好。
星座图(Constellation Diagram):
星座图是一种直观展示调制方案的图,每个点代表一个符号:
- 点到原点的距离 = 幅度
- 点相对于正东方向的角度 = 相位
QPSK 星座图(ASCII示意):
虚轴 (Q)
|
"01" | "00"
135° • | • 45°
|
-----------+----------- 实轴 (I)
|
"10" • | • "11"
225° | 315°
|
四个点幅度相同(距原点距离相同),相位相差90°
2.3 QAM:同时改变幅度和相位
QPSK 只改变相位,QAM 同时改变相位和幅度,这样能放更多的点,每个符号携带更多比特。
每个符号携带的比特数:
每符号比特数 = log 2 ( 符号总数 ) \text{每符号比特数} = \log_2(\text{符号总数}) 每符号比特数=log2(符号总数)
| 调制方式 | 符号数 | 每符号比特数 | 应用场景 |
|---|---|---|---|
| 4-QAM(= QPSK) | 4 | log 2 4 = 2 \log_2 4 = 2 log24=2 位 | 信道差时使用 |
| 16-QAM | 16 | log 2 16 = 4 \log_2 16 = 4 log216=4 位 | 中等信道质量 |
| 64-QAM | 64 | log 2 64 = 6 \log_2 64 = 6 log264=6 位 | 信道好时使用 |
| 256-QAM | 256 | log 2 256 = 8 \log_2 256 = 8 log2256=8 位 | 信道很好 |
| 1024-QAM | 1024 | log 2 1024 = 10 \log_2 1024 = 10 log21024=10 位 | WiFi-6 |
| 4096-QAM | 4096 | log 2 4096 = 12 \log_2 4096 = 12 log24096=12 位 | WiFi-7 |
16-QAM 星座图(ASCII示意):
Q轴
|
| • • • • ← 每行4个点(4种幅度/相位组合)
| • • • •
-+----------- I轴
| • • • •
| • • • •
共16个点,每个点代表4个比特("0000"~"1111")
点越密集,相邻点越近,噪声更容易导致判断错误
噪声如何导致错误(以16-QAM为例):
发射"1111": 接收端测量到的实际位置(噪声影响):
·← 实际发射点 · 噪声把点往左偏了
(理想位置) · · 大多数测量点仍在"1111"附近
· 但有一个点偏进了"1011"的范围!
→ 误判为"1011",产生误码
2.4 自适应调制(Adaptive Modulation)
核心问题:阶数越高的QAM,速率越高,但抗噪声能力越差。如何在速率和可靠性之间取得最佳平衡?
答案:根据当前信道的SNR,动态切换调制方式!
以误码率(BER)目标 10 − 4 10^{-4} 10−4 为例:
| SNR 范围 | 使用调制方式 | 每符号比特数 | 速率 |
|---|---|---|---|
| SNR < 13 dB | 4-QAM | 2 | 低 |
| 13 ≤ SNR < 17 dB | 16-QAM | 4 | 中 |
| SNR ≥ 17 dB | 64-QAM | 6 | 高 |
自适应调制工作流程(Mermaid):
类比:就像开车时自动变速箱会根据路况自动换挡——上坡(信道差)换低挡保可靠,平路(信道好)换高挡提速度。
三、7.3.1 无线信道共享
多个设备需要共享同一个无线信道,如何防止"打架"?本节介绍两种核心技术:OFDMA 和 CSMA/CA。
3.1 FDM → OFDM → OFDMA 的演进
FDM(频分复用):把整个频带切成若干子信道,不同用户用不同子信道,子信道之间留**保护带(Guard Band)**以防干扰。
FDM(有保护带):
频率
| [子信道1] [保护][子信道2] [保护][子信道3]
| | | | | | | | | | |
+--+--------+-+---+-+--------+-+---+-+--------+-> 频率
↑保护带(浪费频谱)
OFDM(正交频分复用):子载波之间数学正交,允许频谱重叠但不互相干扰,省去保护带,频谱利用率更高。
OFDM(子载波正交,可重叠):
功率
| /\ /\ /\ /\
| / \ / \ / \ / \
| / /\ \/ /\ \/ /\ \/ /\ \
| / / \/ / \/ / \/ \ \
|/ / \ / \ / \ \\
+--+----+--+----+--+----+----> 频率
每个子载波在其他子载波的峰值处为零(正交性)
子载波可以重叠,不需要保护带
OFDMA(正交频分多址)= OFDM + 时分:
把频率维度(子信道)和时间维度(时隙)组合成一个二维资源网格,灵活分配给不同用户。
OFDMA 资源网格(ASCII):
时间 →
t1 t2 t3 t4 t5
┌──────┬──────┬──────┬──────┬──────┐ ← 子信道12
│用户A │用户A │用户B │用户B │ │
├──────┼──────┼──────┼──────┼──────┤ ← 子信道11
│用户A │用户A │用户B │ │用户C │
├──────┼──────┼──────┼──────┼──────┤ ← 子信道10
│ │用户A │ │用户B │用户C │
频 ├──────┼──────┼──────┼──────┼──────┤ ← 子信道9
率 │ │ │用户C │用户C │ │
↑ └──────┴──────┴──────┴──────┴──────┘
每个格子 = 1个资源单元(RE)= 最小调度单位
用户A获得多个RE,用户B、C也各获得若干RE
资源单元(RE)的大小:
| 网络类型 | 子信道带宽 | 时隙时长 |
|---|---|---|
| 4G/5G | 15 kHz | 66.6 μ s 66.6\ \mu s 66.6 μs |
| WiFi (OFDMA) | 78 kHz | 12.8 μ s 12.8\ \mu s 12.8 μs |
资源块(RB / RU):多个相邻RE组合在一起作为一个调度单位:
- 4G网络中,一个 RB = 12个子信道 × 7个时隙 = 84个符号
- WiFi OFDMA 中叫 RU(Resource Unit)
4G 资源块(RB)结构:
子信道
12 [·][·][·][·][·][·][·]
11 [·][·][·][·][·][·][·]
10 [·][·][·][·][·][·][·]
9 [·][·][·][·][·][·][·]
8 [·][·][·][·][·][·][·]
7 [·][·][·][·][·][·][·]
6 [·][·][·][·][·][·][·]
5 [·][·][·][·][·][·][·]
4 [·][·][·][·][·][·][·]
3 [·][·][·][·][·][·][·]
2 [·][·][·][·][·][·][·]
1 [·][·][·][·][·][·][·]
t1 t2 t3 t4 t5 t6 t7 →时间
[·] = 1个RE = 1个符号
共12×7=84个RE,构成1个RB
3.2 CSMA/CA:WiFi的信道接入协议
为什么不能用 CSMA/CD?
有线以太网用 CSMA/CD(冲突检测):一边发送,一边监听,发现碰撞立刻停止。
但无线网络有两个致命问题:
问题1:无法检测碰撞
无线发射信号比接收到的信号强几千倍,发射端自己的信号会"淹没"收到的微弱碰撞信号,根本听不到碰撞。
类比:你在麦克风前大喊,根本听不清旁边人的低语。
问题2:隐藏终端
A 和 C 互相听不到,但都在向 B 发送,在 B 处发生碰撞,而 A 和 C 各自都认为信道空闲。
CSMA/CA 的设计思路:碰撞避免(Collision Avoidance)
既然无法检测碰撞,就尽量提前避免碰撞发生。同时增加链路层 ACK 确认机制。
CSMA/CA 完整协议流程
时间线示意(ASCII):
信道状态: [忙忙忙忙忙忙忙忙忙][DIFS][空][空][空][空][空][空][帧帧帧帧帧帧][SIFS][ACK]
↑ ↑
等DIFS后 发送完整帧
开始倒计退避 等待ACK
DIFS = Distributed Inter-Frame Space(分布式帧间间隔,发送前的等待时间)
SIFS = Short Inter-Frame Space(短帧间间隔,接收方回复ACK前的等待时间,比DIFS短)
SIFS < DIFS 保证ACK优先于新的数据帧
退避机制(Binary Exponential Backoff,二进制指数退避):
第 n n n 次碰撞后,从 [ 0 , 2 n − 1 ] [0, 2^n - 1] [0,2n−1] 中随机选一个整数 K K K 作为退避时隙数:
退避时间 = K × 时隙长度 , K ∈ [ 0 , 2 n − 1 ] \text{退避时间} = K \times \text{时隙长度}, \quad K \in [0,\ 2^n - 1] 退避时间=K×时隙长度,K∈[0, 2n−1]
| 碰撞次数 | 退避范围 |
|---|---|
| 第1次 | [ 0 , 1 ] [0, 1] [0,1] |
| 第2次 | [ 0 , 3 ] [0, 3] [0,3] |
| 第3次 | [ 0 , 7 ] [0, 7] [0,7] |
| 第n次 | [ 0 , 2 n − 1 ] [0, 2^n-1] [0,2n−1] |
CSMA/CA vs CSMA/CD 核心对比
CSMA/CD(以太网): CSMA/CA(WiFi):
发前监听 发前监听
发现忙就等 发现忙就退避(随机等)
空了就立刻发 空了也要先退避再发
发的同时检测碰撞 无法检测碰撞,发就整帧发完
发现碰撞立刻停止 靠ACK判断是否成功
碰撞处理代价小 碰撞代价大(整帧白发)
→ "先动再看" → "先想再动"
为什么 CSMA/CA 空闲时也要先退避?
假设A和B都在等第三个人C发完,C一停:
- CSMA/CD:A和B同时发→碰撞→停止→代价小
- CSMA/CA:A和B如果同时发→碰撞→整帧白发→代价大!
所以WiFi让A和B在C发完后都先随机退避,选了不同退避值的那个先发,另一个听到后冻结计数器,等待,这样大概率避免碰撞。
C发完后的场景(ASCII时间线):
C发完
|
v
A:[DIFS][退避=3][3][2][1][0]──发──────────帧──────────[等ACK]
B:[DIFS][退避=7][7][6][6][6][6][冻结,等A发完][5][4][3]...
↑↑
A先开始发,B听到A在发,冻结计数器
等A发完、收到ACK后,B才继续倒计
C++ 代码演示
1. QAM 调制阶数与比特数计算
#include <iostream>
#include <vector>
#include <utility>
#include <cmath>
#include <string>
#include <iomanip>
// 计算 QAM 每个符号携带的比特数
// QAM阶数 M → 每符号比特数 = log2(M)
int bits_per_symbol(int qam_order) {
// log2(M) = ln(M) / ln(2)
return static_cast<int>(std::log2(qam_order));
}
// 根据SNR(dB)推荐调制方式
// 目标:BER < 1e-4
// SNR < 13dB → 4-QAM
// 13 <= SNR < 17dB → 16-QAM
// SNR >= 17dB → 64-QAM
std::string recommend_modulation(double snr_dB) {
if (snr_dB < 13.0) {
return "4-QAM (QPSK)";
} else if (snr_dB < 17.0) {
return "16-QAM";
} else {
return "64-QAM";
}
}
// 计算理论最大吞吐量
// 吞吐量 = 符号速率 × 每符号比特数
// 这里用带宽近似符号速率(奈奎斯特定理:符号速率 ≤ 2B)
double max_throughput_bps(double bandwidth_Hz, int qam_order) {
int bps = bits_per_symbol(qam_order);
// 假设符号速率 = 带宽(简化)
return bandwidth_Hz * bps;
}
int main() {
std::cout << std::fixed << std::setprecision(1);
// ================================================
// 演示1:各QAM阶数的比特携带量
// ================================================
std::cout << "=== QAM 各阶数的比特携带量 ===" << std::endl;
std::cout << std::setw(12) << "QAM阶数"
<< std::setw(16) << "每符号比特数"
<< std::setw(20) << "符号数" << std::endl;
std::cout << std::string(48, '-') << std::endl;
// 常见QAM阶数列表
std::vector qam_orders = {4, 16, 64, 256, 1024, 4096};
for (int M : qam_orders) {
int bps = bits_per_symbol(M);
std::cout << std::setw(12) << (std::to_string(M) + "-QAM")
<< std::setw(16) << bps
<< std::setw(20) << M << std::endl;
}
// ================================================
// 演示2:自适应调制——根据SNR动态选择调制方式
// ================================================
std::cout << std::endl;
std::cout << "=== 自适应调制:根据SNR选择调制方式 ===" << std::endl;
std::cout << std::setw(12) << "SNR(dB)"
<< std::setw(18) << "推荐调制方式"
<< std::setw(16) << "每符号比特数" << std::endl;
std::cout << std::string(46, '-') << std::endl;
// 模拟SNR从差到好的变化
std::vector snr_values = {5.0, 10.0, 12.9, 13.0, 15.0, 17.0, 20.0, 30.0};
for (double snr : snr_values) {
std::string mod = recommend_modulation(snr);
// 根据调制方式获取阶数
int order = (snr < 13.0) ? 4 : (snr < 17.0) ? 16 : 64;
int bps = bits_per_symbol(order);
std::cout << std::setw(12) << snr
<< std::setw(18) << mod
<< std::setw(16) << bps << std::endl;
}
// ================================================
// 演示3:OFDMA 资源块计算
// ================================================
std::cout << std::endl;
std::cout << "=== 4G OFDMA 资源块(RB)参数 ===" << std::endl;
// 4G RB 参数
const int subcarriers_per_rb = 12; // 每RB的子载波数
const int timeslots_per_rb = 7; // 每RB的时隙数
const double subcarrier_bw_kHz = 15.0; // 子载波带宽 15 kHz
const double timeslot_us = 66.6; // 时隙时长 66.6 微秒
int symbols_per_rb = subcarriers_per_rb * timeslots_per_rb;
double rb_bandwidth_kHz = subcarriers_per_rb * subcarrier_bw_kHz;
double rb_duration_ms = timeslots_per_rb * timeslot_us / 1000.0;
std::cout << "每RB子载波数: " << subcarriers_per_rb << " 个" << std::endl;
std::cout << "每RB时隙数: " << timeslots_per_rb << " 个" << std::endl;
std::cout << "每RB符号总数: " << symbols_per_rb << " 个" << std::endl;
std::cout << "RB占用带宽: " << rb_bandwidth_kHz << " kHz" << std::endl;
std::cout << "RB持续时间: " << rb_duration_ms << " ms" << std::endl;
// 计算不同QAM下的RB数据量
std::cout << std::endl;
std::cout << "=== 不同调制下单个RB的承载比特数 ===" << std::endl;
std::cout << std::setw(12) << "调制方式"
<< std::setw(16) << "每符号比特"
<< std::setw(20) << "每RB总比特" << std::endl;
std::cout << std::string(48, '-') << std::endl;
std::vector<std::pair<std::string, int>> mods = {
{"4-QAM", 4},
{"16-QAM", 16},
{"64-QAM", 64},
{"256-QAM",256}
};
for (auto& [name, order] : mods) {
int bps = bits_per_symbol(order);
int total_bits = symbols_per_rb * bps;
std::cout << std::setw(12) << name
<< std::setw(16) << bps
<< std::setw(20) << total_bits << std::endl;
}
// ================================================
// 演示4:CSMA/CA 退避时间模拟
// ================================================
std::cout << std::endl;
std::cout << "=== CSMA/CA 二进制指数退避模拟 ===" << std::endl;
std::cout << "碰撞次数 | 退避范围 | 示例退避时隙数" << std::endl;
std::cout << std::string(45, '-') << std::endl;
// 模拟退避窗口增长
// 第n次碰撞后退避范围:[0, 2^n - 1]
for (int collision = 1; collision <= 6; collision++) {
// 退避窗口大小(CW = Contention Window)
int cw_max = static_cast<int>(std::pow(2, collision)) - 1;
// 示例:取中间值作为演示
int example_k = cw_max / 2;
// 假设每个时隙 9 微秒(802.11 标准)
double slot_us = 9.0;
double backoff_us = example_k * slot_us;
std::cout << std::setw(8) << collision
<< " | [0, " << std::setw(3) << cw_max << "]"
<< " | K=" << std::setw(3) << example_k
<< " → 退避 " << std::setw(6) << backoff_us << " us"
<< std::endl;
}
return 0;
}
预期输出
=== QAM 各阶数的比特携带量 ===
QAM阶数 每符号比特数 符号数
------------------------------------------------
4-QAM 2 4
16-QAM 4 16
64-QAM 6 64
256-QAM 8 256
1024-QAM 10 1024
4096-QAM 12 4096
=== 自适应调制:根据SNR选择调制方式 ===
SNR(dB) 推荐调制方式 每符号比特数
----------------------------------------------
5.0 4-QAM (QPSK) 2
10.0 4-QAM (QPSK) 2
12.9 4-QAM (QPSK) 2
13.0 16-QAM 4
15.0 16-QAM 4
17.0 64-QAM 6
20.0 64-QAM 6
30.0 64-QAM 6
=== 4G OFDMA 资源块(RB)参数 ===
每RB子载波数: 12 个
每RB时隙数: 7 个
每RB符号总数: 84 个
RB占用带宽: 180.0 kHz
RB持续时间: 0.5 ms
=== 不同调制下单个RB的承载比特数 ===
调制方式 每符号比特 每RB总比特
------------------------------------------------
4-QAM 2 168
16-QAM 4 336
64-QAM 6 504
256-QAM 8 672
=== CSMA/CA 二进制指数退避模拟 ===
碰撞次数 | 退避范围 | 示例退避时隙数
---------------------------------------------
1 | [0, 1] | K= 0 → 退避 0.0 us
2 | [0, 3] | K= 1 → 退避 9.0 us
3 | [0, 7] | K= 3 → 退避 27.0 us
4 | [0, 15] | K= 7 → 退避 63.0 us
5 | [0, 31] | K= 15 → 退避 135.0 us
6 | [0, 63] | K= 31 → 退避 279.0 us
核心概念总结
各概念快速记忆类比
| 概念 | 生活类比 |
|---|---|
| 物理层编码+交织 | 把重要文件存多份,分散放不同地方,一处着火不会全丢 |
| ASK(幅度调制) | 声音大小表示不同内容(大声=1,小声=0) |
| FSK(频率调制) | 声调高低表示不同内容(高音=1,低音=0) |
| PSK(相位调制) | 顺时针开始=0,逆时针开始=1 |
| QPSK | 用4个方向(北/西/南/东)各表示一种符号,一次说2个比特 |
| 16-QAM | 用16种不同的"大小+方向"组合,一次传4个比特 |
| 自适应调制 | 信号好时(高速公路)用高挡,信号差时(山路)用低挡 |
| OFDM | 多人同时在不同频率说话,数学保证互不干扰,不需要"静音间隔" |
| OFDMA资源块 | 把时间和频率做成座位表,基站给不同用户分配不同座位 |
| CSMA/CA | 礼貌地等别人说完才说,但还是可能同时开口,靠随机等待减少碰撞 |
| ACK确认 | 说完话等对方说"我听到了",没回应就重说 |
| DIFS | 轮到你说话前,先清嗓子等一小会(给高优先级帧让路) |
| SIFS | 你说完,对方回复前的极短停顿(比DIFS短,保证ACK优先) |
5G RAN:无线链路层 详细解析
本文对应教材第7章相关内容,结合图7.31~7.39,用通俗语言解释5G无线接入网链路层的核心知识点。
目录
1. 5G RAN 协议栈总览
1.1 什么是 RAN?
RAN(Radio Access Network,无线接入网)是用户设备(手机、平板等)与核心网之间的"桥梁",负责通过无线电波传递数据。
1.2 用户平面 vs 控制平面
和有线网络一样,5G RAN 的链路层也分两个平面:
| 平面 | 英文 | 职责 | 比喻 |
|---|---|---|---|
| 用户平面 | User Plane | 传输实际数据(视频、网页等) | 高速公路上跑的车 |
| 控制平面 | Control Plane | 管理无线资源、连接状态、移动性 | 交警和路标系统 |
1.3 图7.31 协议栈结构(ASCII 示意)
设备端 (Device) 基站端 (Base Station)
+---------------------------+ +---------------------------+
| 用户平面 | 控制平面 | | 控制平面 | 用户平面 |
| Network | | | | Network |
+------------+-------------+ +------------+------------+
| SDAP | RRC |<---->| RRC | SDAP |
+------------+-------------+ +------------+------------+
| PDCP |<---->| PDCP |
+--------------------------+ +--------------------------+
| RLC |<---->| RLC |
+--------------------------+ +--------------------------+
| MAC |<---->| MAC |
+--------------------------+ +--------------------------+
| Physical |<---->| Physical |
+--------------------------+ +--------------------------+
| |
无线电波 <================================> 无线电波
- 蓝色(控制平面):RRC 负责控制逻辑
- 绿色(用户平面):SDAP -> PDCP -> RLC -> MAC -> PHY 逐层处理数据
- 虚线双向箭头:表示两端相同子层之间存在"逻辑连接",实际消息通过物理信道传输
2. 链路层各子层详解
5G RAN 链路层从上到下分为5个子层,数据包就像一封信,每过一层就被套上一个新信封(加头部)。
2.1 层次结构全貌
2.2 RRC:无线资源控制(控制平面核心)
职责(可类比为"网络管家"):
- 建立、维护、释放链路层逻辑信道(相当于"开通/关闭通道")
- 管理每个设备的连接状态(活跃、休眠、空闲)
- 管理设备移动性(切换基站,即"漫游")
- 测量并上报无线信道质量
RRC 通过在基站和用户设备之间发送RRC 协议消息来完成工作,这些消息承载在物理控制信道上传输。
2.3 SDAP:服务数据适配协议(用户平面最顶层)
职责:QoS(服务质量)流管理
- 为不同的数据流(如视频通话 vs 普通网页)分配 QoS Flow ID
- 将数据流映射到对应的无线资源上
- 打个比方:就像邮局按包裹的优先级分类(加急件走快递,普通件走平邮)
2.4 PDCP:包数据汇聚协议
职责:
- IP 头部压缩:把冗长的 IP 头部压缩,节省无线信道带宽
- 加密(可选):保护数据安全,防止被窃听
- 完整性校验(可选):确保数据在传输中未被篡改
比喻:PDCP 就像快递公司的打包+贴防伪标签环节。
2.5 RLC:无线链路控制
职责:
- 分段与重组:把大数据包切成小块发送,接收端再拼回来
- 可靠传输:使用 ARQ(自动重传请求)协议,通过序列号、循环冗余校验(CRC)、ACK/NACK 消息保证数据正确到达
ARQ 简单流程:
发送端 接收端
| --- 数据帧(seq=1) --> |
| <-- ACK(seq=1) ---- | (收到了,没问题)
| --- 数据帧(seq=2) --> |
| <-- NACK(seq=2) ---- | (没收到或出错,请重发)
| --- 数据帧(seq=2) --> | (重传)
| <-- ACK(seq=2) ---- |
2.6 MAC:媒体访问控制
职责:调度(Scheduling)——决定"谁在什么时候用哪段频谱发数据"
- 将链路层帧分割成小块,映射到 OFDMA 资源块(Resource Block,RB) 上
- 负责下行(基站→设备)和上行(设备→基站)的传输调度
- 详细调度算法见第6节
2.7 数据包在各子层的封装过程
原始 IP 数据报
+---------------------------+
| IP 数据报 |
+---------------------------+
经过 SDAP 加头
+------+--------------------+
|SDAP头| IP 数据报 |
+------+--------------------+
经过 PDCP 加头
+-----+------+--------------+
|PDCP头|SDAP头| IP 数据报 |
+-----+------+--------------+
经过 RLC 分段加头
+----+-----+------+---------+
|RLC头|PDCP头|SDAP头| IP片段 |
+----+-----+------+---------+
经过 MAC 加头
+---+----+-----+------+------+
|MAC头|RLC头|PDCP头|SDAP头|数据|
+---+----+-----+------+------+
由 PHY 层调制发送
3. 基站功能拆分:解聚合架构
3.1 为什么要"拆分"基站?
早期 2G/3G/4G 的基站是一个整体"黑盒子",所有功能由单一厂商实现,造成:
- 厂商垄断,成本高
- 创新困难,无法灵活升级
5G 开始将基站"拆分"(Disaggregation)成多个功能单元,不同厂商可以提供不同单元的实现,相互竞争,降低成本,促进创新——这和 SDN 把控制平面从路由器中独立出来的思路完全一致。
3.2 三个功能单元(图7.33)
| 单元 | 英文全称 | 包含功能 | 实时性要求 | 通常部署位置 |
|---|---|---|---|---|
| CU | Central Unit | RRC + SDAP + PDCP | 近实时 | 云端或边缘云 |
| DU | Distributed Unit | RLC + MAC + 部分PHY | 实时 | 靠近基站 |
| RU | Radio Unit | D/A转换 + 射频前端 | 严格实时 | 基站天线处 |
关键理解:越靠近天线(RU),对实时性要求越高;越靠近核心网(CU),可以放到云端处理。
4. SD-RAN:软件定义无线接入网
4.1 类比 SDN
还记得第5章的 SDN(软件定义网络)吗?它把路由器的控制平面抽离出来,放到集中的控制器上。SD-RAN 对 RAN 做了同样的事情:
传统 RAN SD-RAN
+---------+ +-----------+
| RRC | | SD-RAN |
| (嵌入 | vs | Controller|
| 基站) | +-----------+
+---------+ |
+---------+
| 数据平面|
| (基站) |
+---------+
4.2 SD-RAN 控制器的三大组件(图7.34)
三大组件详解:
① 控制平面代理(Control Plane Proxy)
- 对外:实现与5G核心网的标准接口(让核心网"看不出"内部是SDN还是传统实现)
- 对内:转发控制命令给 RIC
② 实时智能控制器(RIC, Real-Time Intelligent Controller) - 相当于 SDN 里的"控制器大脑"
- 内含通信层(下发命令给数据平面)
- 内含状态管理层(存储全网信道状态、连接状态等信息到 R-NIB)
- 内含与 xApp 的接口
③ xApps(控制应用程序) - 运行在 RIC 之外的独立软件进程
- 功能举例:负载均衡、设备切换(Handover)、QoS 保障等
- 可以由不同厂商开发,只要遵循标准接口(OpenRAN 理念)
5. 网络发现与附着
5.1 什么是"附着"?
设备(手机)开机或进入新区域后,需要找到附近的网络并"注册"进去,这个过程叫网络关联(Network Association)。
基站会定期广播信标消息(Beacon),告诉周围设备:“我在这里,来连我吧!”
5.2 WiFi 附着(图7.35)——3步简单握手
AP1 广播信标 (Beacon) AP2 广播信标 (Beacon)
\ /
\ 步骤1 /
v v
设备 H1 扫描信道
选择信号最强的 AP2
|
步骤2 v
H1 -----[关联请求 Association Request]-----> AP2
|
步骤3 v
H1 <----[关联响应 Association Response]----- AP2
|
完成关联,获取 DHCP IP 地址
关联成功后,设备会通过 DHCP 获得 IP 地址,就像一台普通的有线电脑一样加入网络子网。
5.3 5G 附着(图7.36)——多步骤复杂过程
5G 的附着比 WiFi 复杂得多,分为以下阶段:
阶段一:读取基站广播信息
基站广播内容(按顺序):
1. PSS (主同步信号) -> 设备用来同步时钟
2. SSS (辅同步信号) -> 提供网络初步标识符
3. MIB (主信息块) -> 子载波间隔、小区是否开放
PSS + SSS + MIB = SSB (系统信号块)
4. SIBs (系统信息块) -> 详细网络参数,最多20个
最重要的 SIB1 (每80ms广播):
- MCC (移动国家码)
- MNC (移动网络码)
- 基站标识符
- 最低接收信号质量要求
阶段二:设备发起连接请求
设备决定要加入此网络,但基站还不知道设备存在,因此设备使用随机接入信道发送:
设备 H1 ----[RRC 连接建立请求]----> 基站2
阶段三:基站响应
设备 H1 <---[RRC 连接建立响应]----- 基站2
此时设备和基站可以交换控制消息,但设备还未完成完整的网络接入(还需要身份认证和获取IP地址,在核心网部分完成)。
WiFi vs 5G 附着对比
| 对比项 | WiFi | 5G |
|---|---|---|
| 信标类型 | 单一 Beacon 帧 | SSB + 多个 SIB |
| 时钟同步 | 不需要 | 需要(PSS) |
| 连接请求 | 802.11 关联请求帧 | RRC 连接建立请求 |
| 复杂度 | 简单(3步) | 复杂(多阶段) |
| 完整入网 | 关联后即完成 | 还需核心网认证 |
6. MAC 调度算法
6.1 为什么无线调度很重要?
在有线网络中,所有设备的链路速率基本固定(如1Gbps以太网),调度顺序对总吞吐量影响不大。
但在无线网络中,不同设备的信道质量差异巨大:
- 靠近基站、视距良好的设备:信道质量好,可以用高阶调制,速率高
- 远离基站、有遮挡的设备:信道质量差,速率低
因此,选择给哪个设备分配资源块(RB),直接影响整体吞吐量和用户体验。
6.2 调度的四个核心考量
| 考量维度 | 问题 | 影响 |
|---|---|---|
| 信道质量感知 | 是否考虑每个设备的信道质量? | 高质量设备速率更高 |
| 公平性 | 是否保证每个设备获得公平的吞吐量? | 差信道设备可能被"饿死" |
| 流量优先级 | 控制平面 vs 用户平面?实时流量 vs 非实时? | 语音/视频需低延迟 |
| QoS 保障 | 是否提供性能保证? | 视频会议不能卡顿 |
6.3 四种调度算法详解
以下用6个用户设备(UE1~UE6)举例说明(对应图7.37):
6个用户的待发送数据队列:
UE1: ████
UE2: ██
UE3: █
UE4: ████████ (数据最多)
UE5: ███
UE6: █████
算法一:轮询调度(Round Robin, RR)
原则:每个设备轮流获得相同数量的 RB,不管信道质量好坏。
时间槽 1:UE1 获得 RB1~RB2
时间槽 2:UE2 获得 RB1~RB2
时间槽 3:UE3 获得 RB1~RB2
...(循环)
- 信道感知:否
- 公平性:轮次公平(但吞吐量不公平,信道差的设备实际传输少)
- 适合场景:对公平性要求高但不关心效率的简单场景
算法二:最大吞吐量调度(Maximum Throughput, MT)
原则:每次把 RB 分给信道质量最好的设备。
5G 中,设备通过发送 CQI(信道质量指示,4位) 告诉基站自己的信道质量。
调度决策:
max i , k { d k i ( t ) } \max_{i,k} \{ d_k^i(t) \} i,kmax{dki(t)}
其中 d k i ( t ) d_k^i(t) dki(t) 是设备 i i i 在时刻 t t t 使用第 k k k 个 RB 的预期吞吐量。
示例:信道质量 UE4 > UE6 > UE1 > UE2 > UE3 > UE5
MT 调度 -> 所有 RB 都给 UE4 (如果它有足够数据)
- 信道感知:是
- 公平性:极不公平(信道差的设备可能永远得不到资源)
- 适合场景:只追求系统吞吐量最大化
算法三:盲均等吞吐量调度(Blind Equal Throughput, BET)
原则:保证所有设备的平均吞吐量相等。
使用指数加权移动平均(EWMA) 估计每个设备的历史平均吞吐量:
R i ( t ) = ( 1 − β ) ⋅ r i ( t ) + β ⋅ R i ( t − 1 ) R^i(t) = (1-\beta) \cdot r^i(t) + \beta \cdot R^i(t-1) Ri(t)=(1−β)⋅ri(t)+β⋅Ri(t−1)
其中:
- r i ( t ) r^i(t) ri(t):设备 i i i 在时间段 t t t 实际测量的吞吐量
- R i ( t ) R^i(t) Ri(t):设备 i i i 的历史平均吞吐量估计值
- β \beta β( 0 < β < 1 0 < \beta < 1 0<β<1):平滑参数, β \beta β 越大,历史值影响越大; β \beta β 越小,近期值影响越大
决策:每次把 RB 分给历史平均吞吐量最低的设备(有数据待发的前提下)。
若 UE3 历史吞吐量最低 -> 优先给 UE3 分配 RB
- 信道感知:间接感知(通过历史吞吐量体现)
- 公平性:吞吐量公平
- 适合场景:需要保证公平的普通用户服务
算法四:比例公平调度(Proportional Fairness, PF)
原则:在吞吐量最大化和公平性之间取得平衡。
调度决策:
max i , k { d k i ( t ) R i ( t − 1 ) } \max_{i,k} \left\{ \frac{d_k^i(t)}{R^i(t-1)} \right\} i,kmax{Ri(t−1)dki(t)}
直觉理解:
- 分子 d k i ( t ) d_k^i(t) dki(t) 大(当前信道质量好)→ 值大,优先调度
- 分母 R i ( t − 1 ) R^i(t-1) Ri(t−1) 小(历史平均吞吐量低)→ 值大,优先调度
这样既照顾了信道好的设备(提高效率),也照顾了历史吞吐量低的设备(保证公平)。 - 信道感知:是
- 公平性:比例公平(最常用的均衡方案)
- 适合场景:现实5G网络中广泛采用
6.4 四种算法对比总结
| 算法 | 信道感知 | 公平性 | 吞吐量 | 适用场景 |
|---|---|---|---|---|
| RR(轮询) | 否 | 轮次公平 | 低 | 简单场景 |
| MT(最大吞吐量) | 是 | 极不公平 | 最高 | 仅关注效率 |
| BET(盲均等吞吐量) | 间接 | 吞吐量公平 | 中等 | 需要公平性 |
| PF(比例公平) | 是 | 比例公平 | 较高 | 现实网络(最常用) |
6.5 C++ 完整实现(四种调度算法模拟)
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <iomanip>
#include <cmath>
#include <string>
// 设备数量
const int NUM_UE = 6;
// 资源块数量
const int NUM_RB = 4;
// 调度轮次
const int ROUNDS = 5;
// 模拟每个设备在每个RB上的信道质量(预期吞吐量,Mbps)
// channel[ue][rb]
double channel[NUM_UE][NUM_RB] = {
{3.0, 2.5, 2.0, 1.5}, // UE0:信道质量一般
{1.0, 1.2, 0.8, 1.1}, // UE1:信道质量较差
{0.5, 0.6, 0.7, 0.5}, // UE2:信道质量很差
{5.0, 4.8, 4.5, 4.0}, // UE3:信道质量很好
{2.0, 2.2, 1.8, 2.1}, // UE4:信道质量中等
{3.5, 3.0, 2.8, 3.2}, // UE5:信道质量较好
};
// 各设备是否有数据待发(全部有数据)
bool hasData[NUM_UE] = {true, true, true, true, true, true};
// ===========================
// 算法一:轮询调度 (Round Robin)
// ===========================
void roundRobin() {
std::cout << "\n=== 轮询调度 (Round Robin) ===\n";
int nextUE = 0; // 下一个轮到的设备
for (int round = 0; round < ROUNDS; round++) {
std::cout << "第" << round + 1 << "轮: ";
for (int rb = 0; rb < NUM_RB; rb++) {
// 找到下一个有数据的设备
int assigned = nextUE % NUM_UE;
std::cout << "RB" << rb << "->UE" << assigned
<< "(" << channel[assigned][rb] << "Mbps) ";
nextUE = (nextUE + 1) % NUM_UE;
}
std::cout << "\n";
}
}
// ===========================
// 算法二:最大吞吐量调度 (Maximum Throughput)
// ===========================
void maxThroughput() {
std::cout << "\n=== 最大吞吐量调度 (Maximum Throughput) ===\n";
for (int round = 0; round < ROUNDS; round++) {
std::cout << "第" << round + 1 << "轮: ";
// 标记每个RB是否已分配
for (int rb = 0; rb < NUM_RB; rb++) {
// 找到信道质量最好的设备
int bestUE = 0;
double bestQuality = -1.0;
for (int ue = 0; ue < NUM_UE; ue++) {
if (hasData[ue] && channel[ue][rb] > bestQuality) {
bestQuality = channel[ue][rb];
bestUE = ue;
}
}
std::cout << "RB" << rb << "->UE" << bestUE
<< "(" << bestQuality << "Mbps) ";
}
std::cout << "\n";
}
}
// ===========================
// 算法三:盲均等吞吐量调度 (BET)
// EWMA 公式:R(t) = (1-beta)*r(t) + beta*R(t-1)
// ===========================
void blindEqualThroughput() {
std::cout << "\n=== 盲均等吞吐量调度 (BET) ===\n";
const double beta = 0.8; // EWMA 平滑参数
// 初始化每个设备的平均吞吐量估计值
double avgThroughput[NUM_UE];
for (int ue = 0; ue < NUM_UE; ue++) {
// 初始估计:取该设备所有RB的平均信道质量
double sum = 0;
for (int rb = 0; rb < NUM_RB; rb++) sum += channel[ue][rb];
avgThroughput[ue] = sum / NUM_RB;
}
for (int round = 0; round < ROUNDS; round++) {
std::cout << "第" << round + 1 << "轮: ";
// 已分配的RB记录
bool rbAssigned[NUM_RB] = {false};
for (int rb = 0; rb < NUM_RB; rb++) {
// 找到平均吞吐量最低的设备(有数据且RB未被占用)
int lowestUE = -1;
double lowestAvg = 1e18;
for (int ue = 0; ue < NUM_UE; ue++) {
if (hasData[ue] && avgThroughput[ue] < lowestAvg) {
lowestAvg = avgThroughput[ue];
lowestUE = ue;
}
}
if (lowestUE == -1) break;
std::cout << "RB" << rb << "->UE" << lowestUE
<< "(" << std::fixed << std::setprecision(2)
<< channel[lowestUE][rb] << "Mbps) ";
// 用实际吞吐量更新 EWMA:R(t) = (1-beta)*r(t) + beta*R(t-1)
double r = channel[lowestUE][rb]; // 本次实际吞吐量
avgThroughput[lowestUE] = (1 - beta) * r + beta * avgThroughput[lowestUE];
}
std::cout << "\n";
// 打印各设备当前平均吞吐量
std::cout << " 当前平均吞吐量估计: ";
for (int ue = 0; ue < NUM_UE; ue++) {
std::cout << "UE" << ue << "=" << std::fixed
<< std::setprecision(2) << avgThroughput[ue] << " ";
}
std::cout << "\n";
}
}
// ===========================
// 算法四:比例公平调度 (Proportional Fairness)
// 决策:max { d_k^i(t) / R^i(t-1) }
// ===========================
void proportionalFairness() {
std::cout << "\n=== 比例公平调度 (Proportional Fairness) ===\n";
const double beta = 0.8;
double avgThroughput[NUM_UE];
for (int ue = 0; ue < NUM_UE; ue++) {
double sum = 0;
for (int rb = 0; rb < NUM_RB; rb++) sum += channel[ue][rb];
avgThroughput[ue] = sum / NUM_RB;
}
for (int round = 0; round < ROUNDS; round++) {
std::cout << "第" << round + 1 << "轮: ";
for (int rb = 0; rb < NUM_RB; rb++) {
// 找到 d_k^i(t) / R^i(t-1) 最大的设备
int bestUE = -1;
double bestScore = -1.0;
for (int ue = 0; ue < NUM_UE; ue++) {
if (!hasData[ue]) continue;
// PF 得分 = 当前信道质量 / 历史平均吞吐量
double score = channel[ue][rb] / avgThroughput[ue];
if (score > bestScore) {
bestScore = score;
bestUE = ue;
}
}
if (bestUE == -1) break;
std::cout << "RB" << rb << "->UE" << bestUE
<< "(得分=" << std::fixed << std::setprecision(2)
<< bestScore << ") ";
// 更新被调度设备的平均吞吐量(EWMA)
double r = channel[bestUE][rb];
avgThroughput[bestUE] = (1 - beta) * r + beta * avgThroughput[bestUE];
}
std::cout << "\n";
}
}
int main() {
std::cout << "5G MAC 调度算法模拟\n";
std::cout << "设备数:" << NUM_UE
<< ",资源块数:" << NUM_RB
<< ",调度轮次:" << ROUNDS << "\n";
std::cout << "\n信道质量矩阵(Mbps):\n";
std::cout << " ";
for (int rb = 0; rb < NUM_RB; rb++)
std::cout << "RB" << rb << " ";
std::cout << "\n";
for (int ue = 0; ue < NUM_UE; ue++) {
std::cout << "UE" << ue << ": ";
for (int rb = 0; rb < NUM_RB; rb++)
std::cout << std::setw(5) << channel[ue][rb] << " ";
std::cout << "\n";
}
roundRobin();
maxThroughput();
blindEqualThroughput();
proportionalFairness();
return 0;
}
https://godbolt.org/z/aaMxq9E5E
编译运行:
g++ -o mac_scheduler mac_scheduler.cpp && ./mac_scheduler
7. 能耗管理:休眠与唤醒
7.1 为什么要省电?
LTE 无线电在收发时耗电 1000~3500 mW,但关闭时仅耗电 15 mW(不到开启时的 1/66)。移动应用中,20%~50% 的电量消耗在通信上。因此,让设备在不通信时"睡眠"是非常重要的节能手段。
7.2 两种省电策略
7.3 协调式睡眠/唤醒
设备和基站双方都知道设备的睡眠/唤醒状态,基站会为睡眠中的设备缓存到来的数据包,等设备唤醒后再发送。
WiFi 的协调睡眠(802.11)
设备发送: [帧头中 power-management bit = 1] --> AP 知道设备要睡了
AP 行为:缓存所有发往该设备的帧
设备周期性唤醒:
--> 扫描 Beacon 帧中的 TIM (Traffic Indication Map)
--> 如果 TIM 显示有帧缓存:发送轮询请求,AP 传输缓存帧
--> 如果 TIM 无帧缓存:继续睡眠
WiFi 6 新增 TWT(目标唤醒时间):设备和 AP 协商好睡眠时长,最长可达 4年5个月!
5G DRX(非连续接收,图7.38)
5G 设备有两种深度的睡眠:
时间轴:
t0 t1 t2 t3 t4 t5
| | | | | |
v v v v v v
[活跃接收数据]-->[短DRX睡眠<->短DRX睡眠]-->[长DRX睡眠<->]-->[数据到达]-->[唤醒]-->[接收]
活动计时器 短DRX 到期 长DRX 到期
启动 进入长DRX 设备唤醒
短 DRX 睡眠:
- 较短的睡眠周期(如几十毫秒)
- 每次唤醒检查是否有数据
- 延迟小,但耗电稍多
长 DRX 睡眠: - 较长的睡眠周期(如几百毫秒)
- 延迟较大( t 5 − t 3 t_5 - t_3 t5−t3),但更省电
时序说明: - t 0 t_0 t0:收到数据,启动活动计时器
- t 1 t_1 t1:计时器超时,进入短 DRX 睡眠
- t 2 t_2 t2:多个短 DRX 周期内无活动,进入长 DRX 睡眠
- t 3 t_3 t3:有新数据包到达基站,基站缓存(设备仍在睡)
- t 4 t_4 t4:长 DRX 周期结束,设备唤醒检查
- t 5 t_5 t5:设备接收数据
额外延迟 = t 5 − t 3 t_5 - t_3 t5−t3(这就是睡眠带来的代价)
7.4 非协调式唤醒发送:LoRaWAN(图7.39)
LoRa 是专为 IoT 设计的低功耗、低速率无线技术(覆盖范围可达几公里)。
最简单的 Class A 设备完全由设备主导:
时间轴:
LoRa 网关 ---↑LoRa帧------------------[等待t2]------------------↑LoRa帧---
| | |
IoT 设备 ---[t0]---[t1]--/睡眠/--[t2]---[t3]---[t4]---[t5]---------
唤醒 等待下行 睡眠 网关有 设备唤 网关 设备
发数据 数据(无) 下行消息 醒发数据 发帧 睡眠
关键特点:
- 设备不知道网关是否存在,直接发就完了
- 发完后短暂等待下行数据(如果有的话)
- 没有下行数据就立刻睡眠
- 网关如果 t 2 t_2 t2 时有消息要发,必须等到设备下次主动联系( t 3 t_3 t3 后)才能发送
- 设备节能优先,可能出现较大的下行延迟
7.5 三种省电方式对比
| 特性 | WiFi 802.11 | 5G DRX | LoRaWAN Class A |
|---|---|---|---|
| 协调方式 | 协调式 | 协调式 | 非协调式 |
| 谁主导 | 双方协商 | 基站+设备协商 | 设备主导 |
| 下行延迟 | 较低 | 中等 | 较高(等下次唤醒) |
| 节能效果 | 好 | 好 | 最好 |
| 适用场景 | 手机/电脑 | 手机/5G设备 | IoT 传感器 |
| 代表标准 | 802.11 | 3GPP 5G | LoRaWAN |
总结
5G RAN 链路层
├── 协议栈(图7.31)
│ ├── 用户平面:SDAP -> PDCP -> RLC -> MAC -> PHY
│ └── 控制平面:RRC(统筹管理)
│
├── 基站解聚合(图7.33)
│ ├── CU(中央单元):RRC + SDAP + PDCP
│ ├── DU(分布式单元):RLC + MAC + PHY部分
│ └── RU(射频单元):D/A转换 + 射频前端
│
├── SD-RAN(图7.34)
│ ├── 控制平面代理
│ ├── RIC(实时智能控制器)+ R-NIB
│ └── xApps(负载均衡/切换/QoS等)
│
├── 网络附着
│ ├── WiFi:Beacon -> 关联请求 -> 关联响应(3步)
│ └── 5G:SSB/SIBs -> RRC连接请求 -> RRC连接响应(多步)
│
├── MAC 调度算法(图7.37)
│ ├── RR:轮询,简单公平
│ ├── MT:最大吞吐量,不公平
│ ├── BET:吞吐量公平,EWMA 均衡
│ └── PF:比例公平,效率与公平的平衡(最常用)
│
└── 能耗管理
├── WiFi:TIM + TWT(协调式)
├── 5G:DRX 短/长睡眠周期(协调式)
└── LoRaWAN Class A:唤醒即发,不协调(最省电)
5G 无线核心网 详细解析
本文对应教材第7章第4节,结合图7.40~7.42,用通俗语言解释5G核心网的架构、隧道技术、身份认证与会话建立过程。
目录
1. 为什么5G需要核心网?
1.1 传统IP网络 vs 5G网络
WiFi 和有线以太网在企业内部看起来是"同等地位"的链路层技术——不需要特殊的核心网来管理。但5G(以及4G)却有一个专门的核心网(Core Network),为什么?
答案藏在历史里:
1G/2G:纯电话网,通过核心网管理身份、计费、漫游
|
v
3G:电话为主,数据服务是"附加品"
|
v
4G/5G:全IP网络,但仍继承了核心网负责的身份/移动性/计费等服务
传统互联网 ISP 从未内置以下服务:
- 全球统一的用户身份识别(SIM卡体系)
- 跨运营商漫游
- 设备移动性(从一个基站切换到另一个基站时保持连接)
- 按用量计费与结算
这些服务都由5G核心网来实现,这是5G与传统IP网络最本质的区别之一。
1.2 服务化架构(SBA)
5G核心网采用服务化架构(Service-Based Architecture,SBA):
| 旧思路(4G及之前) | 新思路(5G) |
|---|---|
| 定义网络"实体"(黑盒子) | 定义网络功能(Network Function,NF) |
| 通过专有协议交互 | 通过标准化服务接口交互 |
| 单厂商专用设备 | 可部署为云端微服务 |
| 控制平面与数据平面耦合 | 明确分离控制平面与用户平面 |
这种演变和第5章学过的SDN思路非常相似:从"专用盒子"走向"软件服务"。
2. 5G核心网架构与网络功能
2.1 整体架构(图7.40)
+--------------------------------------------------+
| 数据存储层 |
| +------------------+ +-------------------+ |
| | UDR | | UDSF | |
| | 统一数据仓库 | | 非结构化数据存储 | |
| +------------------+ +-------------------+ |
+--------------------------------------------------+
| 控制平面(Control Plane) |
| +------+ +-----+ +-----+ +-----+ +------+ |
| | AUSF | | PCF | | UDM | | NEF | | SEPP |----->其他运营商
| +------+ +-----+ +-----+ +-----+ +------+ |
| +------+ +-----+ +-----+ +----+ |
| | AMF | | SMF | | NRF | | AF | |
| +------+ +-----+ +-----+ +----+ |
| ^ ^ |
| |N1|N2 (N1: 直连设备, N2: 直连基站) |
+-----|--|----+------------------------------------+
| |
设备 基站
| |N3
+-----|--|-------------------------------------------+
| v v 用户平面(User Plane) |
| 基站 --N3--> UPF (用户平面功能) ---------> Internet |
+----------------------------------------------------+
2.2 核心网络功能详解
"最重要的三个"网络功能
① UPF:用户平面功能(User Plane Function)
- 身份:5G中唯一位于数据平面的网络功能
- 职责:在基站和互联网之间转发用户IP数据报
- 比喻:高速公路上的"隧道入口/出口"——所有数据必须经过这里
② AMF:接入与移动性管理功能(Access and Mobility Management Function) - 身份:控制平面的"大管家"
- 职责:
- 授权设备接入5G网络
- 管理设备的移动性(切换基站)
- 唯一能通过 N1 接口直接与设备通信的网络功能
- 能通过 N2 接口直接与基站通信(共有两个这样的NF)
- 比喻:机场的"登机口管理员"——你必须通过他才能登机(接入网络)
③ SMF:会话管理功能(Session Management Function) - 职责:
- 为每个设备分配IP地址(类似DHCP)
- 建立和管理数据平面通道(隧道)
- 管理策略、计费等
- 比喻:酒店前台——给你分配房间号(IP地址),建立你的"专属通道"
数据管理功能
UDM 可以把数据存在自己内部,也可以存到外部的 UDR 中(无状态交互,类似 HTTP 的无状态模型),这样可以轻松扩容,适合云端部署。
其他重要功能
| 功能缩写 | 全称 | 核心职责 | 简单比喻 |
|---|---|---|---|
| AUSF | 认证服务器功能 | 验证设备身份(配合AMF) | 海关检查护照 |
| PCF | 策略控制功能 | 管理移动性/QoS/漫游策略 | 规则制定部门 |
| NRF | 网络仓库功能 | NF自动注册与发现 | 黄页/服务目录 |
| NEF | 网络开放功能 | 向第三方应用暴露网络数据 | API 网关 |
| AF | 应用功能 | 第三方应用与核心网的交互点 | 开发者接口 |
| SEPP | 安全边界保护代理 | 跨运营商安全通信(漫游) | 边境安检站 |
| NSSF | 网络切片选择功能 | 管理网络切片(虚拟化网络) | 多租户管理员 |
网络切片(Network Slicing)简介
5G引入了网络切片的概念:在同一套物理基础设施上,虚拟化出多个逻辑网络,供不同业务独立使用。
物理基础设施(一套5G网络)
+------------------------------------+
| 切片A:自动驾驶(超低延迟) |
| 切片B:视频直播(高带宽) |
| 切片C:IoT传感器(超大连接数) |
+------------------------------------+
这和第6章学过的 VPN 在同一物理网络上运行多个逻辑网络的思路完全一致。
2.3 网络功能之间的通信方式
NF之间可以用以下方式通信(标准不强制规定哪种):
方式一:请求/响应(Request/Response)
NF-A -----[请求]-----> NF-B
NF-A <----[响应]------ NF-B
类似HTTP,同步交互,实现简单。
方式二:订阅/通知(Subscribe/Notify,即发布/订阅)
NF-A -----[订阅:我关注X事件]-----> NF-B
(一段时间后X事件发生)
NF-A <----[通知:X事件发生了]------- NF-B
类似第5章 Google Orion SDN 平台的核心模型,适合事件驱动场景。
3. 用户平面功能与隧道技术
3.1 什么是隧道?
隧道(Tunneling)的本质:把一个IP数据报包裹进另一个IP数据报里发送,对中间路由器透明。
没有隧道的世界:
互联网 -> 回程网络中每个路由器都需要知道"设备z现在在哪个基站"
(路由表爆炸!)
有了隧道的世界:
互联网 -> UPF(只有UPF知道设备z在哪个基站)-> 基站 -> 设备z
中间所有路由器只需知道如何到达基站,无需关心设备z的位置
3.2 5G中的隧道机制(图7.41)
5G使用 GTP-U(GPRS Tunneling Protocol - User Plane) 协议,通过 UDP 封装实现隧道。
数据流向(下行:互联网 -> 设备)
步骤1: 互联网发来数据报
+-------------------+
| Src:w Dst:z | <- w是互联网服务器,z是用户设备地址
| 用户数据 |
+-------------------+
步骤2: UPF进行GTP-U封装(套娃)
+-------------------+---------------------------+
| Src:x Dst:y | GTP-U | UDP | Src:w Dst:z | 用户数据 |
+-------------------+---------------------------+
^ UPF地址 ^ 基站地址
外层IP头 内层原始数据报
步骤3: 回程网络(Backhaul)像普通IP数据报一样转发到基站y
步骤4: 基站y解封装,取出内层数据报
+-------------------+
| Src:w Dst:z | <- 还原成原始数据报
| 用户数据 |
+-------------------+
步骤5: 基站通过RAN无线发给设备z
关键地址对应:
| 地址 | 含义 |
|---|---|
| w w w | 互联网发送方地址 |
| z z z | 用户设备地址(UPF分配) |
| x x x | UPF的IP地址 |
| y y y | 基站的IP地址 |
外层数据报头:源地址 x x x(UPF),目的地址 y y y(基站)
内层数据报头:源地址 w w w(互联网),目的地址 z z z(用户设备)
3.3 为什么用隧道?(关键理解)
核心原因:支持设备移动性
设备从基站A移动到基站B时:
没有隧道:
互联网上所有路由器都需要更新路由表:"设备z现在在基站B了"
-> 不可扩展,路由表爆炸
有了隧道:
只需更新UPF中的一条记录:"设备z的隧道目的地从基站A改为基站B"
-> 回程网络路由器完全不受影响
UPF 充当"锚点"(Anchor Point):无论设备移动到哪个基站,外部互联网始终通过UPF找到设备,UPF负责将数据"转投"到正确的基站。
3.4 协议栈结构(图7.41完整解析)
用户设备端 基站端(左侧RAN协议栈) 基站端(隧道协议栈) UPF端
+---------+ +------------------+ +-----------+ +----------+
| Network | | SDAP/RRC | | GTP-U | | GTP-U |
| SDAP RRC| | PDCP | | UDP | | UDP |
| PDCP | | RLC | | IP | | IP |
| RLC | | MAC | | Link | | Link |
| MAC | | Physical | | Physical | | Physical |
| Physical| +------------------+ +-----------+ +----------+
+---------+ ^ ^ ^
^ | | |
| 无线电波 有线回程网络(Backhaul) |
|<--RAN无线链路------>|<---------GTP-U隧道(基站y <-> UPF x)---->|
4. 用户身份、注册与会话建立
4.1 SIM卡:你的全球网络身份证
SIM(Subscriber Identity Module)卡是你在全球蜂窝网络中的唯一身份标识。
SIM卡包含的信息:
IMSI 结构示例:
460 01 1234567890
^ ^ ^
MCC MNC MSIN
(中国)(联通) (用户号)
- 归属网络(Home Network):你的运营商(MCC+MNC决定)
- 访问网络(Visited Network):当你漫游时接入的其他运营商网络
4.2 注册与会话建立(图7.42)
加入5G网络分为两大阶段:注册(Registration) 和 PDU 会话建立(Session Establishment)。
完整时序图(ASCII版本)
设备(H1) 基站(gNB) AMF AUSF 归属网AUSF UDM SMF UPF
| | | | | | | |
|--RRC连接请求/响应------->| | | | | |
| |--注册请求-->| | | | | |
| | | | | | | |
|<-----------身份请求------| | | | | |
|------------身份响应----->| | | | | |
|<-----------认证/安全-----|<---认证/安全->|<----认证/安全->| | | |
|------------认证/安全---->| | | | | |
| | | | |---更新设备->| | |
| | | | | 连接数据 | | |
|<-----------注册接受------| | | | | |
| | | | | | | |
|---PDU会话建立请求-------->| | | | | |
| | |--会话创建请求-->| | |<--订阅检索->| |
| | | | | |<--订阅更新->| |
| | |<-会话创建响应--| | | | |
| | | | | | |--会话建立-->|
| | | | | | |<-会话建立响应|
| | |<--会话信息(IPv4地址,隧道)-------| | | |
|<---会话请求(含SMF信息)-----| | | | | |
|---会话响应--------------->| | | | | |
| | | | | | | |
|============RAN数据平面配置=============| | | | |
| | | | | | | |
|-----第一个上行数据报----->|===================================(通过UPF)==========Internet====>|
阶段一:注册(Registration)详解
目的:让网络知道"你是谁",并验证你的身份。
步骤1: RRC 连接建立(在第7.3.4节已完成)
设备 <--> 基站 建立无线控制信道
步骤2: 基站选择一个 AMF 实例,发送注册请求
步骤3: AMF 向设备索要身份信息(IMSI等)
步骤4: 相互认证
AMF <-> 本地AUSF <-> 归属网络AUSF(如果在漫游)
设备也验证网络的身份(双向认证)
步骤5: AMF 在本地 UDM 中注册设备的身份和订阅服务信息
步骤6: AMF 向设备发送"注册接受"消息
漫游时的认证特殊情况:
你的手机(在A运营商网络)
|
| 想接入
v
B运营商网络的 AUSF
|
| 联系
v
A运营商网络的 AUSF(你的归属网络)
|
v
真正执行认证(A运营商认识你)
两个运营商的 AUSF 之间通过各自的 SEPP(安全边界保护代理) 安全通信。
阶段二:PDU 会话建立(Session Establishment)详解
目的:建立数据平面通道,获得IP地址,真正能上网。
步骤1: 设备发送 PDU 会话建立请求 -> AMF
步骤2: AMF 选择一个 SMF 实例,负责管理该设备的数据平面
步骤3: SMF 通过 UDM 验证设备请求的会话参数是否被允许
步骤4: SMF 选择一个 UPF 实例,建立:
基站 <----GTP-U隧道----> UPF
(这条隧道专属于该设备)
步骤5: SMF 将以下信息返回给设备(经 AMF -> 基站 -> 设备):
- 隧道参数
- 分配的 IPv4 地址
- 其他会话信息
步骤6: 基站和设备配置 RAN 数据平面
步骤7: 设备可以发送第一个上行数据报!
4.3 整个流程的Mermaid时序图
5. 完整流程总结
5.1 5G核心网网络功能总览
5.2 关键概念对比
| 概念 | 类比 | 作用 |
|---|---|---|
| UPF | 高速公路隧道入口 | 唯一数据平面NF,转发所有用户数据 |
| AMF | 机场登机口管理员 | 控制平面核心,管理接入和移动性 |
| SMF | 酒店前台 | 分配IP、建立隧道、管理会话 |
| AUSF | 海关+护照验证 | 双向身份认证 |
| UDM | 户籍管理系统 | 管理用户档案和订阅信息 |
| NRF | 114查号台 | NF自动注册和发现 |
| SEPP | 边境安检站 | 跨运营商安全通信 |
| SIM/IMSI | 护照 | 全球唯一用户身份标识 |
5.3 隧道封装示意(数据报套娃)
互联网 -> UPF 收到:
+-----------------------------------+
| Src: w (互联网) | Dst: z (设备) |
| 用户数据 |
+-----------------------------------+
UPF 进行 GTP-U 封装后 -> 基站:
+------------------+---------------------------+
| Src:x(UPF地址) | GTP-U | UDP | |
| Dst:y(基站地址) | | Src:w Dst:z |用户数据|
+------------------+---------------------------+
外层IP头(回程网络可见) 内层原始IP头(对回程路由器不可见)
基站 解封装后 -> 设备:
+-----------------------------------+
| Src: w (互联网) | Dst: z (设备) |
| 用户数据 |
+-----------------------------------+
5.4 设备从注册到上网的完整生命周期
手机开机
|
v
[7.3.4] 扫描 PSS/SSS/MIB/SIBs,选择基站
|
v
[7.3.4] RRC 连接建立请求/响应(只是无线信道建立)
|
v
[7.4.3] 注册:AMF验证身份(AUSF认证),UDM记录
|
v
[7.4.3] PDU会话建立:SMF分配IP,建立基站<->UPF隧道
|
v
数据平面就绪,开始上网!
|
v
[7.5] 移动性管理:设备移动时,切换基站,更新UPF隧道端点
附录:C++ 模拟5G核心网注册流程
// 5G 核心网注册与会话建立流程模拟
// 模拟各网络功能之间的消息交互顺序
#include <iostream>
#include <string>
#include <vector>
#include <map>
// =========================================
// 消息结构体:模拟网络功能之间传递的消息
// =========================================
struct Message {
std::string from; // 发送方
std::string to; // 接收方
std::string type; // 消息类型
std::string payload; // 消息内容
};
// =========================================
// 打印消息(模拟消息传递)
// =========================================
void sendMessage(const Message& msg) {
std::cout << "[" << msg.from << "] ---["
<< msg.type << "]--> ["
<< msg.to << "]";
if (!msg.payload.empty())
std::cout << " : " << msg.payload;
std::cout << "\n";
}
// =========================================
// SIM 卡信息结构体
// =========================================
struct SIMCard {
std::string mcc; // 移动国家码,如 "460"(中国)
std::string mnc; // 移动网络码,如 "01"(联通)
std::string msin; // 移动用户识别号
std::string cryptoKey; // 认证密钥(实际中不明文存储,此处模拟)
// IMSI = MCC + MNC + MSIN
std::string getIMSI() const {
return mcc + mnc + msin;
}
// 判断归属网络
std::string getHomeNetwork() const {
return "MCC=" + mcc + " MNC=" + mnc;
}
};
// =========================================
// 会话信息结构体
// =========================================
struct SessionInfo {
std::string deviceAddr; // 分配给设备的IP地址(z)
std::string upfAddr; // UPF地址(x)
std::string baseStationAddr; // 基站地址(y)
std::string tunnelId; // GTP-U隧道标识符
bool established; // 会话是否已建立
};
// =========================================
// 5G 核心网主流程模拟
// =========================================
class FiveGCoreSimulator {
private:
SIMCard sim;
SessionInfo session;
bool authenticated;
bool registered;
public:
FiveGCoreSimulator(const SIMCard& s)
: sim(s), authenticated(false), registered(false) {
// 初始化会话信息
session.upfAddr = "10.0.0.1";
session.baseStationAddr = "192.168.1.1";
session.established = false;
}
// ----------------------------------------
// 阶段一:RRC 连接建立(RAN层)
// ----------------------------------------
void rrcConnectionSetup() {
std::cout << "\n======= 阶段0: RRC 无线连接建立 =======\n";
sendMessage({"设备", "基站", "RRC连接建立请求", "设备想接入网络"});
sendMessage({"基站", "设备", "RRC连接建立响应", "无线控制信道已建立"});
std::cout << "=> 设备和基站之间的RRC控制信道已就绪\n";
}
// ----------------------------------------
// 阶段二:注册(Registration)
// ----------------------------------------
void registration() {
std::cout << "\n======= 阶段1: 注册 (Registration) =======\n";
// 步骤1: 基站向 AMF 发送注册请求
sendMessage({"基站", "AMF", "注册请求", "设备请求接入网络"});
// 步骤2: AMF 向设备请求身份
sendMessage({"AMF", "设备", "身份请求", "请提供 IMSI"});
sendMessage({"设备", "AMF", "身份响应",
"IMSI=" + sim.getIMSI() + " 归属网=" + sim.getHomeNetwork()});
// 步骤3: AMF 联系 AUSF 进行认证
// 判断是否在漫游(此处模拟简单逻辑:MCC=460为归属网)
bool isRoaming = (sim.mcc != "460");
if (isRoaming) {
std::cout << " [检测到漫游,将通过 SEPP 联系归属网络 AUSF]\n";
sendMessage({"AMF", "本地AUSF", "认证请求", "IMSI=" + sim.getIMSI()});
sendMessage({"本地AUSF", "归属网AUSF", "跨网认证请求(via SEPP)",
"IMSI=" + sim.getIMSI()});
sendMessage({"归属网AUSF", "本地AUSF", "认证向量",
"认证挑战数据(由归属网生成)"});
} else {
sendMessage({"AMF", "AUSF", "认证请求", "IMSI=" + sim.getIMSI()});
}
// 步骤4: 设备与网络双向认证
sendMessage({"AMF", "设备", "认证挑战", "请用密钥响应挑战"});
sendMessage({"设备", "AMF", "认证响应", "用SIM密钥计算的响应值"});
authenticated = true;
std::cout << " => 双向认证成功!\n";
// 步骤5: AMF 在 UDM 中注册设备
sendMessage({"AMF", "UDM", "更新设备连接数据",
"设备 " + sim.getIMSI() + " 已认证,更新状态"});
// 步骤6: 注册成功
sendMessage({"AMF", "设备", "注册接受", "欢迎接入5G网络"});
registered = true;
std::cout << "=> 注册完成!设备身份已验证并记录\n";
}
// ----------------------------------------
// 阶段三:PDU 会话建立(Session Establishment)
// ----------------------------------------
void sessionEstablishment() {
if (!registered) {
std::cout << "错误:设备尚未注册,无法建立会话!\n";
return;
}
std::cout << "\n======= 阶段2: PDU 会话建立 (Session Establishment) =======\n";
// 步骤1: 设备发起 PDU 会话请求
sendMessage({"设备", "AMF", "PDU会话建立请求", "我需要一个IP数据平面通道"});
// 步骤2: AMF 选择 SMF 并发起会话创建
sendMessage({"AMF", "SMF", "会话创建请求", "为设备 " + sim.getIMSI() + " 建立会话"});
// 步骤3: SMF 向 UDM 验证订阅参数
sendMessage({"SMF", "UDM", "订阅信息检索", "检查设备允许的服务类型"});
sendMessage({"UDM", "SMF", "订阅信息响应", "设备有效,允许数据服务"});
// 步骤4: SMF 选择 UPF,建立隧道
sendMessage({"SMF", "UPF", "会话建立请求",
"为设备建立隧道,基站地址=" + session.baseStationAddr});
// 分配设备IP地址(模拟)
session.deviceAddr = "10.1.1.100"; // SMF/UPF 分配给设备的IP
session.tunnelId = "TUNNEL_001";
sendMessage({"UPF", "SMF", "会话建立响应",
"隧道已创建,设备IP=" + session.deviceAddr +
" 隧道ID=" + session.tunnelId});
// 步骤5: SMF 将会话信息返回给 AMF
sendMessage({"SMF", "AMF", "会话信息",
"IPv4=" + session.deviceAddr +
" UPF=" + session.upfAddr +
" 隧道=" + session.tunnelId});
// 步骤6: AMF 通知基站,基站通知设备
sendMessage({"AMF", "基站", "会话请求(含SMF信息)",
"配置RAN数据平面,设备IP=" + session.deviceAddr});
sendMessage({"基站", "AMF", "会话响应", "RAN数据平面配置完成"});
sendMessage({"基站", "设备", "RAN数据平面配置",
"你的IP=" + session.deviceAddr + " 隧道已就绪"});
session.established = true;
std::cout << "=> 会话建立完成!设备可以上网了\n";
}
// ----------------------------------------
// 数据发送演示:展示隧道封装
// ----------------------------------------
void sendFirstDatagram() {
if (!session.established) {
std::cout << "错误:会话尚未建立!\n";
return;
}
std::cout << "\n======= 数据传输演示:GTP-U 隧道封装 =======\n";
std::cout << "设备发送第一个数据报:\n";
std::cout << " 原始数据报: [Src:" << session.deviceAddr
<< " | Dst:互联网服务器 | 用户数据]\n";
std::cout << "\n基站进行 GTP-U 封装(上行:设备->互联网):\n";
std::cout << " 外层: [Src:" << session.baseStationAddr
<< "(基站) | Dst:" << session.upfAddr << "(UPF)]\n";
std::cout << " 内层: [GTP-U | UDP | Src:" << session.deviceAddr
<< " | Dst:互联网 | 用户数据]\n";
std::cout << "\n回程网络(Backhaul)只看外层地址,转发到 UPF\n";
std::cout << "\nUPF 解封装,取出内层数据报转发到互联网:\n";
std::cout << " [Src:" << session.deviceAddr
<< " | Dst:互联网服务器 | 用户数据] --> Internet\n";
sendMessage({"设备(via基站)", "UPF", "第一个上行数据报",
"GTP隧道=" + session.tunnelId});
std::cout << "=> 数据成功发送到互联网!\n";
}
// 打印设备当前状态
void printStatus() const {
std::cout << "\n======= 设备状态 =======\n";
std::cout << "IMSI: " << sim.getIMSI() << "\n";
std::cout << "归属网络: " << sim.getHomeNetwork() << "\n";
std::cout << "认证状态: " << (authenticated ? "已认证" : "未认证") << "\n";
std::cout << "注册状态: " << (registered ? "已注册" : "未注册") << "\n";
if (session.established) {
std::cout << "设备IP: " << session.deviceAddr << "\n";
std::cout << "UPF地址: " << session.upfAddr << "\n";
std::cout << "隧道ID: " << session.tunnelId << "\n";
}
std::cout << "会话状态: " << (session.established ? "已建立" : "未建立") << "\n";
}
};
int main() {
std::cout << "5G 核心网注册与会话建立流程模拟\n";
std::cout << "=====================================\n";
// 创建一张模拟 SIM 卡
// MCC=460(中国),MNC=01(联通),MSIN为用户编号
SIMCard mySIM;
mySIM.mcc = "460";
mySIM.mnc = "01";
mySIM.msin = "1234567890";
mySIM.cryptoKey = "KEY_SECRET_ABC";
// 创建模拟器
FiveGCoreSimulator sim5g(mySIM);
// 执行完整流程
sim5g.rrcConnectionSetup(); // 步骤0:建立RRC无线连接
sim5g.registration(); // 步骤1:注册(身份认证)
sim5g.sessionEstablishment(); // 步骤2:PDU会话建立(获IP/隧道)
sim5g.sendFirstDatagram(); // 步骤3:发送第一个数据报
// 打印最终状态
sim5g.printStatus();
return 0;
}
https://godbolt.org/z/4M9eW4ehP
5G 核心网注册与会话建立流程模拟
=====================================
======= 阶段0: RRC 无线连接建立 =======
[设备] ---[RRC连接建立请求]--> [基站] : 设备想接入网络
[基站] ---[RRC连接建立响应]--> [设备] : 无线控制信道已建立
=> 设备和基站之间的RRC控制信道已就绪
======= 阶段1: 注册 (Registration) =======
[基站] ---[注册请求]--> [AMF] : 设备请求接入网络
[AMF] ---[身份请求]--> [设备] : 请提供 IMSI
[设备] ---[身份响应]--> [AMF] : IMSI=460011234567890 归属网=MCC=460 MNC=01
[AMF] ---[认证请求]--> [AUSF] : IMSI=460011234567890
[AMF] ---[认证挑战]--> [设备] : 请用密钥响应挑战
[设备] ---[认证响应]--> [AMF] : 用SIM密钥计算的响应值
=> 双向认证成功!
[AMF] ---[更新设备连接数据]--> [UDM] : 设备 460011234567890 已认证,更新状态
[AMF] ---[注册接受]--> [设备] : 欢迎接入5G网络
=> 注册完成!设备身份已验证并记录
======= 阶段2: PDU 会话建立 (Session Establishment) =======
[设备] ---[PDU会话建立请求]--> [AMF] : 我需要一个IP数据平面通道
[AMF] ---[会话创建请求]--> [SMF] : 为设备 460011234567890 建立会话
[SMF] ---[订阅信息检索]--> [UDM] : 检查设备允许的服务类型
[UDM] ---[订阅信息响应]--> [SMF] : 设备有效,允许数据服务
[SMF] ---[会话建立请求]--> [UPF] : 为设备建立隧道,基站地址=192.168.1.1
[UPF] ---[会话建立响应]--> [SMF] : 隧道已创建,设备IP=10.1.1.100 隧道ID=TUNNEL_001
[SMF] ---[会话信息]--> [AMF] : IPv4=10.1.1.100 UPF=10.0.0.1 隧道=TUNNEL_001
[AMF] ---[会话请求(含SMF信息)]--> [基站] : 配置RAN数据平面,设备IP=10.1.1.100
[基站] ---[会话响应]--> [AMF] : RAN数据平面配置完成
[基站] ---[RAN数据平面配置]--> [设备] : 你的IP=10.1.1.100 隧道已就绪
=> 会话建立完成!设备可以上网了
======= 数据传输演示:GTP-U 隧道封装 =======
设备发送第一个数据报:
原始数据报: [Src:10.1.1.100 | Dst:互联网服务器 | 用户数据]
基站进行 GTP-U 封装(上行:设备->互联网):
外层: [Src:192.168.1.1(基站) | Dst:10.0.0.1(UPF)]
内层: [GTP-U | UDP | Src:10.1.1.100 | Dst:互联网 | 用户数据]
回程网络(Backhaul)只看外层地址,转发到 UPF
UPF 解封装,取出内层数据报转发到互联网:
[Src:10.1.1.100 | Dst:互联网服务器 | 用户数据] --> Internet
[设备(via基站)] ---[第一个上行数据报]--> [UPF] : GTP隧道=TUNNEL_001
=> 数据成功发送到互联网!
======= 设备状态 =======
IMSI: 460011234567890
归属网络: MCC=460 MNC=01
认证状态: 已认证
注册状态: 已注册
设备IP: 10.1.1.100
UPF地址: 10.0.0.1
隧道ID: TUNNEL_001
会话状态: 已建立
编译运行:
g++ -o 5g_core_sim 5g_core_sim.cpp && ./5g_core_sim
总结
5G 核心网(7.4节)
├── 架构(SBA)
│ ├── 从"黑盒设备"演变为"微服务"
│ ├── 控制平面与用户平面明确分离
│ └── NF之间用请求/响应或订阅/通知交互
│
├── 核心网络功能(图7.40)
│ ├── 数据平面:UPF(唯一)
│ ├── 控制平面:AMF(核心)、SMF、AUSF、PCF、UDM、NRF...
│ └── 数据存储:UDR、UDSF
│
├── 隧道技术(图7.41)
│ ├── 协议:GTP-U over UDP/IP
│ ├── 路径:设备 <-无线-> 基站 <-GTP隧道-> UPF <-> 互联网
│ ├── 地址:外层(x->y),内层(w->z)
│ └── 目的:支持设备移动性,只有UPF是锚点
│
└── 注册与会话建立(图7.42)
├── SIM/IMSI:全球唯一身份 = MCC + MNC + MSIN
├── 注册:RRC连接 -> AMF -> AUSF认证 -> UDM记录
└── 会话建立:PDU请求 -> SMF分配IP -> 建立GTP隧道 -> 可以上网
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐



所有评论(0)