当前位置: 首页 > news >正文

从帧边界识别到数据编码:嵌入式通信协议与数据序列化方案深度对比

帧格式

定义消息的边界和基本结构,确保接收端能完整提取一帧数据。主要用于“ 一条消息的边界 ”识别。帧格式在外层,定义报文头、长度、类型。

TLV (Type-Length-Value)

TLV 是一种常用的数据编码格式:

- T (Type):字段类型,表示这段数据的含义	
- L (Length):数据长度,表示这段数据有多长
- V (Value):具体的数据内容

它的核心目标是:

- 在字节流中自描述每一段数据的类型和长度
- 方便灵活扩展,新增字段不会破坏旧协议

基本结构:

TypeLengthValue
1字节2字节Length字节数据

Type:通常 1 个字节(可以扩展到 2 字节)
Length:表示 Value 的字节数,常用 1–2 字节

Value:实际数据,可以是字符串、数值、二进制块等

LV (Length-Value)

LV (Length-Value) 是一种非常简单的帧格式:

- L (Length):表示数据长度
- V (Value):实际数据内容

它的主要功能是解决帧边界问题,让接收端知道一帧数据从哪里开始、在哪里结束。
基本结构:

LengthValue
2字节Length字节数据

Length:通常 1–2 个字节,表示 Value 的字节数
Value:实际传输的数据,长度由 Length 决定

Delimited

Delimited(分隔符帧格式)指的是用特定的分隔符(Delimiter)标记一帧数据的开始或结束,从而让接收端知道一条消息在哪里结束,下一条从哪里开始。常见分隔符如下:

- 文本协议:"\n"、"\r\n"(如 HTTP 请求头、CSV 文件)
- 二进制协议:特定字节 0x7E(如 HDLC 协议用 0x7E 标记帧边界)

基本结构:

[ Data1 ] D

[ Data2 ] D

[ Data3 ] D

Data:一帧数据

D (Delimiter):分隔符,标记帧的边界

帧格式总结

帧结构优点缺点串口适配性典型场景
Delimited实现最简单,用分隔符标记帧尾需要转义,数据不能含分隔符适合简单命令传输文本协议、简单 AT 命令
LV低开销,解析简单,性能好不能灵活扩展,字段固定适合固定结构数据Modbus RTU、gRPC Frame
TLV自描述性强,灵活,易扩展帧头比 LV 稍大,解析略复杂适合复杂、可扩展协议BLE GATT、SNMP、IoT 自定义协议

根据不同的应用场景有不同的选择:

需求场景推荐帧结构原因
只传输简单命令或文本数据Delimited实现简单,调试方便
固定字段、性能优先LV长度前缀+负载,结构简单
多字段、未来可能扩展TLVType+Length+Value 自描述灵活
二进制+高可靠+复杂协议TLV + CRC 校验易扩展、可校验数据完整性

在工业控制、物联网里,常用的组合是:

[ 起始符 ] + [ 长度 ] + [ Type ] + [ Value ] + [ CRC ]

  • 起始符:标记帧开始,避免同步丢失
  • 长度:明确帧结束位置
  • Type+Value:支持多字段、可扩展
  • CRC:保证数据可靠

这样结合了 Delimited + LV + TLV 的优点,最通用,也最安全

数据序列化方案

定义帧内有效载荷数据如何编码成字节流,保证结构化数据可传输。将内存中的结构化数据(如对象、数组、字典等)转换为可存储、可传输的线性格式(通常是二进制流或文本字符串)的过程。

JSON

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式, 基于键值对(key-value)表示数据 ,广泛用于前后端通信、配置文件、存储和物联网等场景。

示例:

{"name": "Alice","age": 30,"isStudent": false,"scores": [95, 82, 77],"address": {"city": "New York","zip": "10001"}
}

优点:

  • 易于阅读和调试
  • 跨语言支持广泛
  • 与 JavaScript 原生对象映射简单

缺点:

  • 体积较大:冗余键名,传输效率低
  • 解析速度较慢:文本解析比二进制慢
  • 类型有限:没有二进制数据类型,需要编码(如 Base64)
  • 无严格 Schema:容易出现字段缺失或类型不匹配问题

BSON

BSON一种基于 JSON 语法设计的二进制数据格式,最早由 MongoDB 推出,核心目标是解决 JSON 文本格式在数据传输和存储中的效率问题(如体积过大、解析速度慢)。与纯文本的 JSON 不同,BSON 通过二进制编码优化了数据存储结构,同时保留了 JSON 的 “键值对” 核心逻辑,兼顾了可读性(可解析为 JSON)和性能。

