# modbus-forwarder **Repository Path**: snove/modbus-forwarder ## Basic Information - **Project Name**: modbus-forwarder - **Description**: 工业现场中,单个 Modbus TCP 从站设备通常只支持一个主站连接,无法满足多个上位机、SCADA、PLC 同时接入的需求。本工具作为中间代理,对主站伪装为从站、对从站伪装为主站,实现纯字节流双向透传,不解析任何 Modbus 协议内容。 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: dev - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 15 - **Forks**: 4 - **Created**: 2026-04-16 - **Last Updated**: 2026-05-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README

Modbus TCP 转发工具

工业级 Modbus TCP 纯报文透传平台,解决单个从站设备无法同时接受多个主站并发访问的问题

需求文档 · 架构文档 · 功能扩展

--- ## 界面预览 | 仪表盘 | 连接管理 | |--------|---------| | ![仪表盘](docs/images/仪表盘.png) | ![连接管理](docs/images/连接管理.png) | | 报文日志 | 异常告警 | |---------|---------| | ![报文日志](docs/images/报文日志.png) | ![异常告警](docs/images/异常报警.png) | | 系统设置-本地服务 | 系统设置-从站连接 | |----------------|----------------| | ![本地服务](docs/images/系统设置-本地服务.png) | ![从站连接](docs/images/系统设置-从站连接.png) | | 系统设置-告警阈值 | 系统设置-日志设置 | |----------------|----------------| | ![告警阈值](docs/images/系统设置-告警阈值.png) | ![日志设置](docs/images/系统设置-日志设置.png) | --- ## 项目简介 工业现场中,单个 Modbus TCP 从站设备通常只支持一个主站连接,无法满足多个上位机、SCADA、PLC 同时接入的需求。本工具作为中间代理,对主站伪装为从站、对从站伪装为主站,实现纯字节流双向透传,不解析任何 Modbus 协议内容。 ``` 上位机 / SCADA(主站 1) 上位机 / SCADA(主站 2) ──→ 本工具(代理) ──→ 现场设备(从站) 上位机 / SCADA(主站 N) ``` ## 功能特性 - **零报文解析**:纯字节流透传,不解析任何 Modbus 协议内容,不修改报文数据 - **多主站接入**:支持最多 50 个主站同时连接,FIFO 队列串行调度,避免通讯冲突 - **断线自动重连**:从站断线后自动按策略重连,重连过程实时显示在界面 - **双部署模式**:桌面 GUI 模式(本地单机)+ 无头服务器模式(Docker 部署) - **远程客户端**:独立 JavaFX 客户端,通过网络连接到服务端进行远程管理 - **Web 管理界面**:浏览器访问,深色工控风格,支持多端访问 - **IP 白名单**:可选开启,限制允许接入的主站 IP - **配置持久化**:所有配置通过界面操作,自动保存至 `config.toml` - **告警记录**:异常事件持久化至 SQLite,支持历史查询 ## 项目结构 ``` modbus-forwarder/ ├── modbus-forwarder-common/ 公共模型、事件总线、配置类(被其他模块依赖) ├── modbus-forwarder-core/ 核心转发引擎 + HTTP/WebSocket API(可独立 Docker 部署) ├── modbus-forwarder-ui/ JavaFX 公共 UI 组件库(desktop 和 client 共用) ├── modbus-forwarder-desktop/ 桌面客户端,内嵌 core,适合本地单机使用 ├── modbus-forwarder-client/ 远程客户端,通过网络连接到 core 服务进行管理 ├── modbus-forwarder-server/ 服务端启动入口(无头模式,配合 client 使用) ├── modbus-forwarder-web/ Vue 3 Web 前端,构建产物内嵌到 core ├── config.toml 运行时配置文件(首次启动自动生成) └── docs/ 设计文档 ``` ## 技术栈 | 组件 | 版本 | 用途 | |------|------|------| | Java | 17 LTS | 开发语言 | | Netty | 4.1.108 | 异步 TCP 网络框架 | | Javalin | 6.3.0 | 内嵌 HTTP + WebSocket 服务 | | JavaFX | 17.0.13 | 桌面 GUI | | AtlantaFX | 2.0.0 | JavaFX 主题库 | | Vue 3 | 3.x | Web 前端 | | Naive UI | 2.x | Web UI 组件库 | | SQLite + HikariCP | — | 本地数据持久化 | | Jackson TOML | 2.19.x | 配置文件解析 | | Maven | 3.9.x | 构建工具 | ## 快速开始 ### 环境要求 - JDK 17+ - Maven 3.9+ - Node.js 18+(仅构建 Web 前端时需要) ### 桌面模式(本地单机) 内嵌 core 服务,无需单独启动后端,开箱即用: ```bash mvn install -pl modbus-forwarder-common,modbus-forwarder-core,modbus-forwarder-ui -am mvn javafx:run -pl modbus-forwarder-desktop ``` ### 服务器 + 远程客户端模式 **启动服务端:** ```bash mvn package -pl modbus-forwarder-server -am java -jar modbus-forwarder-server/target/modbus-forwarder-server-1.0.0.jar ``` **启动远程客户端:** ```bash mvn javafx:run -pl modbus-forwarder-client # 在连接对话框中输入服务端地址和端口 ``` ### Docker 部署 ```bash # 构建镜像 docker build -t modbus-forwarder modbus-forwarder-core/ # 运行容器 docker run -d \ -p 8080:8080 \ -p 5020:5020 \ -v $(pwd)/config:/app/config \ -v $(pwd)/logs:/app/logs \ --name modbus-forwarder \ modbus-forwarder # 访问 Web 管理界面 open http://localhost:8080 ``` ### Web 前端开发模式 ```bash cd modbus-forwarder-web npm install npm run dev # 访问 http://localhost:3000 ``` ## 配置文件 首次运行自动生成 `config.toml`,也可手动编辑: ```toml localPort = 5020 # 本工具监听端口(502 需要 root 权限)⚠ 需重启 slaveHost = "127.0.0.1" # 从站 IP ⚠ 需重启 slavePort = 502 # 从站端口 ⚠ 需重启 connectTimeoutMs = 5000 # 连接超时(ms) requestTimeoutMs = 3000 # 请求超时(ms) 热更新 reconnectIntervalMs = 5000 # 重连间隔(ms) 热更新 maxReconnectTimes = -1 # 最大重连次数,-1 表示无限 热更新 maxMasterCount = 50 # 最大主站连接数 热更新 whitelistEnabled = false # 是否启用 IP 白名单 热更新 whitelist = [] # 允许接入的主站 IP 列表 热更新 ``` ## REST API | 方法 | 路径 | 说明 | |------|------|------| | GET | `/api/config` | 获取当前配置 | | PUT | `/api/config` | 保存配置(热更新项立即生效) | | POST | `/api/service/start` | 启动转发服务 | | POST | `/api/service/stop` | 停止转发服务 | | GET | `/api/status` | 查询运行状态和统计数据 | | POST | `/api/slave/reconnect` | 手动触发从站重连 | | DELETE | `/api/master/{channelId}` | 断开指定主站连接 | | WS | `/ws/events` | 实时事件推送(WebSocket) | ## 监听低端口(502) ```bash # Linux 一次性授权(推荐) sudo setcap 'cap_net_bind_service=+ep' $(which java) ``` ## 许可证 [Apache License 2.0](./LICENSE)