2. Thread网络架构与协议栈解析

Thread 并不是一个从零发明的协议,而是一套把成熟标准“拼装”起来的低功耗 IPv6 网状网络方案。理解它的最好方式,是沿着一条数据从应用层向下走到射频、再向上回到应用层的路径,逐层看清每一层负责什么、封装了什么、又依赖谁。本节按 IEEE 802.15.4 物理层与 MAC 层、6LoWPAN 适配层、Thread 网络层与路由机制、UDP 与 CoAP 传输这条主线展开,并在最后给出一份可用于实际抓包对照的封装结构参考。

一、IEEE 802.15.4:物理层与 MAC 层

Thread 的底层完全建立在 IEEE 802.15.4-2006 之上,工作在 2.4 GHz ISM 频段。物理层(PHY)负责把比特变成无线电信号:它定义了 16 个信道(信道 11~26),每个信道带宽 2 MHz,采用 O-QPSK 调制与 DSSS 扩频,标称速率 250 kbps。物理层帧由前导码(4 字节)、帧定界符 SFD(1 字节)、长度字段(1 字节)和 PSDU(最大 127 字节)组成,因此单帧有效载荷上限是 127 字节——这个数字是后面 6LoWPAN 必须做分片压缩的根本原因。

MAC 层负责信道访问与帧的可靠投递。它使用 CSMA/CA:发送前先做空闲信道评估(CCA),信道忙则退避重试。MAC 帧头包含帧控制字段、序列号、寻址字段(PAN ID 与短地址/扩展地址),帧尾是 2 字节 FCS 校验。Thread 使用 802.15.4 的扩展地址(EUI-64)作为设备出厂标识,但在网络内部大量使用 16 位短地址以压缩开销。需要特别注意的是:Thread 并不使用 802.15.4 的“信标使能”模式,而是采用非信标模式,节点异步竞争信道,这为网状转发提供了灵活性。

二、6LoWPAN:把 IPv6 塞进 127 字节

IPv6 报头固定 40 字节,UDP 报头 8 字节,若再加上应用数据,很容易超过 127 字节的 MAC 载荷。6LoWPAN(RFC 4944、6282)就是为此而生的适配层,它做三件事:报头压缩、分片与重组、以及网状寻址。

报头压缩是核心。6LoWPAN 定义了 LOWPAN_IPHC 编码,把 IPv6 报头中大量可推导字段省略:版本号、流量类别、跳数限制等可压缩为 1~2 字节;链路本地地址可由 MAC 地址推导,因此源/目的地址可压缩到 0、8 或 16 位。压缩后,一个典型的 IPv6 + UDP 报头可以从 48 字节降到 6 字节左右。分片则通过 FRAG1/FRAG2 报头实现,把超过单帧容量的 IPv6 包切成多个 802.15.4 帧传输,接收端按 datagram tag 与 offset 重组。此外,6LoWPAN 还定义了 Mesh Header,用于在 MAC 层之上做多跳转发——不过在 Thread 中,多跳主要由网络层路由完成,Mesh Header 使用较少。

三、Thread 网络层与路由机制

Thread 网络层基于 IPv6,并定义了三种设备角色:Leader、Router、REED(Router-Eligible End Device)以及 Sleepy End Device。Leader 负责分配 Router ID、维护网络数据(Network Data),但不承担数据转发中心角色;Router 组成网状骨干,负责转发;REED 在需要时升级为 Router;Sleepy End Device 通常以子节点身份挂在某个父节点下,大部分时间休眠。

路由机制上,Thread 使用按需距离矢量路由的变体。每个 Router 维护到其他 Router 的下一跳信息,路由开销通过 MLE(Mesh Link Establishment)协议交换。当节点需要发送数据时,若目的地址不在邻居表中,会触发路由发现。Thread 还定义了“双向链路质量”指标,用于选择更优路径。对于 Sleepy End Device,数据不直接路由到它,而是先送到其父节点缓存,等子节点轮询时再下发——这是低功耗设计的关键。

网络层还负责地址管理:每个节点拥有 RLOC16(由 Router ID 与子节点 ID 组成)和全局 IPv6 地址。RLOC16 用于网络内部路由,全局地址用于端到端通信。Thread 通过 MLE 和 CoAP 管理网络数据,例如前缀、路由表、服务注册等。

四、UDP 与 CoAP:传输与应用

Thread 传输层主要使用 UDP。UDP 无连接、开销小,适合低功耗设备。Thread 定义了标准端口:MLE 使用 UDP 19788,CoAP 使用 UDP 5683(安全 CoAP 为 5684)。

