电力规约101/104报文解析工具实战:从十六进制盲读到结构化诊断
简介面向电力远动通信与自动化调试人员压缩包仅6.8MB汇集了101、104规约报文解析与联调所需的主流工具覆盖报文分析、浮点数/十六进制转换、客户端与服务端模拟等场景可满足从入门学习到现场排错的需求。包内共136个文件以dll运行库、exe可执行程序、pco配置、csv/xml报文信息表为主部分chm帮助文档和pdf说明便于查阅用法整体结构围绕“报文分析”和“模拟端”两大模块组织。已有7993人学习下载。工具集中包含IEC8705报文翻译工具、报文解析器以及Peugeot、PMA、104主站调试模拟工具等亲测可用的软件其中Peugeot小巧灵活、收发数据正常而104主站调试模拟工具自带实用的报文分析部件有助于深入理解报文格式与交互流程。无论是刚接触101/104规约的新手还是需要快速验证链路的工程师都能从中找到直接可用的解析与模拟手段。 干了这么多年电力自动化现场调试要说哪个环节最磨人报文解析绝对排得上号。101、104这两个规约名字搞变电站自动化、调度数据网、配网自动化的同行应该都不陌生——一个跑串口、一个跑TCP传输方式不同报文格式却一脉相承。手里这套101、104电力规约报文解析工具我从最早的十六进制盲读到做成能自动识别帧类型、拆ASDU、标遥信遥测的辅助工具中间踩了不少坑。这篇就把它从头到尾拆开讲清楚适合正在跟报文较劲的调试工程师、想入门电力规约的嵌入式开发以及做运维想自己排查通道问题的人。1. 先从现场调试说起为什么我需要一个能用的解析工具1.1 101和104到底是什么IEC 60870-5-101是国际电工委员会制定的远动规约跑在串口链路上常见RS-232、RS-485波特率9600是起步也有不少项目用19200甚至更高。IEC 60870-5-104则是101的网络版跑在TCP/IP上默认端口2404。两者在应用层共用同一套ASDU应用服务数据单元结构只是传输层的封装方式完全不同。我第一次接触104的时候觉得它比101复杂后来才发现正好相反。101在串口上要自己处理链路层的CRC校验、重发机制、从站地址确认这些在104里全部由TCP帮你兜底了。但104也有自己的麻烦TCP是字节流没有消息边界你要自己处理粘包、拆包还要维护启停状态机。可以说101的坑在链路层104的坑在传输层两边都需要专门的解析工具来降低调试门槛。1.2 解析工具要解决的核心痛点没工具的时候我们看报文是这种状态68 0E 08 00 00 00 64 01 06 00 01 00 00 00 14 00 00 00一长串十六进制肉眼根本分不清哪里是类型标识、哪里是传送原因、哪里是信息体地址。要判断这条遥测值到底是多少只能拿着规约文档一字节一字节地比对。碰到一帧里带十几个信息体的情况光拆帧就得花十分钟还容易看错字节序。解析工具的核心价值就是把“人对着规约文档查”变成“工具自动拆解”把上面那串字节流翻译成这样的结构化结果类型标识100短浮点遥测传送原因6激活公共地址1信息体地址0值20.0。调试效率提升一个数量级不说更重要的是减少人为误判——很多时候报文看着不对其实是自己数错字节导致的工具能把这个概率降到零。2. 解析工具的核心功能拆解2.1 帧格式解析FT1.2与APCI/APDU的差异做解析工具第一步是把帧格式吃透。101和104虽然ASDU共用但外层封装差异很大需要分开处理。101用的是FT1.2帧格式分固定帧长和可变帧长两种。固定帧长10字节启动字符10、控制字、链路地址、CRC校验两个字节、结束字符16。可变帧长则是68开头后面跟两个重复的长度字段然后是控制字、链路地址、用户数据区最后CRC校验和结束字符16。注意101的CRC是专用算法不是CRC16-MODBUS这是新手最容易踩的坑。104的帧结构就清爽多了也分三种帧类型启动字符结构用途I帧68APDU长度 控制域4字节含发送/接收序号 ASDU传输应用数据S帧68APDU长度 控制域4字节仅接收序号确认接收不带数据U帧68APDU长度 控制域4字节启停/测试命令STARTDT、STOPDT、TESTFR控制域里面的规则是这样的I帧的发送序号和接收序号各占两个字节低字节在前S帧第一个字节是0x01后两个字节是接收序号U帧则是通过第一个字节的高位来区分是STARTDT0x07、STOPDT0x13还是TESTFR0x43第二个字节固定为0。解析工具必须把这些状态流转逻辑也做进去不然碰到U帧就直接傻了。2.2 ASDU拆解类型标识、传送原因、信息体地址才是关键ASDU是所有解析工作的核心结构相对固定类型标识1字节、可变结构限定词VSQ1字节、传送原因2字节、公共地址2字节后面跟着一个或多个信息体。类型标识决定了这条报文的含义常用的有这些类型标识含义简称1单点遥信M_SP_NA_13带时标单点遥信M_SP_TB_19归一化值遥测M_ME_NA_111标度化值遥测M_ME_NB_113短浮点遥测M_ME_NC_130带时标短浮点遥测M_ME_TF_135单点遥控C_SC_NA_145双点遥控C_DC_NA_1100短浮点遥测国网扩展常见于国网项目VSQ这个字节有点讲究最高位是信息体地址连续标志低7位表示信息体数量。如果最高位置1说明后面信息体的地址是连续的解析时不需要逐个读地址用起始地址递增就行了如果最高位为0那每一个信息体都得单独带地址。传送原因占两个字节实际有效的是低6位加方向位。方向位在主站发从站时是0从站发主站时是1。常见传送原因包括6激活、7激活确认、8停止激活、9停止确认、20响应站召唤、3突发遥信等。2.3 遥测、遥信、遥控、遥调的解析逻辑解析工具最终是要把ASDU里的信息体翻译成业务数据这里要按四遥类型分别处理。遥信相对简单单点遥信一个信息体占1字节只看最低位0表示分、1表示合双点遥信占1字节有效位是bit0和bit1组合值00表示不确定、01表示分、10表示合、11表示不确定。带品质位的版本还要解析bit2到bit4的品质描述。遥测分三种值类型归一化值、标度化值、短浮点。归一化值和标度化值都是两个字节需要按规约约定的系数换算成实际工程值。短浮点则是标准的IEEE 754单精度浮点4个字节小端存储解析出来直接就是实际值。这里有个细节很多地方用类型100替代标准13两者数据结构完全一样但有些主站程序对类型标识做了严格校验工具要能兼容这两种写法。遥控、遥调报文的ASDU结构里会增加一个限定词字节用来区分选择还是执行。比如遥控命令信息体里除了地址还会带上限定词选择1、执行2和命令值0或1。解析工具需要把这一层也还原出来不然现场做遥控试验时出了问题根本看不出来是主站没下发还是从站没执行。3. 从抓包到出数据报文解析实战记录3.1 一次104报文完整拆解拿一条最典型的104遥测上报报文来实际操作一遍。原始字节流68 0E 08 00 00 00 64 01 06 00 01 00 00 00 14 00 00 00这串一共18个字节。68是启动字符0E是APDU长度也就是后面16个字节的长度。接着控制域4字节08 00是发送序号400 00是接收序号0说明这是一条I帧。然后进入ASDU区64就是类型标识100短浮点遥测01是VSQ表示1个信息体且地址连续最高位为006 00是传送原因6激活方向位为0说明是主站下发的激活命令01 00是公共地址1后面是信息体00 00是信息体地址014 00 00 00是短浮点值把这个短浮点按小端拼起来就是0x00000014换算成十进制是20所以这条报文表达的是公共地址1下信息体地址0的遥测值20.0。实测中这种报文大量出现在站召唤响应的场景里主站发激活从站用类型100把实时遥测值批量传上来。工具在这里要做的不仅是解析还要能自动归并一条响应帧里可能带几十上百个信息体必须按地址排序、去重、映射到点表名称才算真正“能用”。3.2 101串口报文的解析要点101串口报文解析和104有个显著不同你要自己处理链路层。举个可变帧长的例子68 0F 0F 53 01 09 0D 01 03 00 01 00 00 00 00 1E 00 22 1668启动字符0F 0F长度字段用户数据区15字节53控制字二进制0101 0011功能码3确认/响应bit7置1表示从站发主站01链路地址后面是ASDU09类型标识9归一化遥测、01 VSQ、03 00传送原因3突发、01 00公共地址1信息体00 00地址000 1E标度化值注意低字节在前实际是0x1E007680归一化值要换算成工程值规约里定义满量程对应32767。如果这个遥测的工程量程是0到100A那实际电流就是7680/32767×100≈23.4A。这个换算系数不是规约里写死的而是来自点表配置工具必须提供配置入口否则解析出来只是个裸数值。串口解析还要处理一个麻烦串口报文没有TCP那个“一次一帧”的省心感觉调试的时候经常一个字节一个字节地蹦出来工具必须做状态机缓存按启动字符、长度字段逐步累积直到收满整帧再做校验。3.3 边做边学极简解析脚本的设计思路我在初期验证工具逻辑的时候用Python写过一个极简解析器核心思路就是状态循环。伪代码逻辑大概是这样的def parse_104_frame(data): if data[0] ! 0x68: return None apdu_len data[1] if len(data) 2 apdu_len: return None apci data[2:6] # 判断帧类型 if apci[0] 0x01: # I帧 send_seq apci[0] | (apci[1] 8) recv_seq apci[2] | (apci[3] 8) asdu data[6:2 apdu_len] # 进入ASDU解析 elif apci[0] 0x03 0x01: # S帧 recv_seq apci[2] | (apci[3] 8) else: # U帧处理脚本本身不难难的是把各种边界情况都照顾到。比如APDU长度和实际接收长度不一致、半包、粘包、多帧复合的情况这些都需要在实际调试中不断补充。我的做法是先写个能跑的最小版本然后拿真实抓包样本去喂每遇到一个异常场景就加一个分支慢慢就长成了完整的工具。这个迭代思路比一开始就想写个完美框架要实在得多。4. 调试现场常见的坑与排查技巧4.1 connection reset by peer 到底是谁的问题用telnet连104端口的时候经常直接报telnet: [errno 104] connection reset by peer很多人第一反应是网络不通其实这个错恰恰说明TCP握手已经完成了但连接在应用层被对端主动重置。在104调试里这种情况大概率是以下原因之一主站接入后没有发STARTDT激活命令从站侧等了一会儿就直接断链从站程序在收到激活命令后崩溃重启TCP连接被RST双方对心跳超时时间配置不一致从站认为连接空闲太久主动断开中间有防火墙或NAT设备长连接老化后被强制重置排查思路就三步先抓包看TCP握手和RST包的时序再确认应用层是否正确发送了STARTDT和TESTFR最后核对两端参数表里的超时时间。很多时候主站程序能正常连上但就是不发STARTDT这种情况报文解析工具能帮你一眼看出来。4.2 粘包、拆包与半包处理104基于TCP字节流最大的坑就是报文没有天然边界。主站一次可能收到三四个粘在一起的帧也可能一个帧被拆成两半到达。我见过不少调试人员在这上面栽跟头直接按recv返回值去解析结果一帧被拆半就解析失败。正确做法是维护一个接收缓冲区每次收到数据先追加到缓冲区尾部然后循环检查第一个字节是否为68如果是则读第二个字节作为APDU长度如果缓冲区长度足够就取出完整一帧解析并从缓冲区中移除如果不够就继续等。这个逻辑写起来不复杂但必须放在解析工具的最底层做。4.3 大小端、缩放因子与工程单位电力规约里小端是大趋势信息体地址、传送原因、公共地址、浮点值全部低字节在前。但101的归一化值和标度化值虽然也是小端存储换算时容易搞错符号位。特别是标度化值最高位是符号位负数要用补码理解。另一个经常出问题的是缩放因子。同样的信息体地址在不同变电站里可能对应不同量程一个对应0到100A另一个对应0到600A。如果工具把缩放因子写死换一个站就全错了。我的经验是把缩放因子做成外部配置按点表导入而不是硬编码在工具里。4.4 规约一致性本站和主站对不上怎么办报文解析工具能把帧拆开但不代表两边语义就一致。现实中最大的问题是点表对不上同样信息体地址0x4001本站定义为“1号主变高压侧有功”主站却当成“2号线路电流”。这种情况报文解析工具解决不了但工具能帮你快速定位是地址问题、类型问题还是值域问题。还有一类是规约细节的地域差异。国网和南网对部分类型标识、信息体地址规划有不同约定甚至各省都有自己的细化要求比如信息体地址从0xA000开始的情况就很常见。做工具时最好把这些差异配置化而不是写死在代码里否则换一个区域现场就要改一次代码。现象可能原因排查思路连接被RST未发STARTDT或心跳超时抓包看应用层时序有帧但解析失败粘包/半包处理不完善检查缓冲区累积逻辑类型标识未知对方用扩展类型或私有类型确认规约版本和厂站配置值偏差大缩放因子或类型解析错误核对点表量程与归一化换算5. 工具选型与后续扩展5.1 现成方案盘点从Wireshark到自研脚本做101/104报文解析没必要什么都从零开始。我们先盘一下现成的方案Wireshark自带IEC 60870-5-104的dissector抓包后能直接展开APCI和ASDU字段用来做离线分析非常方便。但它的短板在于不能实时按点表翻译业务名称而且不支持101串口的实时监听需要外接串口转网络工具。开源库方面C/C有lib60870Java生态里有j60870——就是经常有人搜“j60870采集104数据”那个库。这类库把链路层和传输层都封装好了你只需要处理业务回调做采集器或模拟主站很顺手。但如果你要做深度报文诊断、异常帧标记、点表映射这些通用库并不直接支持。商业工具里CANoe配合104插件可以做主站/从站仿真和一致性测试适合厂内验证但整套方案价格不低对单一现场调试来说有点杀鸡用牛刀。我之前在项目里也用过它做规约一致性测试效果很好但日常巡检还是回到轻量自研工具。如果只想要一个趁手的小工具我建议这样组合抓包用Wireshark实时监视和点表映射用自研脚本或工具规约一致性测试用现成商业方案或开源库模拟。这套组合拳目前看是性价比最高的。5.2 从“能解析”到“能诊断”的进阶方向解析只是第一步真正好用的工具应该往“诊断”方向做。我在这套工具迭代过程中陆续加了几个非常管用的功能帧类型统计和一键过滤。现场通道异常时能快速统计当前收到多少I帧、多少S帧、多少U帧如果S帧占比异常高说明数据交互效率有问题如果U帧里TESTFR没有回应大概率是心跳机制没配对。异常帧标记。把CRC校验失败、长度字段异常、类型标识未知、序号跳跃的帧自动标红这样调试时不用逐帧去看直接跳到红帧处理。历史报文回放。现场问题往往不是当场能定位的我会把抓到的报文存成文件回放时模拟真实的时序复现那一次偶发的续传异常。再往后我还在尝试把点表映射做成自动导入——直接读Excel点表按信息体地址自动关联遥信遥测名称和缩放因子。这样工具的输出就不再是“信息体地址0x4001的值是23.4”而是“1号主变高压侧有功23.4MW”现场调试的人一眼就能看懂。我在实际使用中最大的体会是工具再聪明也替不了人但它能把人从枯燥的十六进制里解放出来让你有精力去思考通道到底为什么不通、点表为什么对不上。这套解析工具我还在慢慢迭代像带时标报文、扰动数据、参数下发这些场景后面都会陆续补上。如果你也在折腾101、104希望这篇能帮你少走点弯路也欢迎一起交流现场踩坑的经验。本文还有配套的精品资源点击获取