当前位置: 首页 > news >正文

python实现ModBusTCP协议的server

python实现ModBusTCP协议的server是一件简单的事情,只要通过pymodbus、pyModbusTCP等模块都可以实现,本文采用pymodbus。

相关文章见:

python实现ModBusTCP协议的client-CSDN博客

一、了解pymodbus的Server

1、pymodbus.server的模块

pymodbus.server中的模块,能够用于用于实现 Modbus 协议的服务器端。以下是每个模块的功能介绍:

(1)ModbusSerialServer: 这个模块提供了一个基于串口的 Modbus 服务器。它允许通过串口与 Modbus 客户端通信。

(2)ModbusTcpServer: 这个模块提供了一个基于 TCP/IP 的 Modbus 服务器。它通过 TCP/IP 网络接口与 Modbus 客户端通信。

(3)ModbusTlsServer: 这个模块提供了一个基于 TLS 加密的 Modbus 服务器。它通过安全的 TLS 连接与 Modbus 客户端通信,确保通信的安全性。

(4)ModbusUdpServer: 这个模块提供了一个基于 UDP 的 Modbus 服务器。与 TCP 不同,UDP 是一种面向无连接的协议,适用于某些特定的网络环境。

(5)ServerAsyncStop: 这个类用于异步服务器的停止信号。通过发送这个信号,可以优雅地停止异步服务器的运行。

(6)ServerStop: 这个类用于同步服务器的停止信号。与 ServerAsyncStop 类似,但用于同步服务器。

(7)StartAsyncSerialServer: 这个函数用于启动一个异步的基于串口的 Modbus 服务器。

(8)StartAsyncTcpServer: 这个函数用于启动一个异步的基于 TCP/IP 的 Modbus 服务器。

(9)StartAsyncTlsServer: 这个函数用于启动一个异步的基于 TLS 加密的 Modbus 服务器。

(10)StartAsyncUdpServer: 这个函数用于启动一个异步的基于 UDP 的 Modbus 服务器。

(11)StartSerialServer: 这个函数用于启动一个同步的基于串口的 Modbus 服务器。

(12)StartTcpServer: 这个函数期望用于启动一个同步的基于 TCP/IP 的 Modbus 服务器。(备注:源码其实是异步的)

(13)StartTlsServer: 这个函数期望用于启动一个同步的基于 TLS 加密的 Modbus 服务器。(备注:源码其实是异步的)

(14)StartUdpServer: 这个函数期望用于启动一个同步的基于 UDP 的 Modbus 服务器。(备注:源码其实是异步的)

这些模块和函数提供了多种不同类型的 Modbus 服务器的实现方式,可以根据具体的需求选择合适的模块和函数来创建和启动 Modbus 服务器。

2、模块的选用

StartAsyncTcpServerStartTcpServerpymodbus 库中用于启动 Modbus TCP 服务器的两种不同的方法,其主要区别在于同步(Synchronous)和异步(Asynchronous)执行方式。

(1)StartAsyncTcpServer(异步方式):

StartAsyncTcpServer 是一个异步函数,它使用 Python 的 asyncio 模块来实现异步的 Modbus TCP 服务器。在异步编程中,事件循环(event loop)可以处理多个任务,使得程序在等待某些耗时操作(比如 I/O 操作)时不会被阻塞。这意味着它可以同时处理多个客户端连接,提高了服务器的并发性能。

该函数的调用方式是异步的,需要在异步上下文(比如异步函数内部或者异步脚本中)使用。

(2)StartTcpServer(同步方式):

StartTcpServer 是一个同步函数,它使用 Python 的标准同步执行方式,会阻塞当前线程。在同步模式下,每次只能处理一个客户端连接。这意味着服务器只能顺序处理客户端请求,一个接一个地处理。

该函数的调用方式是同步的,可以在任何地方调用。

总之,选择哪种方式取决于你的应用场景。如果需要处理大量并发连接并提高性能,可以选择异步方式;如果简单的同步处理能够满足需求,可以选择同步方式。

本文采用StartAsyncTcpServer,所以他涉及到的模块是StartTcpServer,源码如下:

def StartTcpServer(**kwargs):  # pylint: disable=invalid-name"""Start and run a serial modbus server."""return asyncio.run(StartAsyncTcpServer(**kwargs))

如果要停止异步,需要调用ServerAsyncStop模块。

二、一个Demo

1、服务端读写自身的保持寄存器的示例

