简介:这是一款面向半导体等制造业设备通信调试场景的SECS-II/HSMS模拟器工具,适合MES上位机开发、设备端程序联调及协议学习人员使用。它可模拟服务端或客户端,帮助验证自编SECS-II报文、连接交互与通信流程是否符合客户或产线要求,降低联调阶段的排查成本。压缩包共4个文件,包含可执行程序、XML配置与样例数据以及使用说明文本,整体约90KB,体积轻便,便于快速部署和离线测试。已有2855人学习下载,说明其在相关调试场景中具备一定参考价值。借助内置默认配置与样板文件,读者可对照说明完成基础连接、消息收发与数据格式校验,并以此为模板扩展自己的测试用例,适合需要快速搭建HSMS通信验证环境、梳理报文调试思路的初中级工程师。
1. 联调现场最常见的失败:SECS-II/HSMS 模拟器装好了,却连不上设备
半夜被叫去看一条产线的通信,日志里全是 T3 超时,主机侧显示未连接,模拟器这边显示已经在监听,两边都觉得自己没问题。这类场景在设备联调里很常见:上位机、设备端、SECSII 调试工具三方,只要有一边的 Active/Passive 角色配反,HSMS 报文就永远对不上。SECS 调试工具不像一般桌面软件,装完不等于能用,端口、角色、定时器、样板文件任何一处没落位,表现都是一样的“没反应”。
这份 SECS-II HSMS 调试工具模拟器(带样板文件)适合三类人:刚接手 SECS 报文对接的开发者、要给设备做离线回环测试的工程师、手上没有真机只能靠模拟器造数据的人。下面按装前清单、安装、参数配置、排错、验证的顺序走一遍。
2. 装前清单:HSMS 角色、端口与运行库三件事先定死
装之前先花二十分钟把这三件事确认掉,后面能省掉一整晚的无效排查。HSMS 是跑在 TCP 之上的会话层协议,它不负责发现对端,也不负责重传,所以“谁去连谁”“连哪个端口”“本机有没有跑起来所需的运行库”这三件事只要错一件,工具界面看上去完全正常,但一条报文都收不到。我一般的顺序是:先画拓扑定角色,再定端口并放行防火墙,最后确认运行库和目录,再解压。
这一步别急着双击程序。HSMS 的坑大多不在工具本身,而在外围:端口被别的进程占了、防火墙把入站丢了、程序放在带中文的路径下读不到样板文件。这些都属于“装完才发现”的类型,提前十分钟排掉,比事后抓包快得多。
2.1 先定角色:Active 与 Passive 只能有一个监听方
HSMS 的连接建立非常朴素:Active 方主动发起 TCP connect,Passive 方 listen 并 accept。HSMS-SS(单会话)场景下,一个端口只承载一条会话,不存在两端都监听然后互相等的情况。常见做法是设备端做 Passive、主机或模拟器做 Active;也有现场反过来,把模拟器当服务端,让设备来连。两种都行,关键是别配成一样。
| 角色 | 行为 | 典型落位 | 配错的后果 |
|---|---|---|---|
| Active | 主动 connect,断开后按 T5 重试 | 上位机、模拟器 | 对端也是 Active 时被拒,日志报连接被重置 |
| Passive | listen 并 accept,端口被独占 | 设备端、被测端 | 对端也是 Passive 时双方死等,永远无连接 |
确认本机端口有没有被占,别靠任务管理器猜,直接用命令行看:
# 以管理员身份运行,查 5000 端口是否已被监听或被占用 Get-NetTCPConnection -LocalPort 5000 -ErrorAction SilentlyContinue | Select-Object LocalAddress, LocalPort, State, OwningProcess # 拿到 OwningProcess 后反查进程名,确认是不是上一个没退干净的模拟器实例 Get-Process -Id (Get-NetTCPConnection -LocalPort 5000).OwningProcess第一段命令列出的 State 如果是Listen而你又打算让本工具做 Passive,说明端口已经被别的程序占着,后面启动必然绑定失败,只是有些工具会把错误吞进日志文件而不弹窗。第二段命令用来确认占用者身份,最常见的就是上次调试没关掉的旧实例,任务管理器里它可能伪装成同名进程,看着像同一个。
2.2 端口与防火墙:5000 只是习惯用法,不是协议规定
HSMS 并没有强制端口号,5000 是现场沿用最广的默认值,改端口完全合法,只要两端一致。真正容易被忽略的是防火墙:本机回环测试(127.0.0.1)不经过防火墙,所以很多人本机自测通过、一到跨机联调就挂,原因就是入站规则没放行。做 Passive 的那一端必须允许对方连进来。
# 只对专用网络放行 5000/TCP 入站,别图省事放开所有配置文件 New-NetFirewallRule -DisplayName "HSMS-Sim-5000-In" ` -Direction Inbound -Protocol TCP -LocalPort 5000 ` -Action Allow -Profile Private # 验证规则是否生效 Get-NetFirewallRule -DisplayName "HSMS-Sim-5000-In" | Format-List Name,Enabled,Direction,Action-Profile Private是关键参数,默认的 Domain/Public 混用会把规则开到不可控的网络环境里,现场机器经常既连内网又插临时网线,限定 Private 更符合实际。-LocalPort要跟配置文件里的 Port 完全一致,改端口时记得同步改规则名,否则下次排查会因为名字对不上而漏看。
另外提醒一句:低于 1024 的端口在部分系统上需要管理员权限才能绑定。如果非要用 1024 以下的端口做 Passive,程序必须提权启动,否则表现为“启动成功但立刻退出”,日志里只有一行绑定失败。
2.3 运行库与目录:路径别带中文和空格
这类工具大多是桌面程序,依赖系统里已有的运行库。装之前先确认版本,别等启动报错再去补。
| 检查项 | 建议值 | 不满足时的表现 |
|---|---|---|
| 系统位数 | 64 位 | 32 位系统上部分功能直接不可用 |
| 运行库 | 与工具说明一致,常见做法是补齐对应版本 | 双击无反应,或提示缺少组件 |
| 安装路径 | 纯英文、无空格,如D:\SECS\sim | 样板文件路径解析失败、日志写不出 |
| 权限 | 普通用户可读写安装目录 | 运行中保存配置失败 |
目录结构我一般手工建成这样,后面所有配置都按这个相对路径写,换机器时整目录拷走就能用:
D:\SECS\sim\ ├─ bin\ # 主程序与依赖 ├─ conf\ # 端口、定时器、会话参数 ├─ samples\ # 样板文件,SML 格式的消息模板 └─ logs\ # 十六进制收发日志,排错主要靠它把样板文件单独放samples,是为了让配置里的路径保持相对,不写死盘符。很多人把样例和程序堆在一个目录里,程序一升级、目录一覆盖,样板就没了,这属于没必要付的代价。
提示:装之前先在目标机器上把系统时间校一下。HSMS 定时器是按秒算的,机器时间漂移过大时,日志时间戳会和设备侧对不上,排查时很容易误判成响应慢。
3. 安装与首次启动:解压式工具的三步落地
这类调试工具基本是绿色包,没有安装向导,所以“安装”这个词其实要拆成三步:解压到正确位置、首次启动让它生成默认配置、把样板文件挂进去。三步里任何一步跳了,程序都能打开,但跑不通。下面按顺序来,每一步给出判断成功的方法,别凭感觉判断“应该好了”。
3.1 解压与目录落位
先把压缩包解到临时目录,再整体移动到目标路径,不要直接解压到桌面再双击运行。桌面路径通常带用户名,中文用户名在国内机器上很常见,而部分老版本程序对非 ASCII 路径处理得不干净,表现为启动后日志目录为空、样板文件列表空白。
# 建目录、解压、确认文件齐全,再补一个可写检查 New-Item -ItemType Directory -Force -Path D:\SECS\sim | Out-Null Expand-Archive -Path .\secs-sim.zip -DestinationPath D:\SECS\sim -Force Get-ChildItem D:\SECS\sim -Recurse -File | Measure-Object | Select-Object Count # 确认当前用户对目录有写权限,日志和配置都要写在这里 $p = "D:\SECS\sim\logs" "probe" | Out-File -FilePath "$p\_w.tmp" -Encoding ascii Remove-Item "$p\_w.tmp"第二条命令看起来多余,实际很值:从压缩包解出来的目录有时会继承只读属性,程序能启动但写不了日志,最后你手里一个字节的收发记录都没有,排错等于闭着眼睛。写一个探针文件再删掉,比事后猜要快。
解压完顺手核对一下文件数量与目录层级是否和资源说明对得上,缺文件的情况多半是解压中断或杀毒软件拦截,重解一次即可,不用怀疑程序本身。
3.2 首次启动与配置生成
第一次启动建议用命令行拉起,这样标准错误不会丢。双击运行时如果程序在初始化阶段就退出,窗口一闪而过,什么信息都留不下。
# 切到程序目录再启动,避免相对路径按当前工作目录解析 Set-Location D:\SECS\sim\bin .\SecsSim.exe 2>&1 | Tee-Object -FilePath D:\SECS\sim\logs\startup.log2>&1把标准错误并入标准输出,Tee-Object同时打到屏幕和文件。这两步是为了拿到启动阶段的真实报错,尤其是缺少运行库、找不到配置文件这类问题,控制台里会有一行明确提示,而弹窗往往只写“初始化失败”。
首次启动成功后,conf目录下应该出现默认配置文件。如果目录是空的,说明程序把配置写到了用户目录(部分程序会这么做),这时要以实际生成的路径为准,别硬按文档里的相对路径配,否则改了不生效。判断方法很简单:改一个显眼的参数(比如端口),重启后看界面上的值有没有变。
logs目录下同时会生成当天的日志文件。这个文件是全篇最重要的东西,后面所有排错都围绕它。建议第一件事就是把日志级别调到十六进制模式,能同时看到帧头和载荷,纯文本模式只能看到解析后的结构,出问题时看不出长度字段错在哪。
3.3 导入样板文件与建第一条消息
带样板文件是这个资源最省事的地方。样板就是几条预先写好的 SML 消息模板,省掉手敲嵌套列表的功夫,也避免长度字段算错。导入方式各版本略有差异,通常是配置里指定samples目录,或者界面上有个“加载模板”的入口。
导入后先别急着改内容,用它原样发一条最简单的 S1F1,确认链路和编码都通,再去改业务消息。这个顺序很重要:先验证通路,再验证内容,两个变量一起动,出问题时说不清是谁的锅。
确认样板加载成功的标志有三个:模板列表里能看到条目名、消息结构树能展开、长度字段不是 0。第三点最容易被忽略,长度字段为 0 的消息发出去,对端只会回一个解析错误,而你这边看起来是“发送成功”,非常容易误判成对端问题。
4. 参数配置:把 HSMS 连接项和 T3/T5/T6/T7 填对
配置文件是这套东西的黑匣子,装的时候没人细看,出问题时全靠它。参数不多,但每个都有明确的物理含义,乱填不会立刻报错,只会在某个特定时序下暴露出来。下面按连接四要素、定时器、报文层、日志四块拆。
4.1 连接四要素:IP、端口、角色、Device ID
[HSMS] Role = Active ; Active=主动连,Passive=监听 Host = 192.168.10.20 ; Active 时填对端地址;Passive 时留空或 0.0.0.0 Port = 5000 ; 两端必须一致 DeviceID = 0 ; 会话内的设备号 SessionID = 0 ; HSMS-SS 固定 0,多会话才需要区分Role决定程序启动后是 listen 还是 connect,前面已经讲过,这里只强调一点:改完角色必须重启会话,热切换在多数实现里不生效,界面上的状态灯可能还是绿的,实际链路早就断了。DeviceID是 SECS-II 层的字段,不是 TCP 层的,它出现在每条消息头里,对端按它判断这条消息属于哪台设备。主机侧常用 0,设备侧用 1 以上的值,两边不一致时对端会丢包而不回错,表现为“发出去了但没回应”,属于典型的无声失败。
Host在 Passive 模式下不要填成具体的本机网卡地址,除非机器有多张网卡且你明确知道要走哪一张。填0.0.0.0表示所有网卡都监听,联调阶段这么配最省事,等确定链路后再收窄。
4.2 定时器:T3 到 T8 各自的含义与取值
HSMS 的定时器是超时重试的全部依据,配小了误判掉线,配大了故障发现不及时。
| 定时器 | 含义 | 常见取值 | 配错的典型症状 |
|---|---|---|---|
| T3 | 等对端回复的超时 | 45 s | 配太小,正常慢响应被判成超时 |
| T5 | 断线后重连间隔 | 10 s | 配太小,对端日志被重连刷屏 |
| T6 | 控制报文(Select 等)超时 | 5 s | 配太大,Select 失败后长时间挂起 |
| T7 | 连上但未 Select 的等待上限 | 10 s | 配太大,假连接状态持续很久 |
| T8 | 单包内字符间超时 | 5 s | 配太小,大包被当成半包丢弃 |
[HSMS.Timers] T3 = 45 ; 秒,业务消息回复超时 T5 = 10 ; 秒,TCP 断开后的重连间隔 T6 = 5 ; 秒,控制事务超时 T7 = 10 ; 秒,连接建立到 Select 完成的上限 T8 = 5 ; 秒,报文内字符间隔超时 Linktest = 30 ; 秒,链路测试周期,0 表示关闭取值的原则是跟着对端走,不是跟着感觉走。设备侧把 T3 设成 45 秒,你这边的 T3 就不能是 20 秒,否则设备还在算,你已经判超时并重发,对端会收到两条重复消息。T5 和 Linktest 一起看:Linktest 周期要明显小于 T5,否则链路测试还没跑完就被重连打断,日志里会看到反复的连接建立与断开。
T8 是最容易被忽略的一个。它限制的是单个报文内字符到达的间隔,网络抖动大或者对端一次发大包时,把 T8 设成 1 秒会导致半包被丢,日志里表现为“收到一部分就没了”,很容易被误判成对端发了残帧。
4.3 SECS-II 报文层:Stream/Function 与 SML 样板
HSMS 只负责把字节送达,字节里面是什么由 SECS-II 定义。调试工具一般以 SML(文本形式)录入消息,运行时转成二进制发出去。样板文件里的条目大致长这样:
'S1F1' W . 'S1F2' W <L [2] <B [1] 0x00> <L [2] <A [6] 'SIM001'> <A [8] '1.0.0.0 ' > > .'S1F1'是消息名,W表示带 W-bit,即要求对端回复;末尾的.是消息结束符,少了它解析器会一直等后续内容。<L [2]>是长度为 2 的列表,<B [1] 0x00>是一个字节的二进制,<A [6]>是 6 字节的 ASCII,注意长度必须和实际内容严格一致——'1.0.0.0 '末尾补了一个空格凑到 8 字节,这不是笔误,是长度字段决定的,去掉空格就变成 7 字节,长度对不上,对端解析直接报错。
改样板时只改内容、不动长度,是新手最容易踩的一步。正确做法是改完内容同步改方括号里的数字,或者干脆让工具重新计算长度后再发。
4.4 日志与多套配置切换
[LOG] Dir = .\logs Level = HEX ; NONE / SUMMARY / HEX RotateMB = 50 ; 单个日志文件上限,超过自动切分 [SAMPLE] Dir = .\samples AutoLoad = S1F1,S1F13,S2F17Level = HEX在排错阶段必开,十六进制模式下能看到帧头、长度字段和载荷的原始字节,是定位编码问题的唯一依据;稳定联调之后可以降到SUMMARY,避免日志膨胀。RotateMB别设太大,一个通宵的十六进制日志能到几百兆,切分文件比单文件更容易定位时间点。
多套配置的做法是复制一份conf目录,按现场命名,比如conf_lineA、conf_lab,切换时整目录替换。别在一个配置文件里删删改改,改到最后自己都记不清原始值是多少,这条属于反复验证过的经验。
5. 排查:连不上、连上就断、报文乱码的现场记录
前面几步都做完仍然不通,就进入排错环节。按层次往下切:先看 TCP 有没有通,再看 HSMS 会话有没有 Select 成功,最后才看 SECS-II 内容。跳过前两层直接看报文,是最浪费时间的做法。
5.1 连接层:连不上与连上就断
现象:主动连接时报连接被拒绝,对端日志里没有任何记录。原因是角色配反或者端口不一致。两端都设成 Passive 时,谁都不会发起 connect,双方各自显示“监听中”;两端都设成 Active 时,先发起的那一方会被拒。解决方式是回到拓扑图确认谁是服务端,只保留一个 Passive,另一个改 Active 并核对端口号是否逐位一致。
现象:TCP 能连上,几秒后自动断开,日志里出现 Select 超时。原因通常是 T7 到期仍未完成 Select 交互,常见于对端还在初始化、或者 DeviceID 不匹配导致对端不认这条会话。解决方式是先看对端是否已完成上线流程,再把 T7 从 10 秒临时放宽到 30 秒验证;如果放宽后能连上,说明是对端启动慢,不是配置错,把 T7 调回合理值即可。
现象:连接反复建立又断开,间隔几乎等于 T5。原因是链路测试周期和重连间隔冲突,或者对端 Linktest 没实现、回了错误控制帧。解决方式是把 Linktest 周期调到明显大于 T5,或者联调阶段直接关掉(设为 0),先确认业务消息能通,再回头处理链路保活。
5.2 报文层:乱码与半包
现象:日志里能看到字节,但解析出来是乱码或者结构树展不开。原因是长度字段与实际内容不符,或者 W-bit 处理不一致(对端期望回复、你发了不带 W 的消息)。解决方式是把日志级别切到 HEX,逐字节核对长度字段:SECS-II 的长度字段按内容实际字节数算,不是按字符数算,中文、全角字符在这类工具里基本不该出现。
现象:大消息只收到前半部分,之后就没有下文。原因是 T8 设得过小,报文内字符间隔超时导致半包被丢弃。解决方式是把 T8 从 5 秒放宽到 10 秒复测,同时在日志里确认是否只有超过一定长度的消息才出问题——这个特征一旦对上,基本可以确定是 T8。
现象:对端回了一个错误码,但看不出是哪条消息触发的。原因是并发发送多条消息时没有带 System Bytes 或者带了重复值,对端的回复对应不上请求。解决方式是串行发送,一条发完等到回复再发下一条,联调阶段不要贪快。
5.3 文件与权限:样板加载失败
现象:模板列表为空,或者加载时报文件不存在。原因是配置里写的是绝对路径,换机器后盘符变了;也可能路径里带中文或空格。解决方式是把samples放到程序目录下,配置一律用相对路径.\samples,并且确认文件名与AutoLoad里列出的条目名完全对应,大小写敏感这件事在部分实现上确实存在。
现象:程序能启动,但运行中保存配置失败。原因是安装目录在受保护位置(比如系统盘根目录下),普通用户没有写权限。解决方式是把整个目录移到非系统盘,或者对目录显式授予当前用户修改权限,别用管理员身份长期运行来绕过权限问题,那样日志文件的所有者会变乱,后面排查更麻烦。
注意:每次改完配置都要完整退出程序再启动,不要只关窗口。部分实现会在退出时回写配置,直接杀进程会导致改动丢失,而你以为已经生效了。
6. 验证跑通:用样板文件走一遍 S1F1 回环
装完不要急着接真实设备,先用本机回环把整条链路走通。这一步的价值在于把所有变量收敛到最小:只有一台机器、一个程序、两个会话实例,任何失败都只能是配置问题,不会牵扯到网络和设备行为。我的做法是开两个实例,一个 Passive 监听 5000,一个 Active 连 127.0.0.1:5000,然后发一条 S1F1。
先确认端口在听:
# 确认 Passive 实例已在监听,状态应为 Listen Get-NetTCPConnection -LocalPort 5000 -State Listen | Select-Object LocalAddress, LocalPort, State # Active 实例启动后,确认连接已建立,应能看到一对 Established Get-NetTCPConnection -LocalPort 5000 | Select-Object LocalAddress, RemoteAddress, State第一段出现Listen、第二段出现一对Established,说明 TCP 层通了。这一步不过,后面所有报文验证都没有意义,直接回第 5.1 节查角色和端口。
TCP 通了之后看会话层。在 Active 实例里发 S1F1,正常时序是:连接建立、Select 交互完成、S1F1 发出、对端回 S1F2、T3 内收到。日志里按这个顺序能对上,就说明 HSMS 会话和 SECS-II 编码都没问题。S1F2 的载荷里会带回设备标识和版本号,这两个值取自样板文件,改样板再发一次,看回复里的值有没有跟着变,能立刻验证编码是否正确。
| 验证点 | 通过标准 | 不通过时先看哪 |
|---|---|---|
| TCP 连接 | 出现一对 Established | 角色、端口、防火墙 |
| HSMS 会话 | 日志出现 Select 完成 | T6、T7、DeviceID |
| SECS-II 编码 | S1F2 能正常解析出结构树 | 长度字段、W-bit |
| 业务回环 | 改样板后回复内容同步变化 | samples 路径、AutoLoad |
| 时序 | 回复在 T3 内到达 | T3 取值、对端处理耗时 |
最后补一个容易被跳过的动作:把日志级别从 HEX 降回 SUMMARY,再跑一次同样的 S1F1。很多人只在高日志级别下验证过,切回正常级别后发现连接行为变了,原因是日志写入本身影响了时序。两种级别各跑一遍,都通过才算真的通过。
从那以后我每次装这套模拟器,都强制先走一遍本机 S1F1 回环,再动任何业务消息——跳过这一步直接接设备,出问题时你分不清是工具没装好还是设备不配合,那个排查成本要高一个数量级。希望帮到你。
本文还有配套的精品资源,点击获取