网络高级day01(Modbus 通信协议)

news2024/9/21 2:50:21

目录

1》modbus分类

1> Modbus RTU

2> Modbus ASCLL

3> Modbus TCP

 2》Modbus TCP的特点

 3》Modbus TCP协议

 1> 报文头(一共7个字节)

 2> 寄存器

3> 功能码

 4> 数据

 01H  功能码分析

 05H 功能码分析

0FH 功能码分析


1》modbus分类

1> Modbus RTU

运行在串口上的协议,采用二进制表现形式以及紧凑的数据结构,通信效率较高,应用比较广泛

2> Modbus ASCLL

 运行在串口上的协议,采用ASCLL码进行传输,并且每个字节的开始和结束都有特殊字符作为标志,传输效率远远低于Modbus RTU,一般只有通讯量比较少的时候才会考虑它。注:在ASCII模式下,每个8位的字节被拆分成两个ASCII字符进行发送,比如十六进制0xAF(1010 1111),会被分解成ASCII字符“A”(0100 0001)和”F”(0100 0110)进行发送,其发送量显然比RTU增加一倍。

3> Modbus TCP

 运行在以太网上的协议

 2》Modbus TCP的特点

1> 主从应答式通信

2> Modbus TCP是应用层协议,基于传输层的TCP进行通信

注:更好的理解网络模型的分层特点:

各层之间独立,每一层不需要知道下一层如何实现

当任何一层发生变化时,只要层间接口关系保持不变,则这层以上或以下层不受影响。

3> Modbus TCP 端口号默认为502

 3》Modbus TCP协议

Modbus TCP 协议包含三部分:报文头、功能码、数据

MBAP:Modbus Application Protocol (modbus报文头)

PDU:Protocol Data Unit(协议数据单元)

Modbus TCP/IP协议最大数据帧长度为260字节

 1> 报文头(一共7个字节)

 2> 寄存器

一共有四种类型的寄存器,分别是:线圈、离散量输入、输入寄存器、保持寄存器。

离散量和线圈其实就是位寄存器(每个寄存器数据占1字节),工业上主要用于控制IO设备。输入和保持寄存器是字寄存器(每个寄存器数据占2个字节),工业上主要用于存储工业设备的值。

1.离散量和线圈其实就是位寄存器(每个寄存器数据占1字节),工业上主要用于控制IO设备

线圈寄存器,类比为开关量。 线圈寄存器支持读也支持写,写在功能码里面又分为写单个线圈寄存器和写多个线圈寄存器。

读单个或多个 写单个 写多个 3个功能码实现

离散输入寄存器,离散输入寄存器就相当于线圈寄存器的只读模式,他也是8个bit表示一个开关量,而他的开关量只能读取输入的开关信号,是不能够写的。比如我读取外部按键的按下还是松开。

对应功能码1个 读单个或多个

2. 输入和保持寄存器是字寄存器(每个寄存器数据占2个字节),工业上主要用于存储工业设备的值

保持寄存器,这个寄存器的单位不再是bit而是两个byte,也就是可以存放具体的数据量的,并且是可读写的。比如空调检测到的室温,这是不可以修改的,因为室温是根据实际的物理环境决定的。

功能码有对应的三个

输入寄存器,这个和保持寄存器类似,但是也是只支持读而不能写。一个寄存器也是占据两个byte的空间。类比我我通过读取输入寄存器获取现在的温度传感器的值

对应的功能码也就一个

 

3> 功能码

 4> 数据

 01H  功能码分析

读数据:

主机-》从机

报文头---功能码---起始地址---数量

从机-》主机

报文头---功能码---字节计数---数据

 05H 功能码分析

写单个:

主机--》从机

报文头---功能码---地址---通断标志/数据

从机--》主机

原文返回

0FH 功能码分析

写多个:

主机-->从机

报文头---功能码---起始地址---数量---字节计数---数据

从机--->主机

报文头---功能码---起始地址---数量

练习

封装函数实现03,05功能码的作用

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
void set_slaveid(uint8_t *p, uint8_t id);
int sockfd;
void read_registers(uint8_t *p, uint16_t addr, uint16_t num, uint8_t *dest);
void write_coil(uint8_t *p, uint16_t addr, int op, uint8_t *dest);
int main(int argc, char const *argv[])
{

    if (argc != 2)
    {
        printf("usage:<ip>\n");
        return -1;
    }
    // 1.创建套接字
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    printf("sockfd:%d\n", sockfd);
    // 2.填充结构体
    struct sockaddr_in saddr;
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(502);
    saddr.sin_addr.s_addr = inet_addr(argv[1]);
    socklen_t addrlen = sizeof(saddr);
    // 3.连接
    if (connect(sockfd, (struct sockaddr *)&saddr, addrlen) < 0)
    {
        perror("connect err");
        return -1;
    }
    // 创建数组
    uint8_t req[32] = {0};
    uint8_t date[128] = {0};
    set_slaveid(req, 0x01);
    read_registers(req, 0x0000, 0x0002, date);//03
    for (int i = 0; i < date[8]; i++)
    {
        printf("%02x ", date[9 + i]);
    }
    putchar(10);
    write_coil(req,0x0000,1,date);//05
    printf("seq:%02x\n",date[1]);
    return 0;
}

