69 lines
2.7 KiB
Python
69 lines
2.7 KiB
Python
import socket
|
||
import time
|
||
from binascii import unhexlify
|
||
|
||
# 目标服务器地址和端口
|
||
TARGET_HOST = 'localhost' # 请根据实际情况修改
|
||
TARGET_PORT = 8888 # 请根据实际情况修改
|
||
|
||
# 元数组 modbus 指令
|
||
MODBUS_DATA_HEX = (
|
||
"7e80D55746B29F687e",
|
||
"010310c07ffffe45217c3d41dfe9964140686641f4"
|
||
)
|
||
# "01031c4268442f41d30000418b6685000000004026f4cac00d1fd3c2ad2a9d6311",
|
||
# "02031c42488fd041c5800041865ab7000000003f364458c03f765ec2add9722da5",
|
||
# "03031c42ffdad541c78000421529b8000000003d5f38f94082080dc2abdf4f1f94"
|
||
# 01 03 1c 4268 442f 41d3 0000 418b 6685 0000 0000 4026 f4ca c00d 1fd3 c2ad 2a9d 6311
|
||
# 从机地址 功能码 字节长度 2个字节 CRC校验
|
||
|
||
# 在计算机中一个字节1Byte=8bit 而16进制表示法中,刚好 2位数表示一个字节 2^4=16
|
||
# Modbus 协议传输数据的基本单位是 16位的寄存器(2个字节)。
|
||
# 但是,像温度、压力这种带有小数点的数值,用 16 位(2个字节)来表示精度不够。因此,工业上通常会把 2 个连续的寄存器(即 4 个字节,32 bit) 捆绑在一起,用来表示一个 32位浮点数(Float32)
|
||
|
||
|
||
def main():
|
||
|
||
try:
|
||
# 创建TCP套接字
|
||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
|
||
# 设置连接超时
|
||
sock.settimeout(5)
|
||
print(f"正在连接到 {TARGET_HOST}:{TARGET_PORT}...")
|
||
sock.connect((TARGET_HOST, TARGET_PORT))
|
||
print("已连接。")
|
||
|
||
for hex_bytes in MODBUS_DATA_HEX:
|
||
|
||
# 0.将十六进制字符串转换为字节
|
||
modbus_bytes = unhexlify(hex_bytes)
|
||
|
||
# 1. 发送注册包
|
||
print("发送注册包...")
|
||
sock.sendall(modbus_bytes)
|
||
print("注册包已发送。")
|
||
|
||
# 2. 等待0.5秒
|
||
print("等待 0.1 秒...")
|
||
time.sleep(0.5)
|
||
|
||
# (可选)接收最终响应
|
||
try:
|
||
final_response = sock.recv(1024)
|
||
if final_response:
|
||
print(f"收到最终响应: {final_response.hex()}")
|
||
else:
|
||
print("收到空的最终响应。")
|
||
except socket.timeout:
|
||
print("等待最终响应超时。")
|
||
# 忽略其他接收错误,直接结束
|
||
|
||
except ConnectionRefusedError:
|
||
print(f"错误: 连接被拒绝,请确认服务器在 {TARGET_HOST}:{TARGET_PORT} 上运行。")
|
||
except ValueError as e:
|
||
print(f"错误: 无效的十六进制字符串. {e}")
|
||
except Exception as e:
|
||
print(f"发生错误: {e}")
|
||
|
||
if __name__ == "__main__":
|
||
main() |