import socket import time from binascii import unhexlify # 目标服务器地址和端口 TARGET_HOST = 'localhost' # 请根据实际情况修改 TARGET_PORT = 8888 # 请根据实际情况修改 # 元数组 modbus 指令 MODBUS_DATA_HEX = ( "7e80DFEB502006887e", "01033041011b7b0000000041eaafb742d19bd74513d545450dd9a4450ec53d00000000420ccf64420c74a9420c74a9c2d200009d99" ) # 重要-四川远德MQTT推送 (倾角计) # "7e803042593632517e", # "01033041011b7b0000000041eaafb742d19bd74513d545450dd9a4450ec53d00000000420ccf64420c74a9420c74a9c2d200009d99" # 深部位移计 # "7e80DD33D43DFC5B7e", # "0103204135317841ab8e39bf27bccd3f1fb19ac2b231bbc0b6f82040ae3207c3f9f80efa23", # "020320413b9fa441acd34dc0024a003fa2a59ac2af34a0c18e17ea413167dbc3f9c7fe6d40", # "0303204139565641ab21ddbff6af333fe26800c2aec626c18685244176ee82c3f9bd7568c8", # "040320413a0d3e41a534d3bf461ccd403d7e00c2ade1e4c0d819c441ce9ca7c3f9a4d260bf" # 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(1) # (可选)接收最终响应 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()