Day40-45 网络高级(modbus)

文章目录

  • Modbus起源
    • 1.起源:
    • 2.分类:
    • 3.优势:
    • 4.应用场景:
    • 5.ModbusTCP特点:
  • Modbus TCP协议格式
    • 1.报文头
    • 2.寄存器
    • 3.功能码
  • 工具软件使用
    • .Modbus Slave&Poll
    • 2.网络调试助手
    • .Wireshark的使用
  • Modbus RTU
    • 1、与Modbus TCP的区别
    • 2、Modbus RTU特点
    • 3.ModbusRTU协议格式:
    • 4.报文详解:
    • 5.模拟器的使用
      • 一、虚拟串口的安装
      • 二、虚拟机绑定端口
      • 三、测试通信
      • 四、将Modbus Slave模拟器作为RTU设备的从机
  • Modbus库
    • 【1】库的安装
      • 1.库的安装配置
      • 2.库的使用
    • 【2】函数接口
    • 【3】编程流程
  • 基于Modbus的工业数据采集项目
    • 1.Http简介
    • 2.Http特点
    • 3.Http协议格式
      • 客户端请求消息格式
        • a. 请求行:
        • b. 请求头:
        • c. 空行
        • d. 请求体
  • WebServer
    • 1.服务器源码分析:
    • 2.安装使用postman
    • 3.结合Modbus部分整体流程分析

Modbus起源

1.起源:

Modbus由Modicon公司于1979年开发,是一种工业现场总线协议标准。
Modbus通信协议具有多个变种,其中有支持串口,以太网多个版本,其中最著名的是Modbus RTU、Modbus ASCII和Modbus TCP三种
其中Modbus TCP是在施耐德收购Modicon后1997年发布的。

2.分类:

1)Modbus RTU:
运行在串口上的协议,采用二进制表现形式以及紧凑型数据结构,通信效率高,应用广泛
2)Modbus ASCII:
运行在串口上的协议,采用ASCII码传输,并且利用特殊字符作为其字节的开始与结束标识,其传输效率要远远低于Modbus RTU协议,一般只有在通信数据量较小的情况下才考虑使用Modbus ASCII通信协议
3)Modbus TCP:
运行在以太网上的协议

3.优势:

 免费、简单、容易使用

4.应用场景:

Modbus协议是现在国内工业领域应用最多的协议,不只PLC设备,各种终端设备,比如水控机、水表、电表、工业秤、各种采集设备

5.ModbusTCP特点:

1.采用主从问答方式进行通信
2.ModbusTCP是应用层协议,基于传输层TCP进行传输的
3.ModbusTCP端口号默认为502

Modbus TCP协议格式

ModbusTcp协议包含三部分:报文头、功能码、数据
在这里插入图片描述

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

1.报文头

包含7个字节,分别是:
在这里插入图片描述

2.寄存器

包含四种:离散量输入、线圈、输入寄存器、保持寄存器
1)离散量和线圈其实就是位寄存器(每个寄存器数据占1字节),工业上主要用于控制IO设备。
线圈寄存器,类比为开关量,每一个bit都对应一个信号的开关状态。所以一个byte就可以同时控制8路的信号。比如控制外部8路io的高低。 线圈寄存器支持读也支持写,写在功能码里面又分为写单个线圈寄存器和写多个线圈寄存器。
对应上面的功能码也就是:0x01 0x05 0x0f
离散输入寄存器,离散输入寄存器就相当于线圈寄存器的只读模式,他也是每个bit表示一个开关量,而他的开关量只能读取输入的开关信号,是不能够写的。比如我读取外部按键的按下还是松开。
所以功能码也简单就一个读的 0x02
2)输入和保持寄存器是字寄存器(每个寄存器数据占2个字节),工业上主要用于存储工业设备的值。
保持寄存器,这个寄存器的单位不再是bit而是两个byte,也就是可以存放具体的数据量的,并且是可读写的。比如我我设置时间年月日,不但可以写也可以读出来现在的时间。写也分为单个写和多个写
所以功能码有对应的三个:0x03 0x06 0x10
输入寄存器,这个和保持寄存器类似,但是也是只支持读而不能写。一个寄存器也是占据两个byte的空间。类比我我通过读取输入寄存器获取现在的AD采集值
对应的功能码也就一个 0x04

