You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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
    
  • 基础使用示例:
    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);
    });
    
    这个库的API设计更贴合TCP场景,文档清晰,地址同样采用0偏移规则。

内容的提问来源于stack exchange,提问作者Adenosine Triphosphate

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 03:16:28