恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
IEC 104仿真工具实战指南:从联调排障到自研架构
首页
资讯中心
/
IEC 104仿真工具实战指南:从联调排障到自研架构
IEC 104仿真工具实战指南:从联调排障到自研架构
发布时间:2026/9/9 9:23:39
简介面向电力系统自动化研发与测试人员的 IEC 104 规约客户端/服务端仿真工具可用于模拟 SCADA 主站与 RTU 从站间的遥测、遥信、遥控、遥调通信支持验证规约解析、命令下发及异常处理等场景。压缩包共 137 个文件大小 14.55MB以 C 源码.cpp/.h、Visual C 工程文件.dsp/.dsw、可执行程序.exe及动态库.dll为主同时附带 .pdb、.obj 等编译调试产物便于直接运行或二次开发。已有 706 人学习下载。资源内含 Master 与 Slave 两套 MFC 程序框架对应客户端和服务端仿真代码覆盖 ASDU/TCPU 分层处理、A 格式与 U 格式交互、断线重连与流量控制等关键逻辑并配有工程说明文档适合学习规约实现细节、开展接口联调与压力测试是一份实用性很强的电力通信调试工具包。 前两天在配电站房现场调一台边缘网关的IEC104上报从下午一直折腾到晚上九点最后还是靠一台仿真工具定位到问题网关在链路建立之后迟迟不发总召唤的激活终止帧主站就始终认为数据没有传完。这种情形我遇到过太多次所以出差电脑里必装一套IEC104 客户端、服务端仿真工具。这篇文章就围绕仿真工具这个主题讲清楚它到底解决什么问题、配置时需要理解哪些协议骨架、客户端仿真和服务端仿真分别要具备什么能力、真实联调中怎么用它排雷以及如果你想自己动手改一版架构上应该怎么拆。做电力自动化的人都知道IEC 60870-5-104是目前远动通信里最常用的协议之一主站、子站两个团队经常各管一段真机子站又没法随便折腾仿真工具就成了中间那个最可靠的裁判。不管你是做调度主站、配电终端、电力网关还是协议栈开发这台工具用好了能帮你把联调时间砍掉一大半。下面我按自己踩过坑的顺序来讲。1. 为什么调IEC 104总得备一套趁手的仿真工具1.1 现场联调的真实痛点我做过的项目里最常见的场景有两种一种是主站平台先建好了子站设备还在出厂测试联调窗口就两三天另一种是现场设备已经投运你根本不敢随便改配置、重启、断链去验证异常逻辑。这两种场景下拿着真机做测试都特别被动。我记得有一次联调一台保护装置对方厂家只给了一个IP和端口连点表都是PDF扫描件。我想验证它在链路中断后会不会主动重连、重连后会不会重新做总召唤但设备运行着我不可能真去拔网线。哪怕能拔旁边就是运行中的监控屏出了问题没人担得起。这种时候仿真工具的价值就出来了我可以自己先模拟一个子站把所有异常场景都过一遍等行为符合预期了再拿真机来验证。另一个扎心的现实是主站和子站往往不是一拨人开发的。两边都觉得自己实现得对出了问题互相甩锅。仿真工具作为一个中立的参照物能明确告诉你报文就在这谁没按规矩来自己看。很多次联调会解决问题的不是争吵而是把抓包文件或仿真工具的日志往桌上一放谁少回了确认帧一目了然。1.2 仿真工具要解决的核心问题说白了IEC 104仿真工具要做的事情有两件一是扮演一个标准参考答案让对方实现能对着它校验二是扮演一个故障注入器把各种不正常的报文、不正常的时序发给对方看对方会不会优雅地处理。先说标准参考答案。你做子站仿真工具扮演一个合规的主站发起TCP连接后按顺序做STARTDT激活、总召唤、周期查询你会看到它对于你上送的每一包数据都规规矩矩回S帧确认。如果工具日志里显示收到未确认的I帧数量超过窗口限制说明你的上送逻辑没有按停止等待确认的方式限制数据量这就是潜在隐患。反过来你做主站仿真工具扮演一个标准的子站它会在收到总召唤后先回激活确认再把所有点按顺序上送最后回一个激活终止。如果你连这种最标准的子站都调不通那问题基本就在主站自己身上。再说故障注入。真实联调中很多问题不是正常流程走不通而是异常情况没被正确处理。比如仿真工具可以主动不发S帧确认让对方陷入窗口满的停等状态可以故意把一个I帧的序号重复发送可以发一个未知的类型标识可以在你召唤总召唤时只回一部分数据就不回了。这些场景用真机去模拟成本太高但用仿真工具配置几秒就能跑一遍。联调前把这些负面用例过一遍能少跑很多趟现场。1.3 什么样的工具算趁手市面上和IEC 104相关的工具其实不少但真正趁手的不多。开源社区里常被拿来二次开发的包括C语言系的lib60870、Python接口的c104以及Java系的OpenMUC j60870商业电力测试仪厂商也大多内置了104模拟功能。我个人评价一个工具好不好用就看四点能不能同时切换客户端和服务端两种角色能不能自定义点表和超时参数能不能方便地注入异常日志能不能导出成通用格式。如果只是拿来临时看看报文那其实任何带解析功能的工具都够用但如果你跟我一样要把仿真工具嵌进联调流程甚至自动化测试里那角色可切换和异常可注入这两点就是刚需。很多工具只能模拟一边等你接到反向联调任务时又得换一个工具来回学习成本很高。后文我会把这两种角色的能力边界拆开细讲。2. 动手配置仿真工具前先把60870-5-104的关键骨架摸清2.1 APDU由APCI和ASDU组成帧类型要看清楚很多人在仿真工具里配参数时一头雾水就是因为没理解报文的基本结构。IEC 104的报文单元叫APDU前面6个字节是APCI控制头后面跟的是ASDU数据区ASDU不一定每帧都有。APCI的第一个字节固定是0x68第二个字节表示后面剩余字节数剩下的4个字节是控制域。控制域不同帧类型就不同。I帧是信息传输帧只有它才能携带ASDUS帧是监视帧只用来做确认表示你发到编号多少的帧我都收到了U帧是控制帧不携带ASDU用来做STARTDT激活/确认、STOPDT激活/确认、TESTFR测试帧的请求/确认。在仿真工具里看日志时如果满屏都是S帧说明对端TCP连接正常但应用层基本没数据流动如果一直是U帧TESTFR说明链路空闲但双方还在通过测试帧保活。实操中有个容易忽略的点I帧里的发送序号和接收序号是15位逻辑序号编码到字节里时整体左移了一位最低位保持0。有些工具显示N(S)是0、1、2有的工具直接按编码值显示0、2、4两种显示方式都能在协议里找到依据但如果你要手动构造报文或者核对抓包必须搞清楚你手里这个工具用的是哪种显示习惯不然排查序号问题时会绕很大一圈。2.2 常用ASDU类型标识和点表映射ASDU里最关键的是类型标识、可变结构限定词、传送原因、公共地址和信息对象地址。类型标识决定这一帧里装的是遥信、遥测还是遥控。常见的有类型标识1是单点遥信3是双点遥信11是标度化值遥测13是短浮点遥测45是单点遥控46是双点遥控100是总召唤。记住这几个就覆盖了日常联调八成以上的报文。信息对象地址IOA是IEC 104里最让新人头疼的地方。它是信息对象的地址通常用3个字节表示不同厂商对IOA的定义方式五花八门有的从1开始有的从0开始有的把点号分在地址的高位和低位。仿真工具里配置点表时IOA范围必须和对方的工程点表严格对齐否则就会出现工具里能看到报文但设备端就是不认这个点的情况。我见过最极端的一个项目两台设备用的都是标准104但IOA编号规则一个按十进制连续编号、一个按功能码分段映射两边联了整整两天才发现是地址含义理解不一致。品质描述词也值得留意。一个遥信或者遥测点在数据后面通常还跟着一个品质字节里面包含无效、非当前值、被取代、被闭锁这些标志位。品质字节在工具里往往是十六进制显示比如0x80表示无效。如果你在仿真工具里看到对端上送的数据是正常值品质无效那这个点就不应该在业务上参与判断。2.3 启动流程与t0到t3这几个超时参数IEC 104启动流程是有严格顺序的TCP连接建立后主站必须先发STARTDT激活子站回STARTDT确认链路才进入可传输数据的状态之后主站再发总召唤子站先回激活确认再按点表把所有数据上送最后回一个激活终止帧表示总召唤结束。很多连上了但收不到数据的问题本质上就是在这个流程的某一环断了。仿真工具里几乎都有超时参数配置这几个参数看起来小实际坑很大。t0是建立TCP连接的超时默认30秒t1是发送I帧之后等待确认的最长超时默认15秒超过就要重发t2是接收方在空闲时主动发S帧确认的间隔默认10秒t3是链路空闲时发TESTFR测试帧的周期默认20秒。k值代表最多允许未确认的I帧数量默认12w值代表收到多少个I帧后必须主动回S帧默认8。我建议平时把工具里的参数先按默认值用出问题再改。有一次我把t2调成60秒结果对端子站因为一直收不到S帧确认以为链路有问题k窗口很快就满了数据上送直接停住。这个例子很典型不是协议实现错而是仿真工具的确认节奏和对端预期不匹配导致对端进入了自我保护。所以调试时先恢复默认参数排除这种非业务性干扰再往下查。3. 客户端仿真和服务端仿真两张完全不同的能力清单3.1 客户端仿真自己扮演调度主站客户端仿真就是工具扮演主站、调度端你去连一台真实的子站设备比如RTU、保护装置或通信网关。这种模式下最基础的能力是主动发起TCP连接正确完成STARTDT激活然后发总召唤把设备里的所有数据拉一遍。再往下一个合格的主站仿真器要能发遥控命令而且得区分选择和执行两步。遥控命令里带有一个S/E位常见的流程是先发一个选择命令等待子站回选择确认再发执行命令等待执行确认。有些子站允许只发执行不选择有些严格要求先选择后执行。拿仿真工具做客户端时你应该能自由配置这一步只选择、只执行、还是先选择后执行。我在现场见过一个主站平台只发执行不发选择把一台严格要求双确认的子站设备调得毫无反应两边查了很久才发现是这个细节。除了拉数据和下发遥控客户端仿真还要能模拟主站的懒和勤。勤的模式好理解就是启动链路后立刻总召唤之后按周期重复总召唤懒的模式则是建链之后不发任何应用数据只靠S帧或者TESTFR保活。这两种模式用来验证子站的主动性尤其是子站能不能在收到总召唤后正确发出激活终止帧这个行为很多协议栈实现得都不够标准。3.2 服务端仿真把一座厂站装进电脑服务端仿真正好反过来工具扮演子站监听一个TCP端口等着主站来连接。别以为被动监听就简单真正折腾人的全是细节。一个完整、规范的服务端仿真器至少要能在收到TCP连接后正确响应STARTDT激活收到总召唤后先回激活确认然后按配置的点表把所有点分批次上送最后回激活终止。这里最难的是分批如果点表很大几万个遥信遥测不可能一包塞完你要按工具配置的每包最多信息对象数量拆帧还得把发送序号、接收序号维护好等待主站的S帧确认。如果主站一直不回S帧你的发送窗口就会满后续数据就发不出去。很多主站实现不好恰恰在接收大量数据时S帧回得不及时仿真工具会非常直接地把这个行为暴露出来。除了被动响应服务端仿真器还必须能主动上送。比如模拟一个遥信变位主动发一包变化遥信传送原因填突发模拟遥测越死区主动上一包新遥测值。这样主站那边就能验证它的报警、遥测刷新逻辑。再进阶一点工具还应该能模拟子站重启发一个传送原因是初始化的报文然后等主站重新发起总召唤。如果主站收到初始化后还傻等旧数据那就说明主站的重启处理逻辑有问题。3.3 角色切换时别忽略的配置项很多工具支持一键切换客户端/服务端角色但切换后有几项配置特别容易漏。端口号是第一个坑做客户端时你填的是对端子站的端口默认2404切到服务端时你必须确认工具自己是不是在2404端口上监听如果本机端口被占用工具往往会在日志角落报一句bind失败不仔细看就漏过去了。公共地址是第二个坑。子站设备的公共地址CASDU一定要在仿真工具里配对不然主站发来的报文公共地址对不上仿真器很可能直接丢弃。我见过有人用服务端仿真接主站怎么调都不通最后发现公共地址填了0而主站发的每个ASDU公共地址都是1。这种问题抓包很容易看出来但界面配置时太容易忽略。4. 联调中最容易踩的五个坑以及完整排查链路4.1 TCP连上了但一包数据都收不到这个坑出现的概率极高。完整排查链路是先看TCP连接状态是否ESTABLISHED然后看有没有完成STARTDT激活握手再看如果角色是主站有没有发出总召唤如果角色是子站有没有配置自动上送。我遇到过最典型的场景是仿真工具客户端显示TCP已连接但报文列表里面什么都没有等多久都没反应。用Wireshark抓包一看原来设备那边只接受了TCP连接但一直没回STARTDT确认。设备端的协议栈处于未激活的初始状态主站发什么应用数据它都不处理。这种时候再往业务层找就是浪费时间问题就在握手这一步。反过来如果STARTDT都完成了总召唤也发了还是没数据就要怀疑是不是点表为空或者周期上送没开启。仿真工具里一般都有一项周期上送或者变化上送的开关很多人打开工具只配置了IP和端口忘记勾选自动上送于是设备端一帧数据都不主动发。这属于工具使用细节但越是低级错误越会浪费整个上午。4.2 对时看着成功设备时间就是差几秒对时命令在主站发来的是一个7字节的CP56Time2a时标里面包含毫秒、分、时、日、月、年、星期看上去很简单但在工具里最容易出错的是时标字段的字节顺序。IEC 104时标通常是小端方式存储毫秒字段在前两个字节然后是分、时、日、月、年、星期。如果你在工具里看到对时时标解析出来是2025-06-15 08:30:00.123那一般是解析对了要是工具直接把原始字节按大端显示成2025-06-15 00:30:08.123这种奇怪组合就要怀疑解析层的问题。还有一个实际经验有些设备对时精度要求不高只精确到秒有些设备则要求毫秒精度。联调时如果发现设备时间和主站总有几十毫秒到几百毫秒的误差先不要急着怀疑协议用仿真工具客户端连续发三次对时然后读设备时间看差值是否稳定。如果稳定差固定值往往是时区或基准时间处理问题如果差值在跳动那就要看设备端的时钟守时精度这不是104消息能解决的。4.3 遥控发下去设备纹丝不动遥控问题排查起来最让人上火因为明明报文也发了设备也没报错但开关就是不动。我的排查顺序是先核点表再核命令类型再核S/E位最后核品质标志。点表不对最常见的表现是IOA在工具里是十进制显示设备点表是十六进制两边没换算就填进去了。其次是单点遥控和双点遥控用错单点遥控对应类型标识45双点遥控对应46。一个双点遥信对象你拿单点遥控去操作设备不响应完全正常。S/E位更是隐蔽。有些设备界面不显示具体S/E值但仿真工具里一般有明确的下拉选项。如果设备要求选择加执行两拍而你只发了执行你会发现设备回了确认帧但状态里带一个命令不被接受的提示。品质标志里的BL闭锁也是一个关键点设备如果上送品质显示闭锁遥控会被拒绝这不是协议问题是设备侧联锁逻辑在起作用。4.4 遥测值在工具里明显不对遥测解析不对往往是类型标识用错。同一个遥测对象不同厂商可能用标度化值类型11或者短浮点类型13。仿真工具如果按标度化值解析一个短浮点报文显示出来的数字完全没意义。我建议在工具里对每个点显示原始字节解析值两列先看原始字节是否符合类型定义再谈换算。另一个常见问题是工程换算系数。IEC 104里的标度化值是一个带符号整数要变成真正的电流、电压通常还要乘以系数、加上偏移。有些设备把系数写死在文档里有些设备直接把缩放后的整数当原始值发出来。仿真工具能不能给每个点配置系数直接决定了你看到的遥测值可不可信。所以别急着说设备上送值错了先用工具关掉系数看原始值再和点表里的量纲核对一遍。还有一个容易误判的是死区。主站侧觉得遥测值该变没变其实不是没变而是变化量没超过设备设置的死区阈值设备按规约不上送。仿真工具客户端模式下可以用总召唤强制拉一次全量数据如果全量数据是新的说明设备本身数据没问题只是变化上送被死区挡住了。4.5 断线重连之后状态始终恢复不了这个问题出现频率也很高而且比首次连接更能暴露协议栈质量。正常的断线重连流程应该是TCP重新连接完成后重新做STARTDT激活必要的话再重新总召唤。但很多实现里TCP重连了STARTDT也过了主站就是不再发总召唤或者子站自己重启之后没有主动通知主站。排查链路一般是看仿真工具日志里断线后有没有收到对端的初始化报文传送原因是初始化的报文如果收到了看主站有没有随之重新发起总召唤如果没有发那问题在主站的状态机它没有把对端重启当作一个触发总召唤的事件。另一个细节是序号。断线重连后发送序号和接收序号往往需要复位。有些设备重连后继续用旧的序号有些从0重新开始。仿真工具如果默认自动复位序号而你的对端又要求连续序号两边就会不断报序号异常。反过来也一样。我现在的习惯是工具里同时打开序号显示重连后第一眼就看N(S)、N(R)是否按预期变化如果对不上再决定要不要手动重置。5. 想自研或扩展仿真工具架构上我建议这么拆5.1 协议栈、会话状态和界面必须分离如果你不满足于用现成工具想基于开源库或自己写一套仿真器架构上第一个原则就是分层。至少要有协议编解码层、会话状态机、业务数据模型和界面展示四块。协议编解码层负责把TCP字节流切分成一个个APDU并解析成结构体也负责把结构体编码成APDU字节流。会话状态机维护连接状态、发送/接收序号、超时定时器、窗口大小。业务数据模型主要管理点表、当前值和品质位。界面展示只做一件事把状态和数据渲染出来。这个分层的好处是你可以在没有界面的时候直接用命令行或脚本调协议栈方便自动化测试。我见过很多自研工具把TCP逻辑和UI逻辑写在一个类里后面想加脚本回放、想跑回归测试几乎没法下手。分层虽然前期多花点时间但后期改动成本会小很多。5.2 数据模型要能直接映射工程点表IEC 104工具的核心数据模型其实就是一张点表。每个点至少要包含以下字段点位名称、IOA、类型标识、初始值、变化阈值、扫描周期、品质位、是否启用。用结构化的方式存这些点不要写在散落的哈希表里。工程实践里点表经常是Excel或者CSV格式仿真工具最好支持直接导入导出。导入时要把IOA换算、类型映射、系数设置都做掉。我记得有个团队自研了一个104服务端仿真最耗时间的不是协议栈而是把上万个点的点表手动录进配置界面。后来加了CSV导入一次搞定。这块做得顺不顺直接决定工具好不好推广。5.3 脚本化跑场景仿真器才有自动化价值当成型工具能手动收发报文之后下一步就是脚本化。最简单的脚本能力是按照时间线自动执行动作比如第0秒建链第2秒发总召唤第5秒模拟一个遥信变位第8秒断线第12秒重连。这种时间线脚本能覆盖掉日常联调里80%的回归场景。再进一步就是断言。脚本里不仅要能执行动作还要能检查对端行为是否符合预期比如总召唤发出后10秒内必须收到激活终止帧超过了就上报失败。把这一层接进CI每次主站或子站版本更新都自动跑一轮协议回归能在早期发现很多低级回归。我现在参与的项目已经把104仿真器作为测试桩接进持续集成里效果非常明显。脚本引擎选型上不用追求复杂JSON序列描述加一个执行器就够了。真要支持Jython、Lua这类嵌入脚本也可以但先别一步到位最小实现能从文本文件读场景就足够解决大多数问题。5.4 做一个最小可用工具的大致路线如果你是从零开始自研我的建议是分三个阶段。第一阶段只做TCP收发和APDU编解码能连上对端能用Wireshark验证你编出来的帧是正确的这就完成了最难的部分。第二阶段加会话状态机支持STARTDT、总召唤、S帧确认、t1/t2/t3超时这时候你已经能跑通基本的数据上送和接收。第三阶段再加点表、遥控、对时、异常注入、脚本化。不要一上来就想支持全部ASDU类型。IEC 104里类型有上百种实际工程常用的就那十几个。先把遥信、遥测、遥控、总召唤、对时做扎实覆盖掉95%的联调问题剩下的等遇到具体需求再补。很多半途而废的自研项目都是死在前期追求大而全上。6. 把仿真工具用出生产力的几个习惯6.1 学会主动制造故障我见过很多人用仿真工具只做一件事连上收报文看报文关掉。这样用其实浪费了工具一半的价值。趁手工具的真正威力在于你能主动制造故障把对端的行为逼出来。比如你想验证主站在子站不发总召唤激活终止帧时会不会卡死那就用服务端仿真收到总召唤后回一包激活确认、上送几个点然后什么都不回了等主站自己超时。这种测试对协议栈的健壮性非常关键。再比如你想验证子站对重复序号的容忍度拿客户端仿真故意把一个I帧连发两次正常实现应该通过S帧确认给一个接收序号逼着发送方发现序号异常。故障注入做多了你对自己产品的边界心里会特别有数。6.2 建立自己的场景配置库工具是给人用的但真正值钱的是你在里面沉淀下来的场景配置。每完成一个项目联调我都习惯把仿真工程文件、点表、参数配置、异常测试脚本一起存档命名规则是项目名_设备型号_协议版本_日期。这个库越攒越值钱。后面再遇到类似设备或者类似主站直接把上次的场景配置调出来改一改就能用不用从零开始填参数。尤其是点表每个项目都重新录一遍既浪费时间又容易出错。配置库里还要写上备注比如这个设备的遥控必须先选择后执行否则会回拒绝、这个主站不会在断线后自动重发总召唤这些经验是工具本身不会告诉你的。6.3 别只信工具解析交叉验证一次再下结论最后一条建议来自好几次被工具误导的教训。仿真工具的报文解析偶尔也会和你预期不一致特别是涉及私有扩展、特殊类型标识、位级品质字段时工具的解析未必准确。遇到可疑报文不要急着按工具的显示下结论用Wireshark打开同一段抓包对照一下APDU长度、控制域字节、ASDU字段两边都一致再定性。Wireshark自带的IEC 60870-5-104解析器做得比较细很多工具不认识的扩展类型它也能拆出原始字节。我现在的习惯是仿真工具负责把流程跑起来Wireshark负责在关键节点抓包留证。特别是客户现场扯皮的时候一份干净的抓包文件比口头解释有用得多。工具是效率工具但最终判断还是要靠自己对协议的理解这个习惯陪着我避开了不少坑。本文还有配套的精品资源点击获取