物联网通信的时候,二进制翻译解析,是始终绕不开的。而且有时候,由于平台端字段的改动,导致一些二进制编解码的字段,要跟着修改。这种改动,有时候会带来意想不到的错误。
而且,编码解码有着大量重复的逻辑,解析的基本都是基本类型,Int,String,Float,Double等等,只不过解析的组合排列顺序不一样、组合排列顺序的不一致,也是由于解析顺序的不一致!
假设,我们得到字段的解析顺序,字段的解析类型,以这个作为参数,我们是否就可以得到,解析数据的值呢?
项目地址:大衍物联: 这个框架的主要作用是解析各种协议!在数据解析中,有不同的协议类型。使用责任链模式,解析出不同的协议报文,并搭配使用,我在modbus中,解析出两种帧数据,一种是注册帧,注册帧内的设备id和设备通道绑定,一种是数据帧,数据帧里能得到设备通道信息,进而得到注册的设备id,根据设备id收发信息!获取完整一帧之后,要转化成model数据,我使用注解,参考FastJson,直接解码成对应的数据。
以基本类型为准,解码和编码的有Int,Double,Float,String,byte,Long,Boolean。有些解码和编码含有帧中帧,但这些帧中帧内,还是Int,Double,Float,String,byte,Long,Boolean。我们画图如下:
Frame代表帧,Field代表字段,字段类型可以为Int,Double,Float,String,byte,Long,Boolean。
可以根据树结构,进行深度遍历算法,完成整个字段的装载!代码如下:
得到所有的待解析,待编码字段!
命令格式
SOP |
LEN |
CMD |
SESSION_ID |
DATA |
SUM |
SOP: |
单字节字头。命令为 ee,应答为66 。 |
LEN: |
单字节。从CMD到SUM的字节数(含CMD和SUM) |
CMD: SESSION_ID: |
单字节,命令字节。 服务端回话编号,6个字节,用户服务端识别通讯会话。如果服务端发起的会话设备应答服务端需要带上服务端下发的会话ID。如果设备发起会话则会话ID为“000000” |
DATA: |
数据字节,不定长。 |
SUM: |
单字节,LEN、CMD、SESSION_ID、DATA的异或值 |
从这个协议,我们可以分析,他是一个两层协议,外层包裹帧头,帧尾,长度,指令,会话,数据,和校验位。内层是需要传输的宝贵数据!
我们对应的物理模型如下:
编码的话,因为一些数据需要计算获得,所以计算如下:
解码按顺序解析即可,不需要额外的计算。
1.读取设备每个端口的状态
服务器读取设备每个端口当前的状态。
数据方向:
模块——设备
命令:
CMD |
0x01 |
数据(上面表示数据含义,下面表示示例数据):
NULL |
0x00 |
参数 |
是否必填 |
说明 |
NULL |
是 |
固定为0x00 |
回复数据(上面表示数据含义,下面表示示例数据):
PORT_NUM |
PORT1_STATUS |
PORT2_STATUS |
… |
0x03 |
0x02 |
0x01 |
… |
参数 |
是否必填 |
说明 |
PORT_NUM |
是 |
设备端口数量 |
PORT_STATUS |
是 |
端口状态: 0x01:端口空闲;0x02:端口正在使用;0x03:端口禁用;0x04:端口故障。 |
示例:模块发送:(EE)(sop) (09) (len) (01)(cmd) (00 00 00 00 00 00)(session) (00)(data) (08)(sum)
模块接收:(66) (sop) (13)(len) (01)(cmd) ( 00 00 00 00 00 00)(session) (0A 02 01 01 01 01 01 01 01 01 01)(data)(1B)(sum) (1端口正在充电,其他端口空闲 )
剥离出外层,数据部分如下:
示例:模块发送: 00
模块接收: 0A 02 01 01 01 01 01 01 01 01 01
编码模型:
Len = 1,代表编码生成的二进制数组长度为1。默认编码字段为Integer类型!
解码模型:
Sequence 代码解析顺序,从小到大排序!从数值可知,先解析端口数量,再解析端口状态。
Port_num 注解含义是,解析类型为byte,字段解析顺序为1,按长度解析,长度参数为1,代表一个byte长度。
States 注解含义是,解析类型为byte数组,字段解析顺序为2,按长度解析,直到数组最后一位
Controller层代码如下: