news 2026/9/9 11:36:03

104主站仿真工具实战:从链路激活到总召唤与遥控调试

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
104主站仿真工具实战:从链路激活到总召唤与遥控调试

简介:一套面向电力自动化与工业通信工程师的 104 主站仿真调试工具集,以客户端软件为核心,用于模拟主站、验证子站兼容性、收发遥测遥信报文并排查链路异常。资源共 93 个文件,压缩包约 4.18MB,主要包含可直接运行的主程序、支撑通信界面与日志的动态库、用于保存场景和通道参数的 xml/pol 配置、记录历史收发过程的 pco 报文,以及 PDF 软件使用说明,能基本搭建完整的 104 协议调试环境。借助包内多种 104、101 报文样本和配置模板,读者可对比学习连接建立、总召、时钟同步等典型交互,也可在开发阶段对子站做兼容性测试,或用于现场异常快速定位。包内目录按程序、库、配置、报文和文档归位,便于快速定位所需模块。目前已有 1411 人学习下载,适合刚接触 104 协议的初级工程师,也可作为电力系统运维、调试人员的随查参考。

1. 项目概述与核心需求解析

前阵子项目上需要验证一批新的远动从站设备,现场调度主站还没到位,光看设备说明书和厂商自测报告心里总不踏实。于是顺手搭了一套104主站仿真软件,把链路协商、总召唤、遥信变位、遥控下发这些关键流程全部跑了一遍,也算是把IEC 60870-5-104规约从“纸上写的”变成了“实际动的”。这篇文章就聊聊这套主站仿真工具怎么选、怎么配、怎么用,以及在调试过程中踩过的那些坑。

先解释一个基本概念,104规约全称是IEC 60870-5-104,是电力系统调度自动化里用于主站与厂站端(变电站、RTU、保护装置等)之间远动通信的标准规约。它把传统的101规约搬到TCP/IP网络上,默认端口2404,解决了长距离传输和带宽利用的问题。实际工程里,104规约基本是变电站接入调度系统的默认选择,所以做电力自动化、系统集成、设备调试的朋友,几乎天天要和它打交道。

主站仿真软件的核心功能,就是在一台普通PC上模拟调度主站侧的行为,主动发起TCP连接,按规约要求的时序跟从站设备交互,包括启动链路、总召唤、时钟同步、接收遥信遥测、下发遥控遥调指令等。有了它,在没有真实调度主站的情况下,就能把从站设备的数据采集、SOE上报、遥控执行这些功能完整验证一遍。

这套工具适合谁来用?如果你是做远动设备调试的工程师,或者在做变电站自动化系统集成、需要验收第三方RTU或保护装置的通信规约,又或者是刚入行想搞懂104规约报文细节的学生,都可以照着这篇文章的思路搭一套属于自己的主站仿真环境。不需要多高端的硬件,一台Windows电脑、一个网口、一根网线就够了。

2. 104规约核心机制速览

2.1 APDU结构与三大帧类型

104规约的报文结构,核心单位叫APDU(应用协议数据单元),它由APCI(应用协议控制信息)和ASDU(应用服务数据单元)组成。APCI在最前面,负责传输控制;ASDU才是真正携带业务数据的地方。很多初学者一上来就对着报文看懵了,其实只要抓住APCI里的那几个关键字节,后面的ASDU解析就顺理成章。

APCI的构成分两种场景。对于I帧(信息帧,用于传输应用数据),格式是“68 长度 控制域1 控制域2 控制域3 控制域4 + ASDU”。其中0x68是启动字符,第二个字节是后面的总长度(包含控制域和ASDU,但不包括0x68和长度字节本身),注意这个长度经常有人算错,后面排查问题时会重点讲。控制域4个字节里,第1和第2字节的低位分别表示发送序号和接收序号(每两个字节一组,位运算规律后面细说)。

另外还有两种帧:S帧(监视帧)只有6个字节,不携带ASDU,专门用来确认接收到的I帧;U帧也只有6个字节,用于链路控制,比如STARTDT(启动数据传输)、STOPDT(停止数据传输)、TESTFR(测试帧)。U帧的格式是“68 04 控制域1 0 0 0”,控制域的特定bit位来表示不同命令,具体的位操作规则在标准里有明确表格,实际使用中对照着填就行。

2.2 连接建立与总召唤流程

104规约的主从交互,最核心的就是建立连接后的启动时序。TCP连接一建立,并不是马上就能传数据,而是要先进行STARTDT激活握手,这个细节特别容易踩坑。

