文章目录
通讯协议制定之数据包结构介绍
1. 前言
通讯协议
又称通信规程,是指通信双方对数据传送控制的一种约定,约定中包括对数据格式
,同步方式
,传送速度
,传送步骤
,检纠错方式
以及控制字符定义
等问题做出统一规定,通信双方必须共同遵守,它也叫做链路控制规程
- 根据项目中的实际应用,本人总结了嵌入式开发中通讯协议制定的相关考虑因素和经验技巧,具体包含如下内容,可供参考学习了解 ( 介绍中阐述的相关术语使用了开发交流沟通中的讲法,可能存在说法不同;因本人技术水平有限,分享创作的内容可能存在不合理的地方,欢迎相互交流沟通、批评指正)
- 通讯协议制定之前言、背景介绍
- 通讯协议制定之交互方式、步骤介绍
- 通讯协议制定之数据包结构介绍
- 通讯协议制定之数据传输类型及传输规则介绍
- 通讯协议制定之数据消息传输方式介绍
- 通讯协议制定之数据包校验算法介绍
- 通讯协议制定之常见问题、注意事项总结
- 在上一篇《 通讯协议制定之交互方式、步骤介绍》中,从发送数据方式,发送步骤方面,介绍了通信的
周期发送
和事件发送
,以及握手、心跳、数据包
交互方式步骤;那么不同的通信数据包如何区分、传输的具体数据内容格式如何规定?本文介绍将解决这些疑问,详细的介绍数据包的结构如何规定,以及各部分结构的作用和相关注意事项。
2. 数据包结构
- 数据层的协议格式和物理层的帧格式定义原理基本相同,即规定好数据传输的
起始符
,各个字段指定的含义
,各个字段的字节长度
等信息内容 - 如下示例为一个实际开发项目中规定的数据包结构示意图,接来下会详细介绍各字段的规定、作用、含义等内容
- 各字段的定义,建议长度字节数和说明汇总如下:
字段定义 | 字节长度 | 说明 |
---|---|---|
起始符 | 2字节 | 数据包的帧头,标志着数据包的起始位置 |
传输方向 | 1字节 | 定义数据传输的方向,用于区分数据流的流向 |
加密信息 | 1字节 | 指示后面的数据字段是否经过加密 |
数据长度 | 2字节 | 用来确定后续传输数据的总长度 |
消息版本号 | 2字节 | 用于确定通信双方传输的数据协议一致性 |
消息编号 | 2字节 | 标记数据流的顺序 |
消息操作类型 | 1字节 | 标记业务数据流的操作特性 |
消息业务类型 | 2字节 | 通信双方可自行约定相应业务类型的数值定义 |
消息数据 | n字节 | 通信传输的交互数据 |
结束符 | 2字节 | 数据包的帧尾,标志着数据包的结束位置 |
检验码 | 2字节 | 对传输数据通过某种检验算法得到结果 |
2.1 数据包起始符
起始字符
,即数据包的帧头
,标志着数据包的起始位置;接收方处理解析数据时,查找到起始字符后,依次按照数据包结构开始解析- 起始字符一般规定
2~4字节
,可采用固定的ASCII字符,比如规定起始字符为2个字节的字符"DF"
,对应16进制数0x44 0x46
起始字符
是必不可少的
2.2 数据包方向
数据包方向
:定义数据传输的方向,用于区分数据流的流向- 数据包方向规定
1字节
即可,比如:A —> B
使用0xA1
,B —> A
使用0xA2
- 使用场景:
- 为了方便对数据流进行分析,可以通过查看该字段,确定数据流流向
- 在本项目中,通信的一方通过业务区分成了:
B模块
,C模块
,那么可以根据数据包方向,规定A —> B
使用0xA1
,B —> A
使用0xA2
,A —> C
使用0xB1
,C —> A
使用0xB2
,来快速区分业务流 - 之前还有一个项目,不同的零件厂家使用了同一个通信协议,为了区分不同的零件厂家,通过使用该字段的含义来区分
- 数据包方向字段并不是必须的,可根据实际需要来确定
2.3 数据包加密信息
加密信息
:用于指示后面的数据字段是否经过加密,传输的数据是明文还是密文- 加密信息规定
1字节
即可,可规定数值含义:0x00: 消息未加密 0x01: 消息已加密
- 加密信息字段并不是必须的,可根据实际需要来确定,很少使用该字段
2.4 数据包长度
数据包长度
:用来确定后续传输数据的总长度- 数据包长度规定
2字节
,统计的长度一般从长度字段之后的第一个字节数开始,一直统计到结束符前一个字节数据 - 如果协议每次传输的数据长度是固定,没有改变,长度字段可以省略;实际使用中,长度绝对不是固定的,因此该字段是必不可少的
2.5 消息版本号
消息版本号
:用于确定通信双方传输的数据协议一致性- 消息版本号常规定
1~2字节
用来标记协议版本号 - 由于需求的改动必然会导致协议的改动,为了方便知道协议版本等内容,可以根据该字段了解;此外可以有效避免因为协议不一致导致的各种问题,接收方在收到对方发送的数据包时,判断该字段,如果版本号不一致,说明使用的协议不是同一个版本协议
2.6 消息编号
消息编号
:该字段有着多种不同叫法,如流水号
,滚动计数
有着相同的含义,用来标记数据流的顺序- 消息编号常用
1~2字节
来标记,比如使用一个字节标记,则该字段从0开始,每发送一包数据,该值累加 1,达到最大值255后,再次从0开始累加 - 消息编号使用场景:
- 用来标记数据流的顺序,比如通过该字段,可确定数据流的先后顺序;
- 对于之前介绍的周期发送的数据,比如心跳,可以通过该字段的连续性,确保周期发送数据是否存在丢包现象;
- 消息请求方发送,接收方回复的
Ack
或response
报文中,将该字段原值返回,可以用来标记交互过程的完整性
- 消息编号字段并不是必须的,可根据实际需要来确定,建议添加使用该字段
2.7 消息操作类型
- 在《通讯协议制定之交互方式、步骤介绍》中,介绍了数据包可以根据交互步骤时序,分成
通知包
、请求包
、回复包
,应答包
,为了检测标记该操作类型,可以用一个字段来表示 - 消息
操作类型
:用来标记业务数据流的操作特性 - 消息操作类型用
1字节
来标记即可,可规定数值含义:0x00: 通知包 0x01: 请求包 0x02: 回复包 0x03: 应答包
- 消息操作类型字段并不是必须的,可根据实际需要来选择
2.8 消息业务类型
业务类型
:通信双方可自行约定相应业务类型的数值定义,也可以称为服务号
、业务号
- 业务类型常用
2字节
来标记,可以将高字节
作为业务类型主类别
,低字节
作为业务类型子类别
例如:握手和心跳数据,可以规定为是状态管理服务,用高字节0x10
表示状态管理业务,用低字节来区分具体业务子类别,0x01
表示握手,0x02
表示心跳;另外一个业务是远程控制服务,高字节用0x20
来表示远程控制,低字节区分具体的子类别,0x01
:远控车门、0x02
:远控车窗、0x03
:远控天窗
业务类型 | 业务说明 |
---|---|
状态管理 | 0x1001: 握手 0x1002:心跳 |
远程控制 | 0x2001:远控车门 0x2002:远控车窗 0x2003:远控天窗 |
消息业务类型
字段是必不可少,可以根据实际项目需求来制定
2.9 消息数据
消息数据
是通信传输的交互数据,其他字段的规定都是为了保证该字段的传输- 消息数据的具体传输,也有多种规定方式,在之后的《通讯协议制定之数据消息传输方式介绍》中,会介绍消息数据如何规定传输
- 交互数据的传输,还会涉及传输数据的数据类型,不同数据类型如何传输,在之后的《通讯协议制定之数据传输类型及传输规则介绍》会进行介绍
2.10 数据包结束符
结束符
,即数据包的帧尾
,标志着数据包的结束位置- 结束字符一般规定
2~4字节
,可采用固定的ASCII字符,比如规定结束字符为2个字节的字符"DF"
,对应16进制数0x44 0x46
- 不同于起始字符,
结束字符
字段不是必须添加的,因为从起始字符开始后,之后每个字段长度都有明确的规定,没有结束字符也没任何影响
2.11 数据包校验
校验
:在数据的传输过程中,无论使用什么方法,都无法保证100%的传输正确率,总有发生错误的时候,为了确保传输的正确率,会通过校验段
对数据进行校验,来确保数据传输的正确性数据校验
就是通过对发送方持有的数据进行某种运算,对接收方收到的数据也进行同样的运算,并且比较这两个结果,如果结果不一样,肯定是传输过程中发生了错误- 具体的校验算法和相关介绍,会在之后的《通讯协议制定之数据包校验算法介绍》中进行介绍
校验
字段建议必须使用,不然可能造成诸多异常
3. 小结
- 以上介绍的11个字段的内容,可以灵活的根据项目的实际需求来选择使用那些字段,并不是所有字段都需要使用
- 字段放置的先后顺序也并不是一定的,也可以灵活的来进行配置使用
- 在实际项目中,如果涉及到通信模块相关的代码,在尝试看懂代码之前,建议先熟悉了解协议结构后,再去看代码,可以达到事半功倍的效果
感谢阅读 若有错误 欢迎指正 !!!