支持数据类型:

BSON 类型对应 JSON 类型说明
DoubleNumber (浮点)64 位浮点数
StringStringUTF-8 编码
ObjectObject嵌套文档
ArrayArray有序列表
Binary data-原生二进制数据
ObjectId-MongoDB 特有唯一 ID
BooleanBooleantrue/false
Date-64 位整数,表示 UTC 时间戳
NullNull空值
Int32Number32 位整数
Int64Number64 位整数
Decimal128Number高精度浮点数

示例:

{"name": "Alice","age": 30,"isStudent": true
}

对应的 BSON 结构:

1D 00 00 00

02 6E 61 6D 65 00 06 00 00 00 41 6C 69 63 65 00

10 61 67 65 00 1E 00 00 00

08 69 73 53 74 75 64 65 6E 74 00 01

00

字段类型内容
文档长度Int321D 00 00 00 (29 bytes)
name 字段String (0x02)02(type) 6E 61 6D 65 00(key="name"+null结束) 06 00 00 00(len) 41 6C 69 63 65(value="Alice") 00(null结束符)
age 字段Int32 (0x10)10 61 67 65 00 1E 00 00 00 (30 decimal = 0x1E)
isStudentBoolean (0x08)08 69 73 53 74 75 64 65 6E 74 00 01 (true = 0x01)
文档结尾-00

优点:

  • 支持更多类型(Date、Binary、Int64 等)
  • 内部存储和传输高效
  • 易于与 MongoDB 集成

缺点:

  • 不可读:不适合直接调试
  • 体积可能比 JSON 大:尤其是短字符串或小对象时,类型前缀会增加额外字节
  • 依赖特定库解析(如 PyMongo、bson.js)

CBOR

CBOR(Concise Binary Object Representation,简洁二进制对象表示)是一种轻量级、高效的二进制数据序列化格式,由 IETF 标准化(RFC 8949),设计目标是成为 “二进制版的 JSON”—— 既保留 JSON 的灵活性和兼容性,又通过二进制编码解决 JSON 体积大、解析慢的问题。

数据类型:

JSON 类型CBOR 类型说明
ObjectMap (5)完全对应,CBOR 更紧凑,可嵌套
ArrayArray (4)对应,长度编码更紧凑
StringUTF-8 String (3)对应,长度可直接编码
NumberUnsigned/Negative Int (0/1) 或 Float (7)CBOR 可表示大整数和各种浮点数
BooleanSimple type (7)true → F5, false → F4
NullSimple type (7)null → F6
二进制数据Byte String (2)JSON 不支持,CBOR 原生支持
日期/时间Tag (6) + valueJSON 用字符串,CBOR 可直接用 Tag 0/1 表示
大整数Tag 2/3 + valueJSON 没有原生类型,需要字符串

示例:

{"name": "Alice","age": 30,"isStudent": true,"scores": [95, 82, 77],"profile_pic": "<binary_data>"
}

CBOR 编码规则

对象 → Map → Major type 5

文档 5 个键值对 → 0xA5

字符串 → Major type 3

长度直接编码在初始字节

整数 → Major type 0

小于 24 → 初始字节直接编码

大于 23 → 0x18 + 值

布尔 → Major type 7

true → 0xF5

数组 → Major type 4

长度 3 → 0x83

二进制 → Major type 2

假设长度 4 → 0x44 + 4 字节数据

A5                                   # Map, 5 键值对63 6E 61 6D 65                        # key: "name", 长度 3
65 41 6C 69 63 65                      # value: "Alice", 长度 563 61 67 65                             # key: "age", 长度 3
18 1E                                   # value: 3069 69 73 53 74 75 64 65 6E 74           # key: "isStudent", 长度 9
F5                                      # value: true66 73 63 6F 72 65 73                    # key: "scores", 长度 6
83 18 5F 18 52 18 4D                     # array [95, 82, 77]  
# 950x5F, 820x52, 770x4D, 小于 240x18 前缀6B 70 72 6F 66 69 6C 65 5F 70 69 63     # key: "profile_pic", 长度 11
44 FF D8 FF E0                             # Byte string, 长度 4, 数据示例: FF D8 FF E0

优点:

  • 二进制,紧凑高效
  • 支持丰富类型(整数、浮点、二进制、标签)
  • 可扩展
  • 与 JSON 结构兼容

缺点:

  • 不可读(需工具解析)
  • 生态比 JSON、Protobuf 少一些

Protocol Buffer

https://protobuf.dev/?utm_source=chatgpt.com

