js实现modbustcp
Modbus TCP 协议简介
Modbus TCP 是基于 TCP/IP 的 Modbus 协议变种,使用端口 502,数据帧去除了校验字段(由 TCP 层保证可靠性)。协议格式如下:
- 事务标识符(2 字节):用于请求/响应匹配。
- 协议标识符(2 字节):固定为
0x0000。 - 长度字段(2 字节):后续字节数。
- 单元标识符(1 字节):设备地址。
- 功能码(1 字节):如
0x03(读保持寄存器)。 - 数据字段(可变):根据功能码变化。
JavaScript 实现方案
使用 Node.js 的 net 模块
通过 Node.js 的 net.Socket 可直接与 Modbus TCP 设备通信。以下为读取保持寄存器的示例:
const net = require('net');
// 配置设备参数
const device = {
host: '192.168.1.100',
port: 502,
unitId: 1,
startAddr: 0,
registerCount: 10
};
// 创建 Modbus TCP 请求帧
function createReadHoldingRegistersRequest(unitId, startAddr, count) {
const buffer = Buffer.alloc(12);
buffer.writeUInt16BE(1, 0); // 事务标识符(示例值)
buffer.writeUInt16BE(0, 2); // 协议标识符
buffer.writeUInt16BE(6, 4); // 长度字段(后续 6 字节)
buffer.writeUInt8(unitId, 6); // 单元标识符
buffer.writeUInt8(0x03, 7); // 功能码:读保持寄存器
buffer.writeUInt16BE(startAddr, 8); // 起始地址
buffer.writeUInt16BE(count, 10); // 寄存器数量
return buffer;
}
// 发送请求并解析响应
const client = new net.Socket();
client.connect(device.port, device.host, () => {
const request = createReadHoldingRegistersRequest(
device.unitId,
device.startAddr,
device.registerCount
);
client.write(request);
});
client.on('data', (data) => {
const unitId = data.readUInt8(6);
const funcCode = data.readUInt8(7);
const byteCount = data.readUInt8(8);
const registers = [];
for (let i = 0; i < byteCount / 2; i++) {
registers.push(data.readUInt16BE(9 + i * 2));
}
console.log('响应数据:', registers);
client.end();
});
client.on('error', (err) => {
console.error('通信错误:', err);
});
使用第三方库
若需快速开发,可选用以下库:

-
modbus-serial:支持 TCP 和 RTU。
npm install modbus-serial示例代码:

const ModbusRTU = require("modbus-serial"); const client = new ModbusRTU.ClientTCP({ host: "192.168.1.100", port: 502, }); client.readHoldingRegisters(0, 10) .then((data) => console.log(data)) .catch((err) => console.error(err)); -
jsmodbus:纯 JavaScript 实现。
npm install jsmodbus示例代码:
const Modbus = require('jsmodbus'); const net = require('net'); const socket = new net.Socket(); const client = new Modbus.client.TCP(socket, 1); socket.connect({ host: '192.168.1.100', port: 502 }, () => { client.readHoldingRegisters(0, 10) .then((resp) => console.log(resp.response._body.values)) .catch(console.error); });
注意事项
- 字节序处理:Modbus 协议默认使用大端序(Big-Endian),需通过
Buffer的writeUInt16BE等方法正确处理。 - 超时机制:添加超时逻辑避免无响应阻塞,例如
socket.setTimeout(3000)。 - 错误处理:检查功能码高位是否为
0x80(异常响应),并解析异常码。 - 性能优化:复用 TCP 连接,避免频繁创建/销毁 Socket。






