方法论:网络协议设计的通用方法
文章目录
一、前言
本人做过多年嵌入式软件开发,使用过不少通信协议比如:modbus,mavlink,mqtt,capwap协议等,这些协议都有一些共同点,可以参考这些协议总结协议设计现在方法论。
- 帧格式(3种字段)
3种必要字段:tlv,crc,设备id/地址等设备标识。
2种可选:flag能力集合协商,version版本协议兼容性。
- 通信流程(7个阶段)
协议交互流程主要有7个过程:发现,握手,认证,数据通信,保活,加密,重传。
- 设计点
-
使用tlv格式用于扩展,报文头部type字段报文类型,length表征报文长度,用于接收端分配buf。
-
链路带宽小的场景,协议层不做重传,由应用层做重传,若协议层做重传则会导致拥塞严重。
-
设备标识和路由:多级id列表用于接收端索引消息处理函数callback,比如:设备标识id,模块id,msg id。
-
报文完整性使用crc检验。
-
报文安全性:通常由认证和加密实现,嵌入式常用认证方式可以采用challenge机制。加密可以使用ssl协议,但是ssl需考虑证书过期的问题,可以选择定期交换密钥,以及AES加密CPU消耗比较高,需硬件支持。
-
协议兼容性:msg id要有前瞻性,使用2bye,65535个msg,方便后面扩展。定义version字段,实现前向兼容。
-
通信方式是:P2P还是P2MP,以及是否需要中间路由,设备角色定义等。
-
publish/subscribe模型,还是选择cs模型。
完整协议设计考量见下文。
二、协议设计核心目标
-
可靠性:数据不丢、不错、不乱序(按需)
-
效率:头部开销小,传输效率高
-
安全性:防窃听、防篡改、防重放
-
可扩展:版本兼容、字段可扩、业务可增
三、协议流程交互(生命周期)
| 阶段 | 关键设计点 | 补充说明 |
|---|---|---|
| 1. 发现 | 广播/组播发现、被动监听、服务声明 | 在局域网内用 UDP 广播,可包含协议版本、能力标识 |
| 2. 握手 | 协议版本协商、参数协商(MTU、心跳间隔、加密算法) | 可支持“版本降级”兼容,避免连接失败 |
| 3. 认证 | Challenge-Response(如 HMAC-SHA256)、Token 机制、证书双向认证 | 避免密码明文传输;可支持多级认证(设备级+用户级) |
| 4. 数据通信 | 分片/重组、流控、QoS、确认机制 | 区分命令型报文(需确认)和推送型报文(可丢失) |
| 5. 保活 | 双向心跳、自动重连、连接健康度检测 | 心跳可携带轻度状态信息(如CPU占用、信号强度) |
| 6. 加密 | 链路加密(TLS/DTLS)或载荷加密(AES-GCM) | 资源受限设备可用 ChaCha20-Poly1305(比 AES 轻量) |
| 7. 重传 | 选择性重传、超时与拥塞避免、去重机制 | 带宽受限场景一般不使用协议层重传,使用应用层重传。 |
四、帧格式设计(通用头部建议)
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
┌───────────────────────────────────────────────────────────────┐
│ Magic(2B) │Version│Flags │ Type/Message ID(2B) │
├───────────────────────────────────────────────────────────────┤
│ Length(2B) │ Sequence ID(2B) │
├───────────────────────────────────────────────────────────────┤
│ Source ID(4B) │ Destination ID(4B) │
├───────────────────────────────────────────────────────────────┤
│ Timestamp / Fragment │
├───────────────────────────────────────────────────────────────┤
│ Payload(变长) │
├───────────────────────────────────────────────────────────────┤
│ CRC32 / Checksum(4B) │
└───────────────────────────────────────────────────────────────┘
字段说明:
-
Magic:固定魔数,用于快速识别数据帧开始,也可用于字节对齐。
-
Version:4bit 主版本 + 4bit 次版本,主版本不兼容时需断开,次版本可向后兼容。
-
Flags:8bit 标志位,例如:
ACK``FRAG``ENCRYPTED``COMPRESSED``REQUEST``RESPONSE``BROADCAST -
Type/Message ID:消息类型编号,预留 0xFF00-0xFFFF 为厂商自定义。
-
Length:整个帧的长度(含头部)。
-
Sequence ID:用于请求-响应匹配,或报文去重。
-
Source/Destination ID:支持层级寻址,例如:
[系统ID:设备ID:模块ID]。 -
Timestamp/Fragment:可用于分片偏移量,或毫秒级时间戳(用于延迟计算)。
-
CRC/Checksum:校验范围建议包含头部,防止头部篡改。
五、TLV 扩展设计
struct tlv {
uint16_t tag; // 高 2bit 表示类型(基本/扩展/厂商/保留)
uint16_t length; // 仅 value 长度
uint8_t value[];
};
-
Tag 设计:高 2bit 定义作用域,便于解析器跳过未知 TLV。
-
嵌套 TLV:可用于复杂结构,但会增加解析复杂度。
六、QoS 分级设计
| 等级 | 确认机制 | 重传次数 | 适用场景 |
|---|---|---|---|
| QoS0 | 无确认 | 0 | 传感器数据(允许丢包) |
| QoS1 | 确认机制 | 1-2 | 控制命令、参数设置 |
| QoS2 | 双向握手 | 3 | 固件升级、关键配置 |
| QoS3 | 端到端应用层确认 | 可配置 | 跨网关重要数据 |
七、安全设计
- 密钥交换:
-
首次连接可使用 Diffie-Hellman 交换临时密钥。
-
长期密钥预置,定期更新(如每小时更换会话密钥)。
- 防重放:
- 序列号 + 时间戳窗口验证。
- 设备身份:
- 可使用设备唯一证书(如 ECC 证书),或芯片唯一 ID 派生密钥。
7.1 认证方式选择
嵌入式领域通常选择如下认证方式,主要通过两种方式认证:
1、验证数据:通过交互数据,验证比如SN码、ID、密码等正确性。
2、通过算法验证:比如哈希算法,challenge机制等都是通过算法校验。
常用的认证方式:
1、使用SN码、MAC等白名单方式,协议设计简单。
2、challenge挑战机制:服务器下发nonce,然后客户端使用哈希+nonce等以及本地的密码或者SN信息生成摘要数据发给服务器,由服务器使用相同方式校验结果。使用相同算法+密钥来认证。服务器和客户端都要配置密钥信息,算法是出厂预设。
3、PSK:预先共享密钥,服务器和客户端都配置相同密钥,预先共享给客户端,客户端配置密钥,常用于WIFI的认证方式。
4、报文级签名:MAVLINK的认证机制,使用固定的签名算法对报文生成摘要字段,只有通信双方知道密钥,才可以认证通过。
八、业务模型与路由
| 模型 | 寻址方式 | 适用场景 |
|---|---|---|
| C/S 模型 | 目标设备 ID + 服务端口 | 集中控制、数据采集 |
| Pub/Sub | Topic 路由(可包含通配符) | 多对多消息分发、事件通知 |
| P2P 直连 | 双方地址直接交换 | 设备间直接通信,低延迟 |
| 网关路由 | 目标地址 = 网关ID + 设备ID | 跨网段、跨协议转发 |
建议:协议设计时可将寻址字段抽象为“目标地址列表”,支持多层路由。
九、其他重要考量点
1. 资源与性能平衡
-
内存小的设备避免复杂重传逻辑,可交给上层。
-
带宽小时启用头部压缩(如 Delta Encoding)。
-
CPU 弱时避免高强度加密,可硬件加速或降低加密频率。
2. 升级与兼容
-
版本号明确,旧版本设备可安全降级通信。
-
设计“能力协商”阶段,双方交换支持的功能列表。
-
保留足够的 Message ID 和标志位供未来使用。
3. 错误处理
-
定义标准错误码(设备忙、内存不足、参数无效等)。
-
错误响应可携带错误详情 TLV。
4. 分片与重组
-
若支持分片,需在头部设计分片标志、总分片数、当前分片索引。
-
重组超时时间建议可配置。
九、建议设计流程
-
明确场景:确定设备能力、网络环境、业务模型。
-
定义消息:列出所有业务报文,归类为命令、数据、事件、响应。
-
设计帧结构:基于上述通用头部,按需删减字段。
-
画状态机:绘制协议各阶段的状态转换图,包括异常处理。
-
写文档:定义每个字段、每个消息的详细格式与语义。
-
实现样例:先实现 PC 端模拟器,再移植到嵌入式。
-
测试:重点测试网络异常(丢包、乱序、重复、延迟)下的行为。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)