在 Niagara Station 现场,经常会遇到几类网络转发需求:

glineSocat 就是为这类场景做的一个 Niagara 组件(类型:glineSocat:SocatChannel,平台 Niagara 4.14)。本文按“组件使用说明”的口径,把参数、四种转发模式、动作和常见排查点整理出来,现场照着填即可。

一、glineSocat 到底是什么

glineSocat 是一个跑在 Niagara 4 Station 里的组件。它做的事情非常朴素:

可以把它理解成一个内嵌在 Niagara 里的 socat——区别是不用写命令行,所有参数都在 Property Sheet 里填,改完点一下按钮就热重载。相比在主机上再挂一个 socat / 端口转发进程,它还有几个好处:

随站启停

挂 station 生命周期:站起它就起、站停它就停,不用写计划任务或系统服务。

无需外部软件

除模块本身,主机上不用安装任何额外程序。

可被 Niagara 管理

状态、字节统计、日志都是站点里的槽位,可在 Workbench / 网页 / oBIX 查看与操作。

二、五步跑起来

步骤在 Workbench / 网页里做什么
① 放组件Workbench 切到 station,把 SocatChannel 拖到某个 Folder(如 PortForward/)
② 填表格打开组件的 Property Sheet,按下面的样例填参数
③ 保存点 Save;网页端要双击改值再点 Save
④ 启动默认 enabled=true 会自动起;改过配置后点动作 restartRelay 热重载
⑤ 看状态看 status / connCount / rxBytes / txBytes / log 确认在跑

记住一个对应关系:mode 选方向,listen* 是“从哪收”,remote* 是“往哪发”。

三、属性表全字段

前 9 个字段需要自己填,后 5 个是只读的运行观察值。

字段类型 / 默认说明
enabledboolean / true总开关。true=组件启动时自动开监听;false=不自动起
modestring / tcp-tcp转发方向,四选一:tcp-tcp / udp-udp / tcp-udp / udp-tcp
listenHoststring / 0.0.0.0本机监听地址。一般填 0.0.0.0(所有网卡)或本机 IP
listenPortint / 8090本机监听端口,注意别和站里已有服务冲突
remoteHoststring / (空)目标地址(IP 或域名),必填,如 192.168.2.180
remotePortint / 80目标端口,如 80 / 161 / 502
backlogint / 50TCP 等待接入队列长度(仅 tcp-tcp / tcp-udp 用),不是最大连接数
idleTimeoutMsint / 0空闲超时毫秒。0=不限;>0 时读写卡住超过该时间就断开。UDP 等回包也用这个值(0 时默认 4000ms)
hexLogboolean / falsetrue=把经过的报文按十六进制写进 log(调试用)。会让日志量明显增大,不建议长期开
status只读运行状态,如 OK udp-udp listening 8090
rxBytes / txBytes只读累计接收 / 发送字节数
connCount只读累计连接数(只统计 TCP 接入;udp 模式下为 0)
log只读操作日志,最近 4000 字符
glineSocat 属性表

图 1 · SocatChannel 属性表(示意:本机监听 8090 → 目标 161,udp-udp)

四、四种转发模式

4.1 tcp-tcp —— TCP 进,TCP 出

把站上某端口转发到另一台设备的 TCP 端口。典型场景:网页管理口、Modbus TCP、任意 TCP 服务。

字段填这个值
modetcp-tcp
listenHost / listenPort0.0.0.0 / 8090
remoteHost / remotePort192.168.2.180 / 80
backlog / idleTimeoutMs / hexLog50 / 0 / false
# 客户端访问站上的 8090,就等于访问目标设备的 80
curl http://192.168.2.112:8090/home.htm
# status: OK tcp-tcp listening 8090   (connCount 会 +1)

数据流:客户端 → TCP 监听 8090 → 站内建 TCP 连到 180:80 → 双向对拷。若目标不可达或端口不通,log 会记 tcp bridge err,但 status 仍显示 listening。

4.2 udp-udp —— UDP 进,UDP 出

适合 SNMP 这类“一问一答”的 UDP 协议。每收到一个请求包,新开一个 UDP socket 发出去,等一个回包(最多等 idleTimeoutMs,默认 4000ms)再送回客户端。

字段填这个值
modeudp-udp
listenHost / listenPort0.0.0.0 / 8091
remoteHost / remotePort192.168.2.180 / 161
idleTimeoutMs0(或 4000 等回包)
snmpget -v1 -c public 192.168.2.112:8091 1.3.6.1.4.1.318.1.1.12.1.5.0
# 期望: 读回设备型号字符串
注意:udp-udp 只支持“一来一回”,纯推送 / 长连接的 UDP 流不适用;它解决的是“同协议 UDP 转发”,并不解决“客户端只会 TCP、设备只回 UDP”这种协议不一致的问题——那种场景要用下面的桥接模式。