Protocol Buffer(简称 Protobuf)是 Google 开发的一种高效的二进制数据序列化格式,旨在替代 XML、JSON 等文本格式,用于数据存储和网络传输。它的核心优势在于体积小、解析快、跨语言支持好,尤其适合高性能场景。

数据类型:

类型描述对应 JSON 类型
double64 位浮点Number
float32 位浮点Number
int3232 位有符号整数Number
int6464 位有符号整数Number
uint3232 位无符号整数Number
uint6464 位无符号整数Number
sint3232 位有符号整数,zig-zag 编码Number
sint6464 位有符号整数,zig-zag 编码Number
fixed32固定长度 32 位整数Number
fixed64固定长度 64 位整数Number
sfixed32固定长度有符号 32 位整数Number
sfixed64固定长度有符号 64 位整数Number
bool布尔值Boolean
stringUTF-8 字符串String
bytes原始二进制Byte string
enum枚举String/Number
message嵌套消息Object
repeated重复字段Array
map<K,V>Map / 字典Object

示例:

{"name": "Alice","age": 30,"isStudent": true,"scores": [95, 82, 77]
}
syntax = "proto3";message Student {string name = 1;int32 age = 2;bool isStudent = 3;repeated int32 scores = 4;
}
FieldTagWire Type内容说明
name12“Alice”length-delimited
age2030varint
isStudent30truevarint (1)
scores4095, 82, 77repeated varint
0a 05 41 6c 69 63 65   # field 1: name, length 5, value "Alice"
10 1e                   # field 2: age = 30
18 01                   # field 3: isStudent = true
20 5f 20 52 20 4d       # field 4: scores = 95, 82, 77

优点:

优点说明
高效紧凑Protobuf 使用二进制编码,不存字段名,整数采用 varint 压缩,整体比 JSON/CBOR/BSON 更小。
跨语言官方支持 C++, Java, Python, Go, C#, JavaScript 等多种语言,可轻松实现跨语言通信。
类型安全每个字段都有明确类型(int32、string、bool 等),避免类型歧义。
向后/向前兼容可以新增字段而不破坏旧版本数据(未定义字段会被忽略),非常适合分布式系统升级。
支持嵌套消息和复杂结构支持数组(repeated)、嵌套消息(message)、Map 等复杂数据结构。
可生成代码可以根据 .proto 文件自动生成各种语言的类,减少手写序列化/反序列化工作量。
广泛应用gRPC、微服务、IoT 数据通信等大规模系统广泛采用。

缺点:

缺点说明
不可读二进制编码,调试或人工查看不方便,需要工具解析。
需要编译生成代码必须通过 protoc 或相关插件生成对应语言的类文件,增加编译步骤。
不支持动态字段名与 JSON 不同,Protobuf 不存储字段名,只能通过 tag 访问字段,灵活性低。
学习成本需要学习 .proto 文件语法、tag 规则、wire type 等概念。
不直接支持 JSON 的某些特性如直接存储 null 或任意嵌套 Map,虽然可以通过 message/optional/fallback 实现,但不如 JSON 灵活。
扩展类型有限不像 CBOR 可以自由扩展自定义标签,需要提前定义 message 或 enum。

MessagePack

MessagePack 是一种高效的二进制数据序列化格式,核心设计理念是 “像 JSON 一样简单,但比 JSON 更快、更小”。它旨在保留 JSON 的灵活性(无 Schema 约束、支持常见数据结构),同时通过二进制编码解决 JSON 文本格式 “体积大、解析慢” 的问题,广泛应用于跨语言通信、数据存储等场景。

数据类型:

类型描述对应 JSON 类型
nil空值null
booltrue / falseBoolean
int有符号整数Number
uint无符号整数Number
float32/64 位浮点数Number
strUTF-8 字符串String
bin二进制数据无(JSON 不支持)
array有序列表Array
map键值对Object
ext扩展类型自定义类型(日期、UUID 等)

示例

{"name": "Alice","age": 30,"isStudent": true,"scores": [95, 82, 77]
}
84                        # map, 4 键值对a4 6e 61 6d 65             # key: "name", fixstr 4
a5 41 6c 69 63 65           # value: "Alice", fixstr 5a3 61 67 65                 # key: "age", fixstr 3
1e                          # value: 30 (positive fixint)a9 69 73 53 74 75 64 65 6e 74 # key: "isStudent", fixstr 9
c3                          # value: truea6 73 63 6f 72 65 73        # key: "scores", fixstr 6
93 5f 52 4d                 # array of 3 elements: 95, 82, 77