CoAP(RFC 7252)是受限应用协议,采用请求/响应模型,方法有 GET、POST、PUT、DELETE,响应码类似 HTTP。CoAP 报文为二进制格式,头部仅 4 字节,支持 Confirmable(CON)与 Non-confirmable(NON)消息。Thread 使用 CoAP 进行网络管理,例如地址注册、路由请求、网络数据分发。实际应用中,设备可通过 CoAP 与边界路由器或云端交互。

下面这张图展示了 Thread 协议栈的完整封装关系与数据流方向,从应用层 CoAP 一路向下到 802.15.4 物理层,并标注了各层的关键报头与典型开销,便于在抓包时逐层对照。

Thread 协议栈封装与数据流 应用数据自上而下逐层封装,自下而上逐层解封装 CoAP / 应用层 方法 GET/POST/PUT/DELETE · CON/NON · 端口 5683/5684 4B 头 UDP 传输层 无连接 · 端口 19788(MLE) / 5683(CoAP) · 校验和 8B 头 6LoWPAN 适配层 IPHC 报头压缩 · FRAG1/FRAG2 分片重组 · Mesh Header 压缩后 6B 左右 Thread 网络层(IPv6 + MLE) RLOC16 路由 · 路由发现 · 网络数据 · 地址管理 IPv6 40B(压缩前) IEEE 802.15.4 MAC 层 CSMA/CA · 帧控制 · 序列号 · 短地址/扩展地址 · FCS 最大 127B PSDU IEEE 802.15.4 物理层 2.4GHz · 信道 11~26 · O-QPSK/DSSS · 250kbps 前导码+SFD+长度 封装(发送) 解封装(接收) 关键约束: 802.15.4 单帧 PSDU ≤ 127B → 6LoWPAN 必须压缩 IPv6/UDP 报头(48B → ~6B)并对超长包分片;Thread 多跳由网络层完成,Mesh Header 使用较少。

五、封装结构对照与抓包参考

为了把上面的层次关系落到可操作的层面,下面给出一份典型的 Thread 数据帧封装结构参考。假设一个节点通过 CoAP 向边界路由器发送一条 GET 请求,路径为单跳,使用短地址寻址。各层封装顺序与典型字节数如下(示例值,实际随压缩情况变化):

应用数据: CoAP GET /status  (约 20B)
  ↓
UDP 头: 源端口 5683, 目的端口 5683, 长度, 校验和  (8B)
  ↓
IPv6 头: 版本/流量类别/跳数限制/源地址/目的地址  (40B, 压缩前)
  ↓
6LoWPAN IPHC: 压缩 IPv6+UDP 报头  (约 6B)
  ↓
MAC 帧: 帧控制(2B) + 序列号(1B) + PAN ID(2B) + 目的短地址(2B) + 源短地址(2B) + FCS(2B)
  ↓
PHY: 前导码(4B) + SFD(1B) + 长度(1B) + PSDU(≤127B)

在抓包工具(如 Wireshark 配合 802.15.4 嗅探器)中,可以按这个顺序逐层展开:先看到 802.15.4 帧头,再看到 6LoWPAN 的 IPHC 压缩字段,接着是解压后的 IPv6 与 UDP,最后是 CoAP 报文。判断压缩是否生效,可以观察 IPHC 字段中的 CID、SAC、SAM、DAM 等标志位;判断是否分片,则看是否存在 FRAG1/FRAG2 报头以及 datagram tag 是否一致。

实践提示:Thread 网络中,MLE 消息使用 UDP 19788 端口,CoAP 使用 5683。若抓包时只看到 802.15.4 帧却无法解析上层,通常是因为没有提供网络密钥或没有正确配置 6LoWPAN 上下文。建议先在实验室用固定信道(如信道 15)和已知 PAN ID 搭建最小网络,再逐步加入节点观察路由建立过程。

六、小结与关键判断依据

Thread 协议栈的分层设计让每一层职责清晰:物理层与 MAC 层解决“怎么在无线信道上可靠传一帧”,6LoWPAN 解决“IPv6 怎么塞进小帧”,网络层解决“多跳怎么走、地址怎么管”,UDP 与 CoAP 解决“应用怎么交互”。在实际工程中,遇到通信异常时,可以按这个顺序逐层排查:先确认物理层信道与速率是否匹配,再检查 MAC 层地址与 PAN ID 是否正确,然后看 6LoWPAN 压缩与分片是否正常,最后检查网络层路由是否收敛、UDP 端口与 CoAP 报文是否符合预期。掌握这条封装链,就掌握了 Thread 网络排障的主干路径。