使用modbus-serial连接Modbus TCP遇PortNotOpenError问题求助
问题描述
我正尝试使用JavaScript的modbus-serial库连接Modbus TCP,已确认IP地址和端口正确,网络无防火墙(即便有,也已有两款工具可成功连接Modbus设备并执行操作),但仍出现如下错误:
PortNotOpenError {
name: 'PortNotOpenError',
message: 'Port Not Open',
errno: 'ECONNREFUSED'
}
我的代码如下:
const ModbusRTU = require("modbus-serial"); console.log("Imported Library"); const client = new ModbusRTU(); console.log("Defined Client"); client.connectTCP("", { port: }); console.log("Connected to Modbus TCP server"); console.log(""); client.writeCoil(2000, 0x01, function (err) { if (err) { console.error(err); } else { console.log("Coil successfully set!"); } });
注:代码中的IP和端口已隐去。我原本期望通过这段代码开启大厅的空调,但却出现了上述错误。
另外,第一款可用工具价格过高,第二款免费但无法自定义界面,因此我选择使用NodeJS(v20.10.0)来实现自定义界面。我尝试过线圈地址2000和2001,但不清楚该库的地址偏移量如何查看。我参考的GitHub问题是关于RS485的,而我使用的是TCP/IP。
请问:该问题是否因临时使用Replit导致?是否需要更换其他JavaScript库(若需要,推荐哪款及如何使用)?我的代码是否存在错误?
问题解答
1. 代码存在明显错误
- 异步逻辑未处理:
client.connectTCP是异步操作,你直接在它后面执行client.writeCoil,此时连接还未建立完成,必然触发"端口未打开"的错误。另外你隐去的IP和端口如果未正确填写,也会直接导致ECONNREFUSED(连接被拒绝)。
修正后的代码示例:const ModbusRTU = require("modbus-serial"); const client = new ModbusRTU(); // 替换为实际的设备IP和端口 client.connectTCP("192.168.x.x", { port: 502 }) .then(() => { console.log("Connected to Modbus TCP server"); // 连接成功后再执行写线圈操作 return client.writeCoil(2000, 0x01); }) .then(() => { console.log("Coil successfully set!"); }) .catch((err) => { console.error(err); }); - 地址偏移问题:
modbus-serial库的线圈地址默认是0偏移——如果你的测试工具用的是2000,直接传2000即可;如果工具里是基于1的地址规则,需要减1传值。可以先写一个已知可用的线圈地址做测试验证。
2. Replit的影响可能性
Replit的网络环境存在出站端口白名单限制,即使本地工具能连通,Replit服务器可能无法访问目标设备的Modbus端口(比如默认的502)。可以在Replit的终端里用以下命令测试连通性:
nc -zv 你的设备IP 端口号
如果连接失败,说明是Replit的网络限制导致的,需要换本地Node.js环境运行代码。
3. 替代库推荐
如果modbus-serial用着不顺手,可以试试jsmodbus:
- 安装命令:
npm install jsmodbus - 基础使用示例:
这个库的API设计更贴合TCP场景,文档清晰,地址同样采用0偏移规则。const { ModbusTCPClient } = require("jsmodbus"); const net = require("net"); const socket = new net.Socket(); const client = new ModbusTCPClient(socket); socket.connect({ host: "你的设备IP", port: 502 }); socket.on("connect", async () => { try { await client.writeSingleCoil(2000, true); console.log("Coil successfully set!"); } catch (err) { console.error(err); } finally { socket.end(); } }); socket.on("error", (err) => { console.error("Socket error:", err); });
内容的提问来源于stack exchange,提问作者Adenosine Triphosphate
相关产品推荐
相关产品推荐