优点:

优点说明
紧凑高效二进制编码,比 JSON 小 30–70% 空间
与 JSON 兼容数据模型一致,易于理解
支持二进制原生支持 bin 类型
支持数组、Map、嵌套与 JSON 完全兼容
可扩展支持 ext 类型,如 UUID、日期、自定义对象
跨语言Python、Go、C++、JavaScript 等都有库

缺点:

缺点说明
不可读二进制格式,调试需工具
类型不严格没有像 Protobuf 那样的强类型检查
向后兼容有限新增字段可能被旧版本忽略,但没有严格的 tag 机制
浮点数/大整数精度需要注意超大整数可能超出 JS Number 精度

选择

各个方案优缺点对比

特性JSONBSONCBORProtocol BuffersMessagePack
数据格式文本二进制二进制二进制二进制
可读性
紧凑性
类型安全部分
支持二进制
扩展类型MongoDB 特定类型✅(Tag)✅(自定义 message/enum)✅(ext)
嵌套/数组
向后兼容可能可能有限
跨语言
典型应用配置文件、Web APIMongoDB 存储IoT、低带宽网络gRPC、微服务通信、IoT高性能网络通信、缓存、IoT

选择原则如下:

场景推荐方案说明
可读性优先 / 调试 / 配置文件JSON易于编辑、调试,跨语言方便
数据库存储(MongoDB 原生)BSONMongoDB 内部使用,支持二进制存储
低带宽 IoT / 二进制传输 / 嵌套数据CBOR / MessagePack紧凑,高效,支持嵌套和扩展类型
高性能微服务 / 跨语言 RPCProtocol Buffers强类型、紧凑、向后兼容,适合 gRPC 或 IoT 高性能通信
轻量级网络通信 / 缓存MessagePack与 JSON 数据模型一致,序列化快,二进制紧凑
需要扩展类型(日期/UUID 等)CBOR / MessagePack原生支持扩展类型,不用额外字段约定

选择数据序列化方案应根据场景权衡:JSON 可读性高、易调试,适合配置和 Web API;BSON 适合 MongoDB 存储,支持二进制;CBOR 与 MessagePack 紧凑高效,适合低带宽或 IoT 通信,且支持扩展类型;Protocol Buffers 则强类型、向后兼容、跨语言高性能,适合微服务或大规模网络通信。总之,可读性优先选 JSON,二进制紧凑优先选 CBOR/MessagePack/Protobuf,严格类型与跨语言要求选 Protobuf。

http://www.dtcms.com/a/456667.html

相关文章:

  • Quick SwiftObjective-C测试框架入门教程
  • GRM tools三大插件使用教程
  • C62-结构体的指针
  • 腾讯云 建网站企业网站seo公司
  • Java-143 深入浅出 MongoDB NoSQL:MongoDB、Redis、HBase、Neo4j应用场景与对比
  • 线程1——javaEE 附面题
  • 吴恩达机器学习课程(PyTorch适配)学习笔记:1.4 模型评估与问题解决
  • 后端_基于注解实现的请求限流
  • 从 0 到 1 搭建 Python 语言 Web UI自动化测试学习系列 10--基础知识 6--元素等待方式和内联框架
  • 织梦网站如何做seo重庆市城市建设档案馆官方网站
  • 一文详解Go语言字符串
  • 通用:MySQL-LBCC并发锁机制
  • Elasticsearch:使用推理端点及语义搜索演示
  • 基于websocket的多用户网页五子棋(九)
  • Async++ 源码分析13--parallel_reduce.h
  • 分布式api调用时间优化和问题排查
  • LeetCode每日一题,20251008
  • h5网站建设的具体内容电子商务平台网站模板
  • hive sql优化基础
  • Linux小课堂: Linux 系统的多面性与 CentOS 下载指南
  • 详解redis,MySQL,mongodb以及各自使用场景
  • 开发网站设计公司建设通网站会员共享密码
  • Linux相关工具vim/gcc/g++/gdb/cgdb的使用详解
  • Verilog和FPGA的自学笔记2——点亮LED
  • uniapp创建ts项目tsconfig.json报错的问题
  • Linux性能调优之内核网络栈发包收包认知
  • 静态网站挂马u钙网logo设计影视剪辑
  • Rust 基础语法指南
  • C11 安全字符串转整数函数详解:atoi_s、atol_s、strtol_s 与 strtoimax_s
  • 从入门到实战:全面解析Protobuf的安装配置、语法规范与高级应用——手把手教你用Protobuf实现高效数据序列化与跨语言通信