import asyncio
import threading
import time
import json
from pymodbus.server import StartTcpServer, ServerAsyncStop
from pymodbus.datastore import ModbusSequentialDataBlock, ModbusSlaveContext, ModbusServerContextif __name__ == "__main__":# Modbus TCP服务器的IP地址和端口号server_ip = "192.168.1.188"port = 502station = 1# 创建一个数据存储区,用于存储从客户端读取的数据store = ModbusSlaveContext(hr=ModbusSequentialDataBlock(0, [0] * 100))# 创建一个服务器上下文,用于处理客户端的请求context = ModbusServerContext(slaves=store, single=True)# 启动ModBusTCP服务器# 创建并启动线程(启动异步服务器)# StartTcpServer(context=context, address=(server_ip, port))modbus_server_thread = threading.Thread(target=StartTcpServer, kwargs=({"context":context, "address":(server_ip, port)}))modbus_server_thread.start()# 设置保持寄存器的0地址的值为s# 定义函数参数fc_as_hex = 0x03  # 功能码,例如读保持寄存器是"0x03"write_address = 0  # 起始地址read_address = 10read_count = 1values = [115]  # 触发指令s 要设置的多个值列表,如[10, 20, 30]# 调用函数,设置0地址为触发指令sstore.setValues(fc_as_hex, write_address, values)# 获取保持寄存器的值并打印hr_values = store.getValues(3, read_address, count=read_count)print("Hold Register Values:", hr_values)assert hr_values == [0], print("测试失败!")time.sleep(10)try:print("停止服务器")asyncio.run(ServerAsyncStop())  # 停止服务器except:pass

相关文章:

  • Jupyter Notebook还有魔术命令?太好使了
  • 聊聊设计模式--简单工厂模式
  • 内网穿透工具之NATAPP(一)
  • 微信小程序案例2-3:婚礼邀请函
  • Databend 开源周报第 116 期
  • 【深度学习】使用Pytorch实现的用于时间序列预测的各种深度学习模型类
  • 基于Java的教室设备管理系统设计与实现(源码+lw+部署文档+讲解等)
  • C# Onnx Yolov8 Detect 印章 指纹捺印 检测
  • RabbitMQ (4)
  • ROS笔记之visualization_msgs-Marker的mesh_resource导入外部模型学习
  • 20.1 OpenSSL 字符BASE64压缩算法
  • php简单后门实现及php连接数据库
  • 模型对象CSS2DObject始终在画布的左上角(问题解决)
  • 视频上的水印文字如何去掉?
  • 【windows 脚本】netsh命令
  • [LeetCode] Wiggle Sort
  • “大数据应用场景”之隔壁老王(连载四)
  • 【跃迁之路】【699天】程序员高效学习方法论探索系列(实验阶段456-2019.1.19)...
  • const let
  • create-react-app项目添加less配置
  • HTML5新特性总结
  • IIS 10 PHP CGI 设置 PHP_INI_SCAN_DIR
  • Java 9 被无情抛弃,Java 8 直接升级到 Java 10!!
  • js学习笔记
  • Material Design
  • vue:响应原理
  • webpack入门学习手记(二)
  • Zsh 开发指南(第十四篇 文件读写)
  • 闭包--闭包之tab栏切换(四)
  • 编写高质量JavaScript代码之并发
  • 多线程 start 和 run 方法到底有什么区别?
  • 基于OpenResty的Lua Web框架lor0.0.2预览版发布
  • 基于组件的设计工作流与界面抽象
  • 解析 Webpack中import、require、按需加载的执行过程
  • 类orAPI - 收藏集 - 掘金
  • 聊聊directory traversal attack
  • 买一台 iPhone X,还是创建一家未来的独角兽?
  • 06-01 点餐小程序前台界面搭建
  • 交换综合实验一
  • #LLM入门|Prompt#1.8_聊天机器人_Chatbot
  • $.ajax中的eval及dataType
  • $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
  • (bean配置类的注解开发)学习Spring的第十三天
  • (BFS)hdoj2377-Bus Pass
  • (C语言)逆序输出字符串
  • (剑指Offer)面试题34:丑数
  • (九十四)函数和二维数组
  • (六)软件测试分工
  • (免费分享)基于springboot,vue疗养中心管理系统
  • (七)Knockout 创建自定义绑定
  • (数位dp) 算法竞赛入门到进阶 书本题集
  • (转)Android学习笔记 --- android任务栈和启动模式
  • ******之网络***——物理***
  • .NET Framework Client Profile - a Subset of the .NET Framework Redistribution
  • .Net小白的大学四年,内含面经