Modbus-TCP详解

news2024/11/16 19:41:04

目录

Modbus-TCP

Modbus TCP协议的帧结构如下:

实现Modbus-Tcp

使用EasyModbusTCP第三方实现Modbus-Tcp

EasyModbusTCP的使用

设置IP

设置端口

设置设备地址

开启通讯

读取寄存器

写入寄存器

实例


Modbus-TCP

Modbus TCP是Modbus协议的一种变体,它使用TCP/IP网络进行设备之间的通信。Modbus TCP协议帧与Modbus RTU或Modbus ASCII不同,因为它包含了TCP头部、IP头部以及可能的以太网头部。

Modbus TCP协议的帧结构如下:

modbus-tcp一般没有效验

(1). 事务处理标识:客户端生成的随机数,由服务器返回,可用于匹配请求和响应。

(2). 协议标识:在Modbus TCP中,该字段固定是00 00。

(3). 数据长度:请求或响应数据的长度,包括单元标识符、功能代码、数据和校验和,但不包括MBAP头。

(4). 单元标识符:在Modbus TCP中,一般设置为0或者连续的从设备地址。

(5). 功能代码:表示要执行的功能。

(6). 数据:根据功能代码不同,数据字段的长度也不同。

事务处理标识符协议标识数据长度单元标识符功能码数据字段 
00 01 00 0000 06        01 03 00 00 00 0A

实现Modbus-Tcp

public partial class Form1 : Form
{
    /// <summary>
    /// 客户端
    /// </summary>
    TcpClient tcp;

    /// <summary>
    /// form构造
    /// </summary>
    public Form1()
    {
        InitializeComponent();

        tcp = new TcpClient();
        tcp.Connect("127.0.0.1",502);

        startReceve();
    }

    /// <summary>
    /// 接收数据
    /// </summary>
    void startReceve()
    {
        Task.Run(() =>
        {
            try 
            { 
                while (true)
                {
                    byte[] bytes = new byte[15];
                    int count = tcp.GetStream().Read(bytes, 0, bytes.Length);
                    string s = BitConverter.ToString(bytes, 0, count); // 把bs数组转成字符串
                    MessageBox.Show(bytes[bytes.Length - 2] * 256 + bytes[bytes.Length-1]+"");
                    MessageBox.Show(s);
                    if (count  == 0)
                    {
                        break;
                    }
                }
            } 
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        });
    }

    private ushort key = 0x000;
    /// <summary>
    /// 发送
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void button1_Click(object sender, EventArgs e)
    {
        key++;
        byte[] bs = BitConverter.GetBytes(key);

        byte[] data = new byte[]
        {
            bs[0],bs[1], // 事务标识符
            0x00,0x00,   // 协议标识符
            0x00,0x06,   // 后面字节长度
            0x01,        // 从站地址
            0x03,        // 功能码
            0x00,0x00,   // 寄存器起始地址
            0x00,0x03    // 读取寄存器个数
        };

        // 发送请求帧
        tcp.GetStream().Write(data, 0, data.Length);

    }
}

使用EasyModbusTCP第三方实现Modbus-Tcp

在C#中使用第三方库EasyModbus TCP进行Modbus通信时,首先需要安装该库。可以通过NuGet包管理器来安装。

EasyModbusTCP的使用

设置IP

ModbusClient client = new ModbusClient();

client.IPAddress = "127.0.0.1"; // 设置IP

设置端口

ModbusClient client = new ModbusClient();

client.Port = 502; // 端口

设置设备地址

ModbusClient client = new ModbusClient();

client.UnitIdentifier = 2; // 修改设备地址

开启通讯

ModbusClient client = new ModbusClient();

client.Connect(); // 开启通讯

读取寄存器

// 参数1 地址      参数2 读取数量

int[] data = client.ReadHoldingRegisters(2,1); // 从主机设备读取寄存器

写入寄存器

// 参数1 地址      参数2 数据

client.WriteSingleRegister(7, 900); // 写入单个寄存器

写入多个寄存器

// 参数1 地址      参数2 数据

client.WriteMultipleRegisters(3,new int[] {200,300}); // 写入多个寄存器

实例