具体流程是这样的:主站发送U帧的STARTDT act(激活请求),从站收到后返回STARTDT con(确认);此时数据传输才算正式激活,主站才能下发总召唤命令。很多人在仿真调试时,TCP连接是通了,但报文发过去从站不回,一看抓包,原来是漏了STARTDT这一手。总召唤命令是C_IC_NA_1,类型标识0x64,用I帧发送,从站收到后会先回一个确认帧,然后逐个上送遥信、遥测数据,最后再发一个总召唤结束标志(激活终止)。仿真主站建议严格按照这个流程走,才能验证出从站的真实行为。

2.3 信息体地址、公共地址与类型标识

再往下拆就是ASDU里的核心字段:类型标识、传送原因、公共地址、信息体地址。类型标识决定了这条报文是干什么的,比如0x01是单点遥信,0x0D是浮点遥测,0x2D是单点遥控,0x64是总召唤命令。传送原因则标识这条报文的性质,常见的有0x06激活、0x07激活确认、0x08停止激活、0x0A激活终止、0x14响应总召唤等。

公共地址(也常叫站地址)就是调度侧给这个厂站分配的地址,范围1到65535,在TCP链路里是全局有效的。信息体地址则是具体到某个遥信点、遥测点或遥控点的地址,它是三个字节的小端表示,比如地址4001在报文里就是0xA1 0x0F 0x00。搞清楚了这些字段,再去对照报文解析,思路会清晰很多。

3. 主站仿真软件选型与整体设计

3.1 自研脚本和现成工具如何取舍

主站仿真软件的选型,基本上有三条路。第一是用现成的商业测试软件,某些电力仪器厂商会配套出规约测试后台,功能全面、界面友好,但价格高且不一定允许二次开发。第二是用开源或共享的协议模拟器,这类工具适合快速验证,但碰到特殊需求(比如按自定义顺序循环上送遥测)往往会受限。第三就是自己动手写一套,用高级语言实现104主站的核心功能,灵活度最高,也最能帮助你深入理解规约。

我当时的选择是“现成工具打底 + 自研脚本补位”。先用现成的104协议模拟器把基本链路跑通,确认对端从站没有硬伤;再用自己写的Python脚本针对项目里的特殊点表做自定义测试,比如模拟连续变位、按分钟级周期拉遥测、做遥控反校延时等。两套手段互为补充,效率比单用任何一种都高。

3.2 功能模块划分

无论选哪种方案,一套像样的104主站仿真软件,至少要包含下面几个功能模块:

  • 连接管理:TCP客户端配置,支持多IP、多端口、自动重连,能手动触发STARTDT激活。
  • 报文构造与解析:支持常见类型标识的组帧、拆帧,能实时显示收发报文的十六进制原始字节和解析后的字段。
  • 总召唤与数据轮询:一键下发总召唤,支持周期性的遥信、遥测类召唤(类型标识0x64、0x65等)。
  • 遥控/遥调操作:下发单点或双点遥控,能处理选择、执行、撤销三个环节,并能解析从站的确认信息。
  • 日志与点表映射:记录完整交互过程,能把信息体地址映射成业务点号,方便跟实际测点对应。

3.3 关键技术选型与参数考量

如果自己写主站脚本,语言上我建议用Python,理由是生态成熟、网络库方便,而且处理十六进制报文非常直观。网络层用标准socket就够,不需要额外引入重量级框架。收发线程加一个队列做缓冲,主线程负责解析和界面输出,即可满足大多数仿真场景。

端口号默认是2404,这个一般不用改。但有一种情况要注意:如果从站前面还有前置机或者防火墙做了端口映射,那么在仿真主站里配置的IP和端口,必须和最终链路实际映射的地址一致,否则会出现TCP能连上但规约报文收不到的情况。这类问题比较隐蔽,排查起来费时间,建议一开始就确认好网络路径。

4. 主站仿真软件的实操过程与核心环节实现

4.1 从零搭建一个最小化仿真主站

下面以自研Python主站为例,给大家一个能直接跑的骨架。我自己的代码结构是四个文件:主程序、协议栈(组帧拆帧)、连接管理、测试用例。这里给出核心的链路激活和总召唤代码片段。

import socket import struct import time def build_u_frame(cmd): # cmd: 0x07 STARTDT act, 0x0B STARTDT con, 0x13 STOPDT act, 0x83 TESTFR act return bytes([0x68, 0x04, cmd, 0x00, 0x00, 0x00]) def build_i_frame(send_seq, recv_seq, asdu): # send_seq和recv_seq是实际计数值,需要左移1位,bit0置0 ctrl1 = (send_seq << 1) & 0xFF ctrl2 = ((send_seq << 1) >> 8) & 0xFF ctrl3 = (recv_seq << 1) & 0xFF ctrl4 = ((recv_seq << 1) >> 8) & 0xFF length = 4 + len(asdu) return bytes([0x68, length, ctrl1, ctrl2, ctrl3, ctrl4]) + asdu sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(('192.168.1.10', 2404)) # 1. 启动数据传输 sock.send(build_u_frame(0x07)) resp = sock.recv(255) # 正常应收到 68 04 0B 00 00 00 print('STARTDT con:', resp.hex())