void set_slaveid(uint8_t *p, uint8_t id)
{
    p[6] = id;
}
void read_registers(uint8_t *p, uint16_t addr, uint16_t num, uint8_t *dest)
{
    p[5] = 0x06;
    p[7] = 0x03;
    p[9] = addr;
    p[8] = addr >> 8;
    p[11] = num;
    p[10] = num >> 8;
    send(sockfd, p, 12, 0);
    recv(sockfd, dest, 128, 0);
}
void write_coil(uint8_t *p, uint16_t addr, int op, uint8_t *dest)
{   
    p[1]=0x01;
    p[5] = 0x06;
    p[7] = 0x05;
    p[9] = addr;
    p[8] = addr >> 8;
    if (op == 1)
    {
        p[10] = 0xFF;
    }
    else
    {
        p[10] = 0x00;
    }
    p[11] = 0x00;
    send(sockfd, p, 12, 0);
    recv(sockfd, dest, 128, 0);
}

今天的分享就到这里结束啦,如果有哪里写的不好的地方,请指正。
如果觉得不错并且对你有帮助的话点个关注支持一下吧!

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

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

相关文章

git reflog 和 git log 的详解和区别

文章目录 1. git log 介绍基本用法&#xff1a;输出内容&#xff1a;常见选项&#xff1a;git log 的局限性&#xff1a; 2. git reflog 介绍基本用法&#xff1a;输出内容&#xff1a;git reflog 输出字段&#xff1a;常见选项&#xff1a;主要用途&#xff1a;示例&#xff1…

Rasa对话模型——做一个语言助手

1、Rasa模型 1.1 模型介绍 Rasa是一个用于构建对话 AI 的开源框架&#xff0c;主要用于开发聊天机器人和语音助手。Rasa 提供了自然语言理解&#xff08;NLU&#xff09;和对话管理&#xff08;DM&#xff09;功能&#xff0c;使开发者能够创建智能、交互式的对话系统。 1.2…

JavaScript 基础 - 第20天_Node.js模块化

文章目录 Day02_Node.js模块化目录学习目标01.模块化简介目标讲解小结 02.ECMAScript标准-默认导出和导入目标讲解小结 03.ECMAScript标准-命名导出和导入目标讲解小结 04.包的概念目标讲解小结 05.npm软件包管理器目标讲解小结 06.npm安装所有依赖目标讲解小结 07.npm全局软件…

计算机领域CCF推荐期刊A/B/C类全目录

计算机领域CCF推荐期刊 最新在检的【自动化与控制系统】的64本SCI期刊最新影响因子、期刊分区、自引率 CCF-A类 CCF-B类 CCF-C类 更多期刊解析干货&#xff0c;移步公众号【Unionpub学术】 计算机领域CCF推荐期刊A/B/C类全目录&#xff08;附excel下载&#xff09;

3.使用 VSCode 过程中的英语积累 - Selection 菜单(每一次重点积累 5 个单词)

前言 学习可以不局限于传统的书籍和课堂&#xff0c;各种生活的元素也都可以做为我们的学习对象&#xff0c;本文将利用 VSCode 页面上的各种英文元素来做英语的积累&#xff0c;如此做有 3 大利 这些软件在我们工作中是时时刻刻接触的&#xff0c;借此做英语积累再合适不过&a…

多线程篇六

多线程篇六 如笔者理解有误欢迎交流指正~⭐ 什么是单例模式&#xff1f; 单例模式是最常见的 设计模式. 顾名思义&#xff0c;单例模式指的就是单个实例的模式.&#xff08;针对某些类只能使用一个对象的场景【如MySQL、JDBC、DataSource】&#xff09; 设计模式 设计模式是…

CentOS7.9环境上NFS搭建及使用

Linux环境NFS搭建及使用 1. 服务器规划2. NFS服务器配置2.1 主机名设置2.2 nfs安装2.2.1 repo文件替换2.2.2 NFS服务安装 2.3 nfs配置2.4 服务查看2.5 资源发布2.6 配置nfs服务开机自启2.7 端口开放 3.应用服务器配置3.1 主机名设置3.2 nfs安装3.2.1 repo文件替换3.2.2 NFS服务…

Vue学习记录之五(组件/生命周期)

一、组件 在每一个.vue文件可以看作是一个组件&#xff0c;组件是可以复用的&#xff0c;每个应用可以看作是一棵嵌套的组件树。 在Vue3中&#xff0c;组件导入以后即可直接使用。 二、组件的生命周期 生命周期就是从诞生(创建)到死亡(销毁) 的过程。 Vue3 组合式API中(se…

Java中的事务管理