public partial class Form1 : Form
{
    ModbusClient client;
    public Form1()
    {
        InitializeComponent();

        client = new ModbusClient();
        client.IPAddress = "127.0.0.1"; // 设置IP
        client.Port = 502; // 端口
        client.UnitIdentifier = 2; // 修改设备地址
        client.Connect(); // 开启通讯
    }

    /// <summary>
    /// 读取 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void button1_Click(object sender, EventArgs e)
    {
        int[] data = client.ReadHoldingRegisters(2,1); // 从主机设备读取寄存器
        MessageBox.Show(data[0]+"");
    }


    /// <summary>
    /// 写入
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void button2_Click(object sender, EventArgs e)
    {
        client.WriteMultipleRegisters(3,new int[] {200,300}); // 写入多个寄存器
        client.WriteSingleRegister(7, 900); // 写入单个寄存器
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1984020.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java多线程的单例设计模式 多种实现方法

目录 前言 饿汉式 懒汉式 Double_check volatile double_check Holder方式 枚举 前言 单例设计模式GOF23中设计模式中最常用的设计模式之一, 单例设计模式提供了多线程环境下的保证唯一实例性的解决方案, 虽然简单, 但是实现单例模式的方式多种多样, 因此需要从多个维度去…

【云原生】恰当运用kubernetes中三种探针,确保应用程序在Kubernetes集群中保持健康、可用和可靠

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

Unity热更——ILRuntime安装接入

一、ILRuntime相关地址 1、官网文档地址 2、GitHub上开源的ILRuntime项目工程 3、GitHub上的官方ILRuntime-Unity实例工程 4、官方视频教程-Unity中文课堂&#xff08;需付费&#xff09; 5、ILRuntime入门笔记-赵青青-博客园 6、ILRuntime 的学习-简书 二、ILRuntime…

Python | Leetcode Python题解之第324题摆动排序II

题目&#xff1a; 题解&#xff1a; def quickSelect(a: List[int], k: int) -> int:seed(datetime.datetime.now())shuffle(a)l, r 0, len(a) - 1while l < r:pivot a[l]i, j l, r 1while True:i 1while i < r and a[i] < pivot:i 1j - 1while j > l an…

自动生成数据:Navicat 16 让数据测试更高效

文章目录 前言一、Navicat是什么&#xff1f;二、Navicat 16 新功能1. 自动生成数据2. 改进的用户界面3. 云同步 三、 安装指南Windows 版安装macOS 版安装Linux 版安装 四、使用示例&#xff1a;自动生成数据1. 创建连接2. 选择表3. 打开数据生成器4. 设置数据规则5. 生成数据…

top命令实时监测Linux进程

top命令可以动态实时显示Linux进程信息&#xff0c;方便观察频繁换进换出的内存的进程变化。 top命令执行示例如下&#xff1a; 其中&#xff0c;第一行表示系统当前时间、系统的运行时间、登录的用户数目、系统的平均负载&#xff08;最近1分钟&#xff0c;最近5分钟&#xff…

springboot艺体培训机构业务管理系统--论文源码调试讲解

第2章 开发环境与技术 开发艺体培训机构业务管理系统需要搭建编程的环境&#xff0c;也需要通过调查&#xff0c;对各个相关技术进行分析&#xff0c;选取适合本系统开发的技术与工具。 2.1 MySQL数据库 MySQL是一种具有安全系数、安全系数、混合开发性、高效化等特征的轻量…

基于Raft算法的分布式KV数据库:五、剩余部分

github地址&#xff1a;https://github.com/1412771048/Raft CPPRaft系列-剩余部分 首先我们看下第五章的架构图&#xff0c;图中的主要部分我们在前几张讲解完毕了&#xff0c;目前还剩下clerk和k-v数据库&#xff0c;而本篇的重点在于补全版图&#xff0c;完成&#xff1a;…

SQL注入sqli-labs-master关卡一

本文环境搭建使用的是小皮&#xff0c;靶机压缩包&#xff1a;通过百度网盘分享的文件&#xff1a;sqli-labs-php7-master.zip 链接&#xff1a;https://pan.baidu.com/s/1xBfsi2lyrA1QgUWycRsHeQ?pwdqwer 提取码&#xff1a;qwer 下载解压至phpstudy的WWW目录下即可。 第一…

关于Redis的面试题

一、为什么要使用Redis 内存数据库,速度很快工作单线程worker,串行化,原子操作,IO线程是多线程的。避免上下文切换使用 IO模型,天生支撑高并发kv模型,v具有类型结构具有本地方法,计算数据移动二进制安全,value值最大为512MB二、Redis是多线程还是单线程 Redis在6.0版本…

(免费领源码)java#SSM#MYSQL私家车位共享APP 51842-计算机毕业设计项目选题推荐

目 录 摘要 1 绪论 1.1 课题的研究背景 1.2研究内容与研究目标 1.3ssm框架 1.4论文结构与章节安排 2 2 私家车位共享APP系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据增加流程 2.2.2 数据修改流程 2.2.3数据删除流程 2.3 系统功能分析 2.3.1功能性分析 2…

计算机网络(TCP报文段首部格式中序号和确认号)

TCP首部格式中的序号和确认号并不总是同时出现。 TCP首部的序号和确认号是根据TCP通信的不同阶段和目的来决定的。在建立连接的过程中&#xff0c;序号用于标识发送数据的起始位置&#xff0c;而确认号用于表示接收方期望接收的下一个数据的起始位置。这两个字段在TCP通信的不同…

【vulhub靶场之rsync关】

一、使用nmap模块查看该ip地址有没有Rsync未授权访问漏洞 nmap -p 873 --script rsync-list-modules 加IP地址 查看到是有漏洞的模块的 二、使用rsync命令连接并读取文件 查看src目录里面的信息。 三、对系统中的敏感文件进行下载——/etc/passwd 执行命令&#xff1a; rsy…

【Python】Python中的循环语句

循环语句 导读一、基本概念1.1 循环语句的执行流程1.2 循环语句的分类 二、while语句三、for语句四、break与continue五、死循环六、循环中的else语句七、range()函数结语 导读 大家好&#xff0c;很高兴又和大家见面啦&#xff01;&#xff01;&#xff01; 在上一篇内容中我…

《Advanced RAG》-04-深度研究RAG技术Re-ranking

摘要 文章首先介绍了重新排序在RAG中的重要性&#xff0c;它允许对检索到的文档进行重新排序和过滤&#xff0c;以确保最相关的文档能够被优先考虑&#xff0c;从而提高RAG的效率和准确性。 接着&#xff0c;文章详细描述了两种主流的重新排序方法&#xff1a; 一种是使用重新排…

使用Jetbrains.Rider反编译Unity的DLL文件看源码

直接将dll文件的打开方式用Rider打开即可&#xff0c;打开BattleSeqGenertor.dll文件的效果如下&#xff1a;

Redis 的6种回收策略(淘汰策略)详解

Redis 的6种回收策略&#xff08;淘汰策略&#xff09;详解 1、Redis的六种淘汰策略1. volatile-lru2. volatile-ttl3. volatile-random4. allkeys-lru5. allkeys-random6. no-eviction 2、使用策略规则 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&am…

MyIP:强大且简单好用!

在这个数字化的时代&#xff0c;IP地址就像是我们的网络身份证。各位在日常的工作中&#xff0c;肯定会会遇到需要和 IP 地址相关的需求。 今天和大家聊一聊一个非常好用的开源 IP 工具项目 - MyIP。 简介 MyIP一个开源IP工具箱&#xff0c;提供了一系列的网络检测工具&…

适合双11入手的蓝牙耳机推荐?4款开放式耳机测评

2024年也确实快到大家购物疯狂买买买的双11日子了&#xff0c;我相信肯定也有人在购物车攒了一大堆商品就等着双11清空了。那肯定现在还有人在为双11的购物车放什么东西发愁吧&#xff0c;那对于我来说&#xff0c;双11的购物车应该也是要有蓝牙耳机的一席之地的。 因为毕竟在…

Python酷库之旅-第三方库Pandas(068)

目录 一、用法精讲 271、pandas.Series.dt.dayofyear属性 271-1、语法 271-2、参数 271-3、功能 271-4、返回值 271-5、说明 271-6、用法 271-6-1、数据准备 271-6-2、代码示例 271-6-3、结果输出 272、pandas.Series.dt.days_in_month属性 272-1、语法 272-2、参…