“数采仪上显示连接成功,平台那边一条数据都没有。”这是华东某化工园区一位运维工程师打电话时的原话。现场网络 ping 得通、端口 telnet 得开、设备日志里也没有断线记录,问题就卡在最容易被忽略的一层——上传报文被平台按 HJ212 CRC校验错误整包丢弃了。
结论:连接成功只证明 TCP 通,不代表报文合规。现场故障里,很大一部分是组包时的累加和算错、或数据段长度写错,平台收到后直接判非法帧、静默丢掉,设备端因为收到 TCP 应答反而认为“已经发出去了”。所以第一步不是重启设备,而是把原始报文抓出来,对着 HJ212 一字节一字节核。
HJ212 CRC校验错误到底错在哪一段
一帧 HJ212 报文长这样:## + 四位数据段长度 + 数据段 + &&。数据段里是 QN(17 位时间戳)、ST(系统编码)、CN(命令编码)、PW、MN、Flag、CP 等字段,末尾是两位十六进制校验码。
校验范围是 ## 之后、&& 之前的全部字符,## 和 && 本身不参与。算法是逐字符取 ASCII 码累加,取低 8 位,转成两位十六进制、字母大写。注意是两位,不是四位——不少现场把“四位长度字段”和“两位校验码”记混,随手补了两个 0,平台自然判错。
还有两个高频细节:数据段长度按字节数(ASCII 字符数)计算,混进一个中文或全角符号就多算;QN 的 17 位时间戳中间不能有空格、不能掉位,少一位整帧长度就跟着变,长度字段不跟着改,平台先按长度截取,截错了自然算不对。
四层原因,不要一上来就怀疑网络
- 协议层:累加和算错、十六进制大小写混用、长度字段与实际不符、字段顺序错(如 CN=2011 上传实时数据与 CN=3020 上传历史数据混用)、分隔符误用全角分号。
- 网络层:中间经过防火墙、DTU 或串口服务器做 ASCII/HEX 转码,把分号、星号转义掉;或 MTU 分片导致半包,接收端按 && 结尾截取失败。
- 设备层:数采仪协议模板版本与平台不一致,还在用老模板组包;仪表侧给出的浓度值带单位或负号,组包前没做数值清洗。
- 平台层:平台侧校验规则收紧,部分省份近年对长度字段和校验码都做了强校验;或 MN、ST 与备案信息不一致,被当成非法帧。
排查顺序:先报文,再设备,再链路,最后平台
顺序本身就是效率。报文是所有问题的交汇点,抓一次就能砍掉一半可能性;改设备参数要重启、要联系厂家,成本最高,放后面;链路问题通常伴随断连日志,反而最好认。
- 第一步,在数采仪调试口或串口抓原始报文,确认发出去的字节和你想的一致;
- 第二步,手算或写脚本复算累加和,与报文里的两位校验码比对,不一致就是设备组包问题;
- 第三步,在抓包工具里对比 HEX 与 ASCII 两种视图,判断有没有中间设备改写;
- 第四步,手工构造一条合法帧直接发给平台,看是否回 CN=9014 的应答,回执正常说明平台侧规则没变。
三个容易误判的坑
- 把“连接成功”当成“上传成功”。TCP 建连只管端口通不通,平台校验失败不会回 RST,设备照样显示在线。
- 抓包看到的和实发的不一样。十六进制里 20 是空格、3B 是分号,肉眼看像对的,实际可能多了一个不可见字符。
- 拿别家的报文直接套。同是 HJ212,不同省份、不同平台在 Flag、CP 字段和应答命令上取值不同,照抄模板,校验码算对了也可能被判格式错。
常见问题
我这个情况到底要不要改设备程序?先抓一帧出来复算,校验码对不上、长度字段明显不符,多半是组包模板问题,需要升级固件或改参数;如果设备发出的本就是合法帧,问题在中间链路或平台配置,改设备白改。
同一台数采仪,A 厂能传、B 厂不能传,是不是平台的问题?先比对两边的 QN 时间格式、MN 和 ST 取值。部分平台对长度和校验码执行强校验,A 厂宽松、B 厂严格,设备本身并没有坏。
报文我手算对了,平台还是提示校验错,还能是哪儿的毛病?看中间有没有 DTU、串口服务器、防火墙做协议转换,重点查分号、星号、等号是否被转义成编码,这类改写不改变人眼看到的文本,却会改掉每一个字节。
换根网线、重启一下能不能解决?能解决的是断连、超时、重连失败这类现象;HJ212 CRC校验错误是内容层面的问题,重启只会让平台再丢一次同样的帧。