SL651-2014协议中心站协议解析简单实现

SL651协议数据通过在互联网中发送时可看成是一种应用层协议。本文用框架netty解析了该协议的中心站端的一部分,协议其余部分解析类似。

首先需要了解在SL651协议中的中心站、遥测站、遥测终端设备分别代表是什么。

 参考https://wenku.baidu.com/view/8c524e964793daef5ef7ba0d4a7302768f996f0c.html?_wkts_=1707112839329&bdQuery=%E9%81%A5%E6%B5%8B%E7%AB%99

在SL651-2014规约中建议遥测终端设备和遥测站通信采用的是Modbus-RTU或SDI-12协议。参考
详解Modbus通信协议---清晰易懂-CSDN博客

本文涉及到的是在SL651-2014中定义的遥测站和中心站的通信协议。

1.概要

1.1报文解析

1.1.1编码格式

SL651协议提供了2种编码格式:HEX/BCD编码和ASCII字符编码。本文实现主要基于ASCII字符编码,HEX/BCD编码也简要分析。文中A设备采用了ASCII编码,B设备采用了HEX/BCD编码。

1.1.2数据解析

报文中的主要数据为:帧起始符,中心站地址,遥测站地址,密码,功能码,帧起始符,功能码(报文类型),遥测站分类码,观测时间,监测项,校验码等。

1.1.3数据校验

在SL651协议中提供了数据的校验方式,通过CRC16方式计算正文及之前的所有报文的校验码,再在报文正文后面加上结束符和校验码。在链路层、传输层本身分别也有校验方式。但它们是独立的。

1.2.数据的完整性和通信方式

主要考虑的是半包粘包问题,还有数据校验,通信方式及连接维持方式。

1.2.1通信方式及连接维持方式

首先SL651协议定义了4种中心站和遥测站的通信方式(M1,M2,M3,M4)。其中M1为发送/无回答传输模式。M2为发送/确认传输模式。M3为多包发送/确认传输模式,M4为查询/响应模式。本文是基于M2传输模式。 

在传输层,操作系统的默认保活时间是7200秒。为了保持连接提高效率,在SL651应用层也定义了一些维持连接机制。遥测端会定时发送链路维持报,以保持连接。这样可以在应用层自定义保活时间。本文在应用层简化不做处理,所以保活时间默认是传输层的7200秒。

1.2.2半包粘包

粘包问题在netty中提供了类中已经基本解决了。而半包问题比较复杂,如需开发高效的解决半包问题可以参考netty提供的类io.netty.handler.codec.http.HttpObjectDecoder的处理方式。因为半包发生时一次完整数据可能在任何字节截断。HttpObjectDecoder中对每个解析阶段都定义了一个状态,如遇到半包情况,只需从当前状态解析就可以了,但是编程较复杂。

本文较为简单的处理了半包问题:先创建一个ByteBuf副本,解析一遍数据,在ByteBuf副本读取数据不足时抛出InsufficientDataException异常,不做任何处理。如果解析成功就将原ByteBuf指针设置到ByteBuf副本的位置(等价于原ByteBuf解析了数据)。  遇到其他解析错误的情况,就清空ByteBuf所有数据。以上处理效率不高,如果有多个半包,可能重复解析起始的byte多次,最差的情况下复杂度为O(n^2)。这里水文协议因为一次请求数据不长,所以影响不大。

2.报文解析

2.1编码格式

SL651协议中定义了2种编码格式HEX/BCD编码和ASCII字符编码。SL651规定了在报文的起始字节标识报文属于那种编码格式。ASCII的报文容易理解但较长,在自定义监测项时有较强的扩展性易读性,起始字节01。HEX编码较短,在自定义报文时扩展性较差,起始字节7E7E。

文中A设备采用了ASCII编码,B设备采用了HEX/BCD编码。

图2.1.1、图2.1.2分别是A设备的ASCII编码的测试报文,B设备的HEX/BCD编码测试报文。

图2.1.1 ASCII编码的测试报文(A设备)

 图2.1.2 HEX/BCD编码测试报文(B设备)

图2.1.1,图2.1.2是2种编码的报文在EditPlus中的16进制显示格式。

计算机中数据都是二进制字节流。一般将二进制字节流代表字符含义的情况时称为字符流,当二进制字节流不代表字符含义称为字节流。

两种报文解析细节见SL651文档。它们的报文起始符报文结束符是相同的,差不多就是图2.1.1中显示不出字符的那些字节。根据SL651文档中的定义,ASCII报文与HEX/BCD报文的不同之处大致体现在:

1.数据在ASCII报文中表示为一串ASCII字符,在HEX/BCD报文按照字节的原始值或者BCD码原始值表示。

2.数据在ASCII报文中通常以字节20(空格字符) 表示数据的分隔。而在HEX/BCD报文中需要额外增加1字节的数据定义字节(如图2.1.2中的第0x26的字节)。

3.SL651协议主要是定义降雨等相关数据的,在遇到自定义的数据时,ASCII报文扩展性较强,因为有空格字符作为分格符,可以任意定义字符串名称。HEX/BCD报文需要在已定义的监测项编码后面扩展(见SL651-2014附录C),并且没有可读性。在图2.1.2中在字节0x36后就自定义了的FF12和FF11监测项编码,还定义了无数据时数据为AAAAAA。

2.2数据解析

数据解析时,ASCII报文和HEX/BCD报文的主要对应的原始数据含义是一样的。主要区别就是:HEX/BCD报文尽量将一个原始数据的2位数,用HEX或BCD编码进一个字节,用字节16进制查看能直观看清,比如图2.1.2中字节0x20——0x24 用BCD编码2206021420代表了22年6月2日14时20分。而ASCII报文会将这个时间的解析为每一个数字的ASCII报文,比如图2.1.1中字节0x3B——0x46就是240115110000的ASCII码。 

疑问:在图2.1.2设备B这段报文中 数据定义字节似乎不符合SL651-2014文档6.6.3.2节的标准。

图2.1.2中第0x26个字节是0x19,二进制是00011001

图2.2.1 HEX/BCD数据定义字节

按照标准中字节高5位时00011,字节低3位是001,这种情况十进制有效数字应该是3,小数点位数是1。表示应该位N(3,1)。但它实际情况代表了N(6,1),也就是十进制有效数字6位,小数点1位。

似乎遥测站上行报文的数据定义取了高6位000110,低2位01 ?这种情况似乎说明了,当遥测端发送的时候格式不规范时,需要将实际报文和协议标准结合起来 才能避免解析错误。

2.2.1 报文解析注意点和一些简化处理

1.在SL651-2014附录B中提供了多种报文类型。本文简化处理,只解析定时报。

2.在SL651-2014的6.6.2.7节中,规定报文正文可以存在多个遥测站。报文简化处理默认只存在一条报文中只存在一个站点。

2.3数据校验

在传输层TCP协议中已经提供了很多确保数据可靠性机制。比如对报文的编号,ack确认,超时重传,数据校验等机制,能确保应用层SL651接收到的报文是按顺序的、完整的。在SL651协议中也简单的定义了数据校验机制。SL651应用层接收报文需要根据校验码进行CRC16数据校验,确认报文需要发送校验码。这里简化只对确认确认报文发送校验码。需要注意的时HEX/BCD报文的校验码是2个字节,ASCII编码的校验码是对HEX/BCD报文2个字节校验码的HEX格式在进行ASCII编码,也就是4个字节。

参考

Java实现CRC16算法校验_java 参数为16进制字符串crc16实现-CSDN博客

3.数据的完整性和通信方式

3.1通信方式及连接维持方式

本文的协议解析实现是基于ASCII编码的。通过测试报文日志可以看出,在接收到遥测站上行报文后,需要发送下行报文确认。否则遥测站会因为超时重传机制发送多次上行报文。可以推断出遥测站应该是工作在SL651协议的M2模式上的。

图3.1 遥测站上行报文日志

 从图3.1可以看出一些点位因为发送小时报后没有接收到确认报文,所以多次发送小时报。上图中还能看到链路维持报,链路维报并不需要回复确认报文。链路维报可在应用层提供连接维持机制。本文在应用层简化不做这些处理,所以保活时间默认是操作系统在传输层(TCP)定义的7200秒。

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-05 22:26:02       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-05 22:26:02       106 阅读
  3. 在Django里面运行非项目文件

    2024-02-05 22:26:02       87 阅读
  4. Python语言-面向对象

    2024-02-05 22:26:02       96 阅读

热门阅读

  1. C++中的friend用法

    2024-02-05 22:26:02       49 阅读
  2. idea常用插件

    2024-02-05 22:26:02       48 阅读
  3. 数据合规:确保数据安全与隐私保护的关键

    2024-02-05 22:26:02       51 阅读
  4. Tomcat -- catalina.bat

    2024-02-05 22:26:02       47 阅读
  5. leetcode中二叉树迭代遍历中的三种遍历方式实现

    2024-02-05 22:26:02       60 阅读