这段代码里,build_u_frame和build_i_frame是两个最基本的组帧函数。特别注意I帧的序号处理,发送序号和接收序号都要左移一位再填充到控制域里,因为第0位固定是0,这是规约明确规定的。如果你在某一天发现对端一直不回I帧,先检查一下序号是不是写错了,这个问题在自定义实现里出现概率非常高。

4.2 总召唤流程实现细节

链路激活完成后,紧接着就发总召唤。总召唤的ASDU构造相对固定,类型标识0x64,传送原因0x06,公共地址用2字节小端,信息体地址是0x000000(三字节)。把一个完整的总召唤报文放出来参考:

68 0E 02 00 00 00 64 01 06 00 01 00 00 00 00 00

拆解一下:68是启动字符,0E(十进制14)表示后面总共14个字节;02 00 00 00是I帧控制域,表明发送序号为1、接收序号为0;64是类型标识(总召唤);01是ASDU中信息体数目,此处只有一个;06 00是传送原因(激活);01 00是公共地址(小端,表示地址1);后面的00 00 00是信息体地址;最后的00是总召唤限定词,表示“站总召唤”。整个报文要组对,一个字节都不能错。

发完总召唤,从站会先回一个“激活确认”(传送原因0x07),然后开始上送数据。等它上送完所有遥测遥信,会再发一个“激活终止”(传送原因0x0A)的帧,代表这一轮总召唤结束。仿真主站眼里,收到激活终止才算一轮完整的总召唤完成。如果只收到中间数据,没等到激活终止,说明从站可能还有数据没上送完,或者上送逻辑本身有异常。

4.3 遥控指令的报文构造与处理流程

遥控操作是现场最容易出问题的环节,因为涉及选择、执行、撤销三个子步骤,而且每一步都要有对应的确认。以单点遥控(类型标识0x2D)为例,选择的报文格式是:

68 0E 02 00 00 00 2D 01 06 00 01 00 01 60 00 01

注意看信息体地址是0x6001(这里为演示方便,取了0x000160的小端表示,实际按点表填),最后一位是遥控命令状态,0x01表示合闸,0x00表示分闸,0x02表示选择命令的限定词组合。选择命令的传送原因是0x06(激活),从站如果允许操作,会回一个传送原因0x07的确认帧。

选择确认后,主站再下执行命令,传送原因同样是0x06,但信息体地址最后一个字节要带上执行限定词。整个过程中,从站如果在选择后规定时间内没收到执行命令,会自动撤销,主站也会收到一个带撤销标识的帧。仿真软件在处理遥控时,一定要实现超时监听的逻辑,不然会把撤销帧误判为执行成功。

5. 常见问题与排查技巧实录

5.1 连接正常但报文无回应的排查顺序

这类问题占了调试工作的七成以上。我的排查顺序几乎固定:先TCP层再规约层。TCP能用ping通、telnet端口能连上,只能说明网络通,不代表规约层没问题;如果TCP都连不上,就看地址、掩码、防火墙。规约层最常见的原因有三个:没做STARTDT激活、I帧序号对不上、公共地址不匹配。其中公共地址不匹配最为隐蔽——从站收到的报文公共地址不是自己站的地址,它连确认帧都不会回,你在主站侧看就是“发送超时”,玻璃心一点的工程师就开始怀疑网线了。

5.2 长度计算错误导致的解析错位

104报文里0x68后面的长度字节,指的是从控制域第一个字节开始到整个报文结束的所有字节数。很多人习惯性以为这个长度是“ASDU长度”或者“总长度减2”,结果就错了。比如完整总召唤报文“68 0E 02 00 00 00 64 01 06 00 01 00 00 00 00 00”总共16个字节,0x68和0x0E不算进0E,0x0E等于后面14个字节。如果填成0x10(16),对端解析的时候会把下一条报文的前两个字节吞掉,后续报文全部错位,表现出来就是交互完全混乱。遇到这种情况,抓包看十六进制原始字节,十秒钟就能定位。

5.3 序号不匹配与重复帧处理

I帧序号是收发双方各自维护的,发送序号和接收序号分别独立。有一种典型错误是,接收方已经收到了序号为0的帧,但发送方因为超时重发,重发帧还是序号0;如果发送方没有正确递增序号,接收方会按照“重复帧”处理,可能直接丢弃。仿真主站需要维护好本地发送计数器和接收计数器,每发一个I帧发送序号加1,每收一个I帧接收序号加1。有些从站设备对重复序号的处理并不一样,有的直接忽略,有的一定会回一个S帧确认,但业务数据不会重复处理。搞清楚对端设备的这一特性,可以避免很多误判。

5.4 虚拟机和本机仿真环境的网络注意事项