3.功能码

在这里插入图片描述
具体协议分析可参考:
http://www.360doc.com/content/20/0804/12/43769266_928452485.shtml

读数据:
主机->从机:报文头(7) + 功能码(1) + 起始地址(2)+ 数量(2)
从机->主机:报文头(7) + 功能码(1) + 字节计数(1)+ 数据(?)

写单个:
主机->从机:报文头(7) + 功能码(1) + 地址(2)+ 数据/断通标志(2)

写多个:
主机->从机:报文头(7) + 功能码(1) + 起始地址(2)+ 数量(2)+字节计数(1)+数据(?)

练习:读传感器数据,读1个寄存器数据,写出主从数据收发协议。
主机给从机:
|-事务处理标识符|-协议类型-|-字节长度-|-从机ID-|-功能码-|-起始地址-|-寄存器个数-|
0x0000 0x0000 0x0006 0x01 0x03 0x0000 0x0001
|-事务处理标识符|-协议类型-|-字节长度-|-从机ID-|-功能码-|-数据长度-|-寄存器数据-|
0x0000 0x0000 0x0005 0x01 0x03 0x02 0x0102

工具软件使用

.Modbus Slave&Poll

1)软件默认安装
2)破解
点击connection->connect,输入序列号即可
3)使用
先设置
在这里插入图片描述
后连接(连接时注意先开启slave端(相当于服务器),后起poll端(相当于客户端))
在这里插入图片描述查询windows IP:

win r 输入cmd
输入 ipconfig

2.网络调试助手

在这里插入图片描述

.Wireshark的使用

捕获器选择:
windows如果连接有线网络,选择本地连接/以太网
如果连接无线网络,选择WLAN
如果只是在本机上的通信,选择NPCAP Loopback apdater
或Adapter for loopback traffic capture
过滤条件:
过滤端口:tcp.port==502
过滤IP:ip.addr == 192.168.3.11(windows 的ip)
在这里插入图片描述
在这里插入图片描述

Modbus RTU

1、与Modbus TCP的区别

在一般工业场景使用modbus RTU的场景还是更多一些,modbus RTU基于串行协议进行收发数据,包括RS232/485等工业总线协议。
与modbus TCP不同的是RTU没有报文头MBAP字段,但是在尾部增加了两个CRC检验字节(CRC16),因为网络协议中自带校验,所以在TCP协议中不需要使用CRC校验码。
RTU和TCP的总体使用方法基本一致,只是在创建modbus对象时有所不同,TCP需要传入网络socket信息;而RTU需要传入串口相关信息。

2、Modbus RTU特点

ModbusRTU也是主从问答协议,由主机发起,一问一答
设置串口参数:
设置串口参数时要求:
波特率为9600
8位数据位
1位停止位
无流控

3.ModbusRTU协议格式:

ModbusRTU协议数据帧包含四部分:地址码、功能码、数据、校验码
地址码:从机ID 1-247
功能码:同ModbusTCP协议
数据:起始地址、数量、数据
校验码:2字节,对地址码、功能码、数据部分进行校验,调用函数自动生成

4.报文详解:

03功能码:
主机->从机: 01 03 00 00 00 01 84 0A
01:从机ID
03:功能码
00 00:起始地址
00 01:数量
84 0A:校验码

从机->主机:01 03 02 00 14 b8 44
1.01:从机ID
03:功能码
02: 字节计数
00 14:数据
b8 44 :校验码

参考示例:
https://blog.csdn.net/qq153471503/article/details/124317894

5.模拟器的使用

由于实际硬件产品成本较高,我们这里可以使用Modbus软件模拟器,进行数据模拟从而分析Modbus协议。
使用工具:

  1. ModbusPoll(模拟主机)和ModbusSlave(模拟从机)
  2. vspd虚拟串口
  3. UartAssist串口调试工具
    设置串口参数要求:波特率为9600 8位数据位 1位停止位 无流控 无校验
    虚拟串口的使用:

一、虚拟串口的安装

1.将压缩包解压后,双击vspd.exe文件进行安装
在这里插入图片描述
2.安装完成后,找到安装目录,将Cracked下的文件复制到软件安装目录

3.打开软件,添加com1和com2端口(用完记得删除端口)
4.添加完端口后,打开设备管理器,这里出现如下图所示即可。

在这里插入图片描述

二、虚拟机绑定端口

  1. 将虚拟机在系统关机(必须是关机状态,挂起不行)状态下,点击虚拟机->设置->硬件->添加串行端口,添加COM1
    2.添加完成后,第一次使用需要将电脑重启
    3.重启之后,开启虚拟机,点击虚拟机->可移动设备->串行端口->连接
    4.当连接上虚拟串口后,在终端输入dmesg | grep tty,可以查看到对应的设备文件,其中默认的会有ttyS0文件,剩下的就是虚拟串口对应的设备文件

三、测试通信

1.Windows打开串口调试工具,选择好串口COM2->COM1,设置对应的波特率
在这里插入图片描述
2.在虚拟机运行minicom
在虚拟机安装minicom软件
sudo apt-get install minicom
在终端执行sudo minicom -s
1)选择serial port setup,回车
在这里插入图片描述2)设置设备文件,波特率,关闭流控,按如下图设置(文件改成自己的)

在这里插入图片描述
3)修改完成后,回车,保存修改,选择save setup as dfl,敲回车,再次选择exit回车
在这里插入图片描述4)退出后就可以和windows下的串口调试工具进行通信测试
5)也可以在这个界面输入字符,查看串口助手的显示情况。

在这里插入图片描述
6)退出:ctrl+A、Z,在弹出的界面里输入X 回车,即可退出。

四、将Modbus Slave模拟器作为RTU设备的从机

虚拟机绑定COM1端口,slave连接COM2端口,虚拟机通过编程测试串口通信
Modbus Slave端的配置如下:
在这里插入图片描述

Modbus库

【1】库的安装

1.库的安装配置

1.在linux中解压压缩包
tar -xvf libmodbus-3.1.7.tar.gz
2.进入源码目录,创建文件夹(存放头文件、库文件)
cd libmodbus-3.1.7
mkdir install
3.执行脚本configure,进行安装配置(指定安装目录)
./configure --prefix=$PWD/install
4.执行make和make install
make//编译
make install//安装
执行完成后会在install文件夹下生产对应的头文件、库文件件夹。install用于存放产生的头文件、库文件等

2.库的使用

要想编译方便,可以将头文件和库文件放到系统路径下
sudo cp install/include/modbus/.h /usr/include
sudo cp install/lib/
-r /lib -d
后期编译时,可以直接gcc xx.c -lmodbus
头文件默认搜索路径:/usr/include 、/usr/local/include
库文件默认搜索路径:/lib、/usr/lib

【2】函数接口

modbus_t*   modbus_new_tcp(const char *ip, int port)
功能:以TCP方式创建Modbus实例,并初始化
参数:ip   :ip地址port:端口号
返回值:成功:Modbus实例失败:NULL
int modbus_set_slave(modbus_t *ctx, int slave)
功能:设置从机ID
参数:ctx   :Modbus实例slave:从机ID
返回值:成功:0失败:-1
int   modbus_connect(modbus_t *ctx)
功能:和从机(slave)建立连接
参数:ctx:Modbus实例
返回值:成功:0失败:-1
void   modbus_free(modbus_t *ctx)
功能:释放Modbus实例
参数:ctx:Modbus实例
void   modbus_close(modbus_t *ctx)
功能:关闭套接字
参数:ctx:Modbus实例
int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest)
功能:读取线圈状态,可读取多个连续线圈的状态(对应功能码为0x01)
参数:ctx   :Modbus实例addr :寄存器起始地址nb    :寄存器个数dest :得到的状态值
int  modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest)
功能:读取输入状态,可读取多个连续输入的状态(对应功能码为0x02)
参数:ctx   :Modbus实例addr :寄存器起始地址nb   :寄存器个数dest :得到的状态值
返回值:成功:返回nb的值
int  modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest)
功能:读取保持寄存器的值,可读取多个连续保持寄存器的值(对应功能码为0x03)
参数:ctx   :Modbus实例addr :寄存器起始地址nb    :寄存器个数dest :得到的寄存器的值
返回值:成功:读到寄存器的个数失败:-1
int   modbus_read_input_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest)
功能:读输入寄存器的值,可读取多个连续输入寄存器的值(对应功能码为0x04)
参数:ctx   :Modbus实例addr :寄存器起始地址nb    :寄存器个数dest :得到的寄存器的值
返回值:成功:读到寄存器的个数失败:-1
int  modbus_write_bit(modbus_t *ctx, int addr, int status);
功能:写入单个线圈的状态(对应功能码为0x05)
参数:ctx     :Modbus实例addr  :线圈地址status:线圈状态
返回值:成功:0失败:-1
int  modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *src);
功能:写入多个连续线圈的状态(对应功能码为15)
参数:ctx     :Modbus实例addr  :线圈地址nb     :线圈个数src    :多个线圈状态
返回值:成功:0失败:-1
int  modbus_write_register(modbus_t *ctx, int addr, int value);
功能:  写入单个寄存器(对应功能码为0x06)
参数: ctx    :Modbus实例addr  :寄存器地址value :寄存器的值 
返回值:成功:0失败:-1
int  modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src);
功能:写入多个连续寄存器(对应功能码为16)
参数:ctx    :Modbus实例addr  :寄存器地址nb     :寄存器的个数src    :多个寄存器的值 
返回值:成功:0失败:-1

【3】编程流程

1.创建实例
modbus_new_tcp
2.设置从机ID
modbus_set_slave
3.连接
modbus_connect
4.读写操作
调用功能码对应函数
5.关闭套接字
modbus_close
6.释放示例
modbus_free

基于Modbus的工业数据采集项目

1.Http简介

HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于Web Browser(浏览器)到Web Server(服务器)进行数据交互的传输协议。
HTTP是应用层协议
HTTP是一个基于TCP通信协议传输来传递数据(HTML 文件, 图片文件, 查询结果等)
HTTP协议工作于B/S架构上,浏览器作为HTTP客户端通过URL主动向HTTP服务端即WEB服务器发送所有请求,Web服务器根据接收到的请求后,向客户端发送响应信息。
HTTP默认端口号为80,但是你也可以改为8080或者其他端口

2.Http特点

HTTP是无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
HTTP是媒体独立的:这意味着,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。客户端以及服务器指定使用适合的MIME-type内容类型。
HTTP是无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

3.Http协议格式

客户端请求消息格式

客户端发送一个HTTP请求到服务器的请求消息包括以下格式:请求行、请求头部、空行和请求数据四个部分组成,下图给出了请求报文的一般格式。
在这里插入图片描述

a. 请求行:

请求行是由请求方法字段、url字段、http协议版本字段3个部分组成。请求行定义了本次请求的方式,格式如下:GET /example.html HTTP/1.1(CRLF)。

http的请求方式:
http协议中共定义了八种数据的请求方法。分别是:OPTIONS、HEAD、GET、POST、PUT、DELETE、TRACE、CONNECT;我们在实际应用中常用的也就是 get 和 post,其他请求方式也都可以通过这两种方式间接的来实现。
(增POST 删DELETE 改PUT 查GET)
GET方法和POST方法的区别?
GET通常用来从服务器上获得数据,而非修改信息;POST用来向服务器传递数据。
1.请求数据带参数,;GET请求的数据会附加在URL之后,以?分割URL和传输数据,多个参数用&连接。POST请求会把请求的数据放置在HTTP请求包的包体中。
因此,GET请求的数据会暴露在地址栏中,而POST请求则不会。
2.传输数据的大小;在HTTP规范中,没有对URL的长度和传输的数据大小进行限制。但是在实际开发过程中,对于GET,特定的浏览器和服务器对URL的长度有限制。因此,在使用GET请求时,传输数据会受到URL长度的限制。对于POST,由于不是URL传值,理论上是不会受限制的,但是实际上各个服务器会规定对POST提交数据大小进行限制,Apache、IIS都有各自的配置
3.GET请求返回的内容可以被浏览器缓存起来。而每次提交的POST,浏览器在你按 下F5的时候会跳出确认框,浏览器不会缓存POST请求返回的内容
4.GET对数据进行查询,POST主要对数据进行增删改!简单说,GET是只读,POST是写
5.对于参数的数据类型,get只接受ASCII字符,而post没有限制。

