如何配置Python uModbus服务器实现与指定客户端的32位数据读写
嘿,我来帮你搞定这个uModbus服务器的配置,实现和指定客户端的32位数据读写测试~
配置Python uModbus服务器实现指定客户端32位数据读写测试
一、核心配置要点梳理
首先咱们得把几个关键参数和逻辑理清楚:
- 服务器绑定IP必须设为你的系统IP
152.168.96.11,端口用Modbus标准的502就行(要是被占用可以换其他未使用端口) - 为了只和指定客户端
152.168.96.32通信,咱们加个IP过滤逻辑,拒绝其他无关设备的连接 - 32位数据在Modbus里是通过两个连续16位寄存器拼接实现的,所以要处理好高低位的顺序(大端/小端,大部分设备默认大端)
二、修改后的完整可运行服务器代码
我把基础代码做了针对性修改,加了IP过滤、32位数据处理逻辑,直接就能用:
#!/usr/bin/env python3 from umodbus import conf from umodbus.server.tcp import get_server from umodbus.server.tcp import RequestHandler from socketserver import TCPServer import struct # 配置Modbus数据格式:默认大端模式(高位在前),如果客户端用小端可调整WORD_ORDER conf.SIGNED_VALUES = False conf.BYTE_ORDER = conf.BIG_ENDIAN conf.WORD_ORDER = conf.BIG_ENDIAN # 指定允许连接的客户端IP ALLOWED_CLIENT = '152.168.96.32' # 自定义请求处理器,实现IP白名单过滤 class RestrictedRequestHandler(RequestHandler): def handle(self): client_ip = self.client_address[0] if client_ip != ALLOWED_CLIENT: print(f"拒绝非授权IP {client_ip} 的连接请求") self.request.close() return print(f"授权客户端 {client_ip} 已成功连接") super().handle() # 创建服务器实例,绑定到指定IP和端口 server = get_server(TCPServer, ('152.168.96.11', 502), RestrictedRequestHandler) # 模拟保持寄存器:每两个16位寄存器对应一个32位数据 holding_registers = { 0: [0, 0], # 地址0+1存储第一个32位数据 2: [0, 0], # 地址2+3存储第二个32位数据 } # 读取32位数据的回调函数(功能码3) def read_32bit_data(slave_id, address, quantity): regs = [] # 每一个32位数据对应2个16位寄存器,所以要读取2*quantity个寄存器 for i in range(quantity): target_addr = address + i*2 regs.extend(holding_registers.get(target_addr, [0, 0])) return regs # 写入32位数据的回调函数(功能码16) def write_32bit_data(slave_id, address, values): # 传入的values是16位寄存器列表,每两个对应一个32位数据 for i in range(0, len(values), 2): target_addr = address + (i//2)*2 if target_addr in holding_registers: holding_registers[target_addr] = values[i:i+2] # 解析拼接后的32位浮点数据(如果是整数就用位移拼接:(val1 <<16)|val2) packed_data = struct.pack('>HH', values[i], values[i+1]) float_value = struct.unpack('>f', packed_data)[0] print(f"已写入32位浮点数据到地址{target_addr}: {float_value}") # 注册读写功能到服务器 server.add_read_function(3, read_32bit_data) # 功能码3:读取保持寄存器 server.add_write_function(16, write_32bit_data) # 功能码16:批量写入保持寄存器 if __name__ == '__main__': try: print(f"uModbus服务器已启动,绑定地址:152.168.96.11:502,仅允许客户端 {ALLOWED_CLIENT} 连接") server.serve_forever() except KeyboardInterrupt: print("服务器已停止运行") server.shutdown()
三、关键细节说明
- IP过滤机制:通过自定义
RestrictedRequestHandler,只放行152.168.96.32的连接,其他IP会被直接断开,提升安全性 - 32位数据处理:
- 读取时:自动把连续两个16位寄存器拼接成32位数据,代码默认大端模式,若客户端用小端,把
conf.WORD_ORDER改成conf.LITTLE_ENDIAN即可 - 写入时:接收客户端发送的两个16位值,拼接后解析为浮点型(如果是整数场景,替换成位移拼接逻辑即可)
- 读取时:自动把连续两个16位寄存器拼接成32位数据,代码默认大端模式,若客户端用小端,把
- 寄存器管理:用字典模拟保持寄存器,每组两个16位寄存器对应一个32位数据,方便扩展更多数据点
四、测试步骤
- 运行上述服务器代码,控制台会输出启动成功的提示
- 用客户端(152.168.96.32)测试:
- 读取操作:使用功能码3,读取起始地址0,数量1(实际会读取2个16位寄存器,对应一个32位数据)
- 写入操作:使用功能码16,写入起始地址0,传入两个16位整数(比如
[0x41480000 >> 16, 0x41480000 & 0xFFFF],对应32位浮点型的12.5)
内容的提问来源于stack exchange,提问作者Chandra Sekhar K
相关产品推荐
相关产品推荐