4.3 tcp-udp —— TCP 进,UDP 出(桥接)

客户端只会说 TCP,目标设备只会说 UDP。比如监控平台用 TCP 连过来,组件把字节原样塞进 UDP 包发给目标的 SNMP 端口。

字段填这个值
modetcp-udp
listenHost / listenPort0.0.0.0 / 8092
remoteHost / remotePort192.168.2.180 / 161
hexLogtrue(调试期可开)

数据流:客户端开 TCP 连到 8092 → 站把 TCP 字节原样丢进一个 UDP 包发给 180:161 → 等 UDP 回包 → 原样写回 TCP 连接。

4.4 udp-tcp —— UDP 进,TCP 出(反向桥接)

反向桥接:客户端只发 UDP,目标是 HTTP/TCP 服务。

字段填这个值
modeudp-tcp
listenHost / listenPort0.0.0.0 / 8093
remoteHost / remotePort192.168.2.180 / 80
idleTimeoutMs0(或自定义)

数据流:收到一个 UDP 包 → 新建一条 TCP 连到 180:80 → 把包内容发过去 → 读一次 TCP 响应 → 用 UDP 发回给客户端。

4.5 四种模式速查

mode 填法客户端 → 站站 → 目标典型用途
tcp-tcpTCP(长连接)TCP(长连接)网页转发、Modbus TCP、任意 TCP 服务
udp-udpUDP 一问一回UDP 一问一回SNMP 轮询、简单 UDP 查询
tcp-udpTCPUDP客户端只会 TCP,设备只回 UDP(如 SNMP 桥接)
udp-tcpUDPTCP客户端只会 UDP,目标是 TCP/HTTP 服务

选法:两边协议相同 → tcp-tcp / udp-udp;两边协议不同 → tcp-udp / udp-tcp 桥接。

五、日志里那条 “no matching transaction” 怎么读

在 udp-udp 转 SNMP 的调试过程中,日志里出现过这样一条:

Receive response with no matching transaction from null

先把截图里的字段读清楚,再判断它属于哪一层的问题:

字段截图值含义
ReqID0本地没有找到对应的请求事务 ID
Var Bind1.3.6.1.6.3.15.1.1.5.0 COUNTER: 640OID 是 usmStatsUnknownEngineIDs,表示“未知的 SNMP Engine ID”计数
pduType168对应 SNMP Report PDU,不是普通响应
isResponsetrue这是一个响应包
source IP / Remote Port192.168.2.180 / 161来自 PDU 本身

从 OID 和 pduType 看,这条日志更像是 SNMPv3 USM 层的问题:目标设备在报 usmStatsUnknownEngineIDs,意思是它收到的请求里 Engine ID 对不上,于是回了一个 Report PDU 说明情况。这属于 SNMP 协议层 / 认证层的不匹配,而不是 glineSocat 中继本身超时或丢包的典型表现。

因此排查顺序建议这样:

  1. 先看协议层:确认客户端和目标设备用的 SNMP 版本(v1/v2c/v3)、community 或 USM 用户名 / Engine ID 是否对齐。OID 落在 usmStats* 这一组时,先查 SNMPv3 的 Engine ID 协商和认证配置。
  2. 再看中继层:确认 remoteHost/remotePort 填对、目标 161 端口可达、idleTimeoutMs 给够(默认等回包约 4000ms)。
  3. 最后看轮询节奏:短时间高频并发请求、回包乱序到达,也可能让本地事务对不上,但这通常伴随连接数和重传异常,不会单独以 usmStatsUnknownEngineIDs 的形式出现。
UDP 中继十六进制调试日志

图 2 · hexLog=true 时的十六进制报文日志(调试用,看完请关掉)

六、并发与 CPU 消耗

先说结论:组件里没有 maxClients 这类并发上限参数,代码未做限流,来多少接多少。真正的天花板是 JVM 线程数、文件描述符和内存,不是吞吐量。
问题实际情况
有没有最大客户端数?组件里没有 maxClients 属性,代码未做并发上限
每个客户端一个线程?TCP 每连接 1 个处理线程;UDP 桥接是每收到一个包起一个线程
backlog 是上限吗?不是,它只是“已握手、未 accept”的排队缓冲,默认 50
真正的天花板在哪?JVM 线程数 / 文件描述符 / 内存

CPU:空闲或少量连接时线程阻塞在 read(),几乎不占 CPU;数据吞吐是纯 IO 搬运,开销很低。主要成本在长连接数——每多一条 TCP 长连接就多一个线程。工程上普通场景 <200 并发 TCP 连接无压力;大批长连接建议把 idleTimeoutMs 设上限,hexLog 不要长期开。