b. 请求头:

也被称作消息报头,请求头是由一些键值对组成,每行一对,关键字和值用英文冒号“:”分隔。允许客户端向服务器发送一些附加信息或者客户端自身的信息,典型的请求头如下:
Accept:作用:描述客户端希望接收的 响应body 数据类型;示例:Accept:text/html
Accept-Charset:作用:浏览器可以接受的字符编码集;示例:Accept-Charset:utf-8
Accept-Language:作用:浏览器可接受的语言;示例:Accept-Language:en
Connection:作用:表示是否需要持久连接,注意HTTP1.1默认进行持久连接;示例:Connection:close
Content-Length:作用:请求的内容长度:示例:Content-Length:348
Content-Type:作用:描述客户端发送的 body 数据类型

c. 空行

最后一个请求头之后是一个空行,发送回车符和换行符,通知服务器以下不再有请求头。

d. 请求体

请求数据:请求数据不在GET方法中使用,而是在POST方法中使用。POST方法适用于需要客户填写表单的场合。与请求数据相关的最常使用的请求头是Content-Type和Content-Length。

WebServer

简单TCP服务器示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <unistd.h>#define PORT 8080
#define BUFFER_SIZE 1024void handle_request(int client_socket) {char buffer[BUFFER_SIZE];char response[] = "HTTP/1.1 200 OK\nContent-Type: text/html\n\n<html><body><h1>Hello, World!</h1></body></html>";// 从客户端读取请求ssize_t bytes_read = read(client_socket, buffer, BUFFER_SIZE - 1);if (bytes_read == -1) {perror("读取请求失败");return;}buffer[bytes_read] = '\0';// 打印请求内容printf("收到请求:\n%s\n", buffer);// 发送响应给客户端ssize_t bytes_written = write(client_socket, response, strlen(response));if (bytes_written == -1) {perror("发送响应失败");}
}int main() {int server_socket, client_socket;struct sockaddr_in server_address, client_address;socklen_t client_address_len;//创建套接字if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {perror("创建套接字失败");exit(1);}//设置地址重用int reuse = 1;if (setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1) {perror("设置地址重用失败");exit(1);}//初始化绑定地址server_address.sin_family = AF_INET;server_address.sin_port = htons(PORT);server_address.sin_addr.s_addr = htonl(INADDR_ANY);if (bind(server_socket, (struct sockaddr *)&server_address, sizeof(server_address)) == -1) {perror("绑定地址失败");exit(1);}//启动监听if (listen(server_socket, 10) == -1) {perror("启动监听失败");exit(1);}printf("服务器已启动,监听端口 %d\n", PORT);// 接受连接并处理请求while (1) {client_address_len = sizeof(client_address);if ((client_socket = accept(server_socket, (struct sockaddr *)&client_address, &client_address_len)) == -1) {perror("接受连接失败");continue;}printf("接受新连接\n");// 处理请求handle_request(client_socket);// 关闭客户端套接字close(client_socket);printf("连接已关闭\n");}// 关闭服务器套接字close(server_socket);return 0;
}

1.服务器源码分析:

1.初始化服务器
2.循环等等待连接,连接后创建线程,调用线程函数msg_request,再函数中调用
handler_msg函数分析请求
3.handler_msg函数中,先查看请求内容,其次获取请求方法、URL、参数,判断请求方法是什么,对need_handler赋值,确定请求资源路径,如果请求地址没有携带任何资源,则默认返回index.html文件,如果资源不存在,返回404,如果需要处理(get请求带参数,post请求)调用handle_request函数,如果不需要(get请求不带参数且资源存在),调用echo_www函数,直接返回资源
4.handle_request函数主要用来获取post请求正文数据,调用parse_and_process函数处理正文内容(需要自己额外添加函数)

2.安装使用postman

在这里插入图片描述

3.结合Modbus部分整体流程分析

在这里插入图片描述

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

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

相关文章

Google Play上架:谷歌支付政策变更

目录 政策发布时间概括内容付款政策变动内容归纳google付款用户政策政策发布时间 2024 年 3 月 6 日 概括内容 为遵守《数字市场法案》(DMA) 的规定,从 2024 年 3 月 6 日起,我们将更新付款政策,允许开发者将欧洲经济区 (EEA) 的用户引导至其应用之外的平台(包括推广应用…

YUNBE云贝-PostgreSQL Vacuum详解:深入理解与实践

引言 PostgreSQL作为一款功能强大、开源的关系型数据库管理系统&#xff0c;其性能优化机制中&#xff0c;“VACUUM”命令扮演着至关重要的角色。本文将对PostgreSQL的VACUUM操作进行全面解析&#xff0c;探讨其工作原理、类型以及如何在实际环境中合理应用。 一、VACUUM基础概…

视频监控汇聚管理系统EasyCVR平台RTMP推流异常是什么原因?

AI视频智能分析/视频监控管理平台EasyCVR能在复杂的网络环境中&#xff08;专网、内网、局域网、广域网、公网等&#xff09;&#xff0c;支持设备通过4G、5G、WIFI、有线等方式接入&#xff0c;并将设备进行统一集中接入与视频汇聚管理&#xff0c;经平台接入的视频流能实现多…

无人机自动返航算法部署与飞行控制实践

一、环境准备 无人机硬件&#xff1a;确保你有一台支持自定义飞行控制的无人机&#xff0c;通常配备有Pixhawk或其他类似的飞行控制器。 地面站软件&#xff1a;安装如Mission Planner或QGroundControl等地面站软件&#xff0c;用于配置无人机参数和上传飞行控制代码。 编程环…

基于Python flask 的豆瓣电影排行榜,豆瓣电影评分可视化,豆瓣电影评分预测系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、Python技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&…

1+x中级题目练习复盘(四)

顺序存储较链式存储节省空间、查找性能高、插入和删除性能低。 <ALL表示小于最小 大于ANY表示大于最小值 LEFT OUTER JOIN 等同于LEFT JOIN INNER 和OUTER 不能同时出现 Before注解的方法在每个测试方法执行之前都要执行一次 一个Lambda表达式由以下三部分组…

什么软件可以剪辑录音?录音剪辑推荐3款工具

随着数字技术的发展&#xff0c;录音已经成为我们日常生活和工作中不可或缺的一部分。无论是会议记录、课堂笔记&#xff0c;还是音乐创作、语音聊天&#xff0c;我们都需要用到录音功能。然而&#xff0c;单纯的录音往往不能满足我们的需求&#xff0c;我们还需要对录音进行剪…

cesium-可视化区域分析

全部代码 <template><div id="cesiumContainer" style="height: 100vh;"></div><div id="toolbar" style="position: fixed;top:20px;left:220px;"><el-breadcrumb :separator-icon="ArrowRight&quo…

外卖小程序-购物车模块表结构设计和后端代码

表结构设计 添加购物车代码 Service public class ShoppingCartServiceImpl implements ShoppingCartService {Autowiredprivate ShoppingCartMapper shoppingCartMapper;Autowiredprivate DishMapper dishMapper;Autowiredprivate SetmealMapper setmealMapper;/*** 添加购物…

【C#】KeyDown事件不被触发的问题。

在c#的winform工程中&#xff0c;可能会遇到创建了一个对话框&#xff0c;该对话框内包含了控件作为这个对话框的一部分。软件运行时&#xff0c;键盘输入按键&#xff0c;却没有办法触发对话框的KeyDown事件。是不是很奇怪呢&#xff1f; 首先要明白&#xff1a;主对话…

MySQL--执行一条 select 语句,期间发生了什么?

执行一条 SQL 查询语句&#xff0c;期间发生了什么&#xff1f; 连接器&#xff1a;建立连接&#xff0c;管理连接、校验用户身份&#xff1b;查询缓存&#xff1a;查询语句如果命中查询缓存则直接返回&#xff0c;否则继续往下执行。MySQL 8.0 已删除该模块&#xff1b;解析 …

Vue.js+SpringBoot开发APK检测管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 开放平台模块2.3 软件档案模块2.4 软件检测模块2.5 软件举报模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 开放平台表3.2.2 软件档案表3.2.3 软件检测表3.2.4 软件举报表 四、系统展示五、核心代…

Linux命令:dmesg命令

目录 1 dmesg命令1.1 简介1.2 说明1.3 案例1、显示所有内核消息2、实时监控新消息3、显示特定级别的消息4、将消息输出到文件5、搜索包含特定字符串的被检测到的硬件6、将开机信息发邮件7、打印并清除内核环形缓冲区 总结 1 dmesg命令 1.1 简介 dmesg 命令在 Linux 系统中用于…

Lord 3DMCV7-AHRS 时间同步硬件触发设置

目的:通过FPGA发送脉冲触发IMU采集数据。FPGA发送脉冲时,IMU才有数据产生。 FPGA与IMU的硬件接线就不讲了,这里主要说明的是IMU的设置以及ROS驱动的config文件更改。 1. WIN上位机设置 通过IMU在WINDOWS的上位机SensorConnect对IMU的GPIO、波特率等基本功能进行设值,具体…

通过spring boot/redis/aspect 防止表单重复提交【防抖】

一、啥是防抖 所谓防抖&#xff0c;一是防用户手抖&#xff0c;二是防网络抖动。在Web系统中&#xff0c;表单提交是一个非常常见的功能&#xff0c;如果不加控制&#xff0c;容易因为用户的误操作或网络延迟导致同一请求被发送多次&#xff0c;进而生成重复的数据记录。要针…

用pyecharts的overlap绘制叠加图时,设置的颜色不起作用

问题 用pyecharts绘制叠加图时&#xff0c;如折线图上叠加散点图时&#xff0c;分别设置了自己的颜色&#xff08;三角是绿色&#xff0c;圆形是蓝色&#xff09;&#xff0c;但是渲染颜色和图例颜色不一致&#xff0c;如下图所示&#xff0c;折线颜色和散点颜色相同。 解决…

Leet code 904 水果成篮

解题思路&#xff1a;滑动窗口 创建hash表记录水果的种类和数量 两个指针left 和 right 从数组起始位置开始滑动&#xff0c;right在循环内 hash[fruits[right]] 进窗口 然后判断 hash表中的种类是否大于2 一旦大于2就要想办法出窗口 出窗口需要将hash表中种类重回2种 …

python做筛子用

import randomdef roll_dice():roll random.randint(1,10)return roll def main():total_times 100#初始化列表result_list[0]*10for i in range(total_times):print(roll_dice())for j in range(1,11):if roll_dice() j:result_list[j-1] 1if __name__ __main__:main() 结…

基于Java (spring-boot)的个人博客系统

一、项目介绍 登录模块&#xff1a;用户登录、用户注册 普通用户&#xff1a;博客主页、博客随笔、博客留言、个人信息修改 管理员&#xff1a;系统管理、内容管理、文章管理、随笔管理、分类管理、标签管理、留言管理、评论管理、文件管理 博客编辑&#xff1a;支持富文本编辑…

Autosar教程-Mcal教程-Fls配置教程

3.11.1 FLS基础知识 flash操作中有两个术语:block和page。block是flash最小的擦除单位,page则是flash写入的最小单位。以我们使用的F1KM-S4(R7F7016533)来说,它的是64 bytes, page是4bytes。这也就意味着,如果要擦除的话,最小要擦除64 bytes,但是写入可以按4字节的大小写入…