有些人喜欢在虚拟机里跑Linux再用Docker起仿真服务,这本身没问题,但要注意虚拟网卡的MAC地址漂移会影响TCP连接稳定性。另外,如果在同一台电脑上同时跑主站仿真和从站模拟器,一定要用真实网卡的IP,不要用127.0.0.1,因为有些协议库对loopback地址的处理和物理网卡不一致,可能导致收包异常。我在实验环境里遇到过一次VirtualBox虚拟机网络配置出错导致通信中断的情况,后来直接换回物理机跑仿真,问题立刻消失。因此,在排查诡异通信故障时,先简化网络环境,往往是最快的解决路径。

5.5 常用问题速查表

故障现象可能原因快速排查方法
TCP端口连不上从站未启动、防火墙拦截、IP配置错telnet从站IP 2404,不通则逐层查网络
连上后发任何报文无回应未进行STARTDT激活或公共地址不匹配先发U帧STARTDT act,再核对公共地址
总召唤只有部分数据总召唤过程中链路断开或序号错乱抓包看序号是否连续,重发总召唤
总召唤收不到激活终止从站上送逻辑异常或数据量过大等待更长时间,检查从站测点表配置
遥控执行后无确认未走选择流程或限定词不对核对选择帧的限定词,确认从站支持的功能
报文能收到但解析乱码长度字节错误或字节序理解错从0x68开始逐字节核对原始报文

6. 一版更贴近现场的扩展思路

如果你的104主站仿真软件已经能稳定完成链路激活、总召唤、遥控这几个基础动作,我建议再往上叠两个实战功能。第一个是模拟多变位场景,即按时间序列连续触发一批遥信变位,验证从站的上送时序是否正确,这在大批量测点联调时尤其有用;第二个是配合GPS或对时报文做网络对时验证,检验从站的时间同步机制,这直接关系到故障录波和SOE时标的准确性。

有一点必须单独拿出来提:104规约虽然标准统一,但不同厂商的实现细节会有差异。有的从站在收到总召唤后会以极快的速度把所有点一次性上送,有的则会在中间插入多个S帧确认,还有的在收到执行命令后会回复两次确认帧。作为仿真主站,我们要做的不是抱怨对端“不合规”,而是想办法让仿真工具兼容这些差异。合理设置接收超时、支持半自动确认模式、允许手动调整发送序号起始值,这些功能看着不起眼,实际联调时却能省下大量时间。

7. 实操中的个人体会

我在实际搭建和使用104主站仿真软件的过程中,最大的感受是“规约串通了,设备就看透了”。一开始总想着找各种高大上的测试平台,折腾下来发现,真正可靠的反而是自己一行一行写出来的那套脚本。它能让我在出问题时随手加日志、随手改逻辑,不用等着厂商售后响应。

最后再分享一个小技巧:无论你用的是现成工具还是自研脚本,一定要把每个收发报文的原始十六进制数据完整记到日志里。很多看似诡异的问题,比如偶然丢失的一帧、多出来的一帧S帧确认,事后回看十六进制日志都能找到规律。有了这份日志,你在跟从站厂商或调度主站团队对接时,沟通效率会高出一个量级。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/9 11:34:30

Skills深度解析:让AI Agent具备可复用工作流的核心机制

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/9 11:34:25

【信息科学与工程学】【制造科学】第八十七篇 精密光学与制造光学核心学科知识01

编号 类型 领域 行业 课程 知识列表及方程式列表 在精密光学与制造光学中的作用 工业级、产业界的应用 关联知识和标准 1 基础理论 几何光学 精密光学 应用光学 知识列表: 光线追迹、近轴成像、像差理论(球差、彗差、像散、场曲、畸变)、孔径光阑、入瞳出瞳、景深…

作者头像 李华
网站建设 2026/9/9 11:33:57

【单片机毕设案例分享】基于 STM32 的定时计时语音控制窗帘系统设计 基于 STM32 的 DHT11 环境检测智能窗帘控制器设计(018207)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于单片机&#xff0c;STM32单片机&#xff0c;51单片机&#xff0c;J…

作者头像 李华
网站建设 2026/9/9 11:33:34

动态偏置OTA深度解析:压摆率与功耗的平衡艺术

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/9 11:33:02

FPGA实现SPI通信实战:从时序设计到Flash读写调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/9 11:31:50

Java 11新特性实战指南:核心API、HttpClient与迁移避坑

Java 11 这个版本&#xff0c;放在整个Java生态里都是一个绕不开的转折点。它既是Java 8之后真正意义上的长期支持版本&#xff08;LTS&#xff09;&#xff0c;又第一次把Oracle JDK的免费许可开放到了个人开发和多数生产场景。很多人问我Java 11有哪些新特性&#xff0c;我自…

作者头像 李华