1.1 事务管理 1.1 事务回顾 事务是一组操作的集合&#xff0c;它是一个不可分割的工作单位。事务会把所有的操作作为一个整体&#xff0c;一起向数据库提交或者是撤销操作请求。所以这组操作要么同时成功&#xff0c;要么同时失败。 怎么样来控制这组操作&#xff0c;让这组操…

力扣最热一百题——合并两个有序链表

目录 题目链接&#xff1a;21. 合并两个有序链表 - 力扣&#xff08;LeetCode&#xff09; 题目描述 示例 提示&#xff1a; 解法一&#xff1a;比大小放入 Java写法&#xff1a; 运行时间以及复杂度 C写法&#xff1a; 运行时间以及复杂度 总结 题目链接&#xff1a…

Qt/C++事件过滤器与控件响应重写的使用、场景的不同

在Qt/C中&#xff0c;事件过滤器和控件响应重写是两种用于捕获和处理鼠标、键盘等事件的机制&#xff0c;它们的用途和使用场景不同&#xff0c;各有优劣。下面详细介绍它们的区别、各自适用的场景、以及混合使用的场景和注意事项。 1. 事件过滤器&#xff08;Event Filter&…

JavaScript 可选链操作符:深度解读与实战应用( JS 可选链操作符)

前言 在JavaScript开发中&#xff0c;我们经常会遇到访问嵌套对象属性的需求。然而&#xff0c;处理深层嵌套对象时&#xff0c;属性可能为 undefined 或 null&#xff0c;直接访问这些属性时会抛出错误。为了解决这种问题&#xff0c;JavaScript在ES2020中引入了一项新特性—…

104.游戏安全项目-基址的技术原理-基址的本质

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a;易道云信息技术研究院 本人写的内容纯属胡编乱造&#xff0c;全都是合成造假&#xff0c;仅仅只是为了娱乐&#xff0c;请不要盲目相信…

【初阶数据结构】一文讲清楚 “堆” 和 “堆排序” -- 树和二叉树(二)(内含TOP-K问题)

文章目录 前言1. 堆1.1 堆的概念1.2 堆的分类 2. 堆的实现2.1 堆的结构体设置2.2 堆的初始化2.3 堆的销毁2.4 添加数据到堆2.4.1 "向上调整"算法 2.5 从堆中删除数据2.5.1 “向下调整”算法 2.6 堆的其它各种方法接口函数 3. 堆排序3.1 堆排序的代码实现 4. TOP-K问题…

主机和Docker容器之间的文件互传方法汇总

Docker渐渐成为前端的一个工具&#xff0c;它像一个通用包装&#xff0c;可以把各种环境包裹其中&#xff0c;从而实现跨设备的兼容。使用的过程中&#xff0c;往往会需要将本地的文件和docker容器内部的文件互传&#xff1a;将主机的文件传递给容器内&#xff0c;让里面的工具…

【LLM大模型】如何让大模型更好地进行场景落地?

自ChatGPT模型问世后&#xff0c;在全球范围内掀起了AI新浪潮。 有很多企业和高校也随之开源了一些效果优异的大模型&#xff0c;例如&#xff1a;Qwen系列模型、MiniCPM序列模型、Yi系列模型、ChatGLM系列模型、Llama系列模型、Baichuan系列模型、Deepseek系列模型、Moss模型…

sqli-lab靶场学习(二)——Less8-10(盲注、时间盲注)

Less8 第八关依然是先看一般状态 http://localhost/sqli-labs/Less-8/?id1 然后用单引号闭合&#xff1a; http://localhost/sqli-labs/Less-8/?id1 这关的问题在于报错是不显示&#xff0c;那没办法通过上篇文章的updatexml大法处理。对于这种情况&#xff0c;需要用“盲…

从 InnoDB 到 Memory:MySQL 存储引擎的多样性

&#x1f4c3;个人主页&#xff1a;island1314 &#x1f525;个人专栏&#xff1a;MySQL学习 ⛺️ 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f442;&#x1f3fd;留言 &#x1f60d;收藏 &#x1f49e; &#x1f49e; &#x1f49e; &#x1f680;前言 &#x1f525…

PSINS,GNSS速度与SINS滤波的MATLAB代码

文章目录 程序说明主要特点适用范围获取方式运行截图 程序说明 基于PSINS工具箱的GNSS和SINS滤波的MATLAB代码&#xff0c;观测量为GNSS的三轴速度。 专为工程师和研究人员设计&#xff0c;助您轻松实现高精度的导航和定位。 主要特点 高精度滤波算法&#xff1a;结合PSINS和…

内存dump文件分析

目录 dumpsneak攻击步骤&#xff1a; dump 打开Volatility工具目录&#xff0c;C:\Users\Administrator\Desktop\应急工具集\volatility 打开运行输入volatility.exe -f 文件 imageinfo&#xff08;花费比较长的时间&#xff0c;对于这个mem文件&#xff0c;可以使用Win2012…