七、改完配置怎么生效:5 个动作

动作在属性表的 Actions 区。最关键的是 restartRelay——改了 mode / 端口 / remoteHost 等属性后,监听不会自动重建,必须点一次。

动作作用什么时候点
startRelay启动监听 / 中继enabled=false 时手动起
stopRelay停止中继、断开所有连接维护 / 换配置前
restartRelay停止再启动(热重载)改完任何配置后点它
clearLog清空 log日志太长时
clearStatsrxBytes/txBytes/connCount 归零重新测流量前
# oBIX 调动作(命令行)
curl -u 'Obix:<密码>' -X POST \
  'http://HOST/obix/config/PortForward/SocatChannel/restartRelay/'
# 网页端: 属性表下方 Actions 区,找到 restartRelay 点一下

八、常见问题排查

现象可能原因怎么处理
status = ERR BindExceptionlistenPort 被占用换端口,或先停占用它的服务
status 一直 listening 但连不上防火墙 / 目标不可达查站所在机器防火墙;看 log 有没有 bridge err
log 里 tcp bridge errremoteHost/remotePort 填错或设备没开ping/curl 目标,确认端口开放
改了配置没变化没热重载点 restartRelay
UDP 收不到回包目标不回 / 回太慢调大 idleTimeoutMs;确认协议是一问一回
数据能通但看不懂想抓包hexLog=true 看十六进制日志(用完关掉)

九、用 oBIX 脚本化配置

不想点网页时,可以用 oBIX 写属性。注意必须 PUT 带 obix XML,POST 纯文本会报错。

# 读全部属性
curl -u 'Obix:<密码>' 'http://HOST/obix/config/PortForward/SocatChannel/'

# 写字符串(PUT + obix XML)
curl -u 'Obix:<密码>' -X PUT -H 'Content-Type: text/xml' \
  --data '<str val="192.168.2.180"/>' '.../SocatChannel/remoteHost/'
# 写整数
curl ... -X PUT --data '<int val="80"/>' '.../SocatChannel/remotePort/'
# 写布尔
curl ... -X PUT --data '<bool val="true"/>' '.../SocatChannel/enabled/'

# 错误做法(会失败):POST 纯文本 → EOFException;POST <str> → 类型转换错误
# 调动作用 POST .../restartRelay/ ;创建对象请用 Workbench / 网页拖组件

十、小结

同协议转发用 tcp-tcp / udp-udp;两边协议不一致才用 tcp-udp / udp-tcp 桥接。日志里出现协议层(如 SNMP usmStats*)的回包时,先按对应协议本身的原因排查,再看中继层的超时和可达性。

FAQ 常见问题

glineSocat 和直接在主机上跑 socat 有什么区别?
glineSocat 是跑在 Niagara Station 内的原生组件,随站启停、无需额外进程/服务;参数在 Property Sheet 里填,状态、字节统计和日志都是站点里的槽位,可以在 Workbench / 网页 / oBIX 里观察和操作。而主机上的 socat 需要自己写服务或计划任务来保活,也脱离了 Niagara 的管理视野。
它能做协议桥接吗?普通端口转发做不到的那种。
能。tcp-udp(客户端 TCP、目标是 UDP)与 udp-tcp(客户端 UDP、目标是 TCP)就是协议桥接,这是纯端口转发工具不具备的能力。普通的端口转发只能“同协议”,glineSocat 还多出这两种跨协议模式。
改了 mode / 端口,为什么没生效?
改属性不会自动重建监听,必须点一次 restartRelay 热重载。唯一例外是站点首次启动、且 enabled=true 时会自动启动。改完记得看 status 是否变成 OK <mode> listening <port>。
UDP 收不到回包怎么办?
先确认协议本身是不是“一问一回”(udp-udp / 桥接都只支持一问一回,不支持流式或服务端主动推送);再确认目标端口可达、idleTimeoutMs 是否给够(0 时等回包默认约 4000ms)。如果日志出现 usmStats* 之类协议层回包,要先按 SNMP 版本 / Engine ID 等协议原因排查。
能带多少并发?会不会很吃 CPU?
组件没有 maxClients 之类的并发上限,也不做限流;真正的天花板是 JVM 线程数、文件描述符和内存。空闲时几乎不占 CPU,主要成本是长连接(每条 TCP 长连接一个线程)和 hexLog。普通场景 <200 并发 TCP 连接无压力;大批长连接建议设 idleTimeoutMs 上限并关掉 hexLog。
📂 所属分类:技术文档与教程