You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置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()

三、关键细节说明

  1. IP过滤机制:通过自定义RestrictedRequestHandler,只放行152.168.96.32的连接,其他IP会被直接断开,提升安全性
  2. 32位数据处理:
    • 读取时:自动把连续两个16位寄存器拼接成32位数据,代码默认大端模式,若客户端用小端,把conf.WORD_ORDER改成conf.LITTLE_ENDIAN即可
    • 写入时:接收客户端发送的两个16位值,拼接后解析为浮点型(如果是整数场景,替换成位移拼接逻辑即可)
  3. 寄存器管理:用字典模拟保持寄存器,每组两个16位寄存器对应一个32位数据,方便扩展更多数据点

四、测试步骤

  1. 运行上述服务器代码,控制台会输出启动成功的提示
  2. 用客户端(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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:10:04