Linux下如何用Netcat通过TCP发送Modbus RTU请求并捕获响应?
问题解答
1. 完整Netcat命令构造
首先需要把Modbus RTU请求的十六进制序列转成可发送的字节流,步骤如下:
- 拆解Modbus请求参数:
- 设备地址:
0x01 - 功能码(读输入寄存器):
0x03 - 内存地址
1000H(十六进制)拆分为大端字节:0x10 0x00 - 寄存器数量1拆分为大端字节:
0x00 0x01 - 计算Modbus CRC16校验码:对前面6个字节
01 03 10 00 00 01计算CRC-16/MODBUS,得到校验字节0xCB 0x39(低字节在前)
- 设备地址:
- 最终完整请求字节序列:
0x01 0x03 0x10 0x00 0x00 0x01 0xCB 0x39
用printf生成字节流并通过nc发送的命令:
printf '\x01\x03\x10\x00\x00\x01\xCB\x39' | nc 192.168.0.5 2000
2. 能否用nc -l 3456监听响应?
不能直接这么做。nc -l 3456是启动一个独立的TCP监听服务,而TCP转RS485设备会将响应发回发起请求的客户端连接端口,而非这个独立监听端口。如果要接收响应,只需让发送请求的nc保持连接即可——默认情况下nc在发送数据后不会立即关闭连接,会等待接收响应并输出到终端。
3. 如何指定发送请求的端口?
使用nc的-p参数指定客户端源端口,比如指定端口3456发送请求并等待响应:
printf '\x01\x03\x10\x00\x00\x01\xCB\x39' | nc -p 3456 192.168.0.5 2000
执行后,终端会等待TCP转RS485设备返回的响应,若要直观查看十六进制格式的响应,可配合xxd转换:
printf '\x01\x03\x10\x00\x00\x01\xCB\x39' | nc -p 3456 192.168.0.5 2000 | xxd -p
4. 十六进制Modbus消息转字节形式的方法
Linux下常用两种方式:
printf命令:用\x前缀表示十六进制字节,比如\x01对应字节01,按序列写出即可生成对应字节流。echo+xxd组合:先输出纯十六进制字符串,再用xxd -r -p反向解析为原始字节流:echo -n "010310000001CB39" | xxd -r -p | nc 192.168.0.5 2000
内容的提问来源于stack exchange,提问作者Dan Luba
相关产品推荐
相关产品推荐

