#网络高级 笔记

modbus_tcp协议
modbus_rtu协议和modbus库
http协议和web服务器搭建
服务器原码分析和基于WebServer的工业数据采集项目
第H5,即网页制作,项目完善

一、modbus起源

1.起源

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

2. 分类

Modbus RTU

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

Modbus ASCII

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

Modbus TCP

运行在以太网上的协议

3. 优势

免费、简单、容易使用

4. 应用场景

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

5. ModbusTCP特点(掌握)

1)采用主从问答式通信
2)Modbus TCP是应用层协议基于传输层的TCP进行通信的
3)Modbus TCP端口号默认502
注:更好的理解网络模型的分层特点:
各层之间独立,每一层不需要知道下一层如何实现
当任何一层发生变化时,只要层间接口关系保持不变,则这层以上或以下层不受影响。

二、ModbusTCP的协议格式

ModbusTcp协议包含三部分:报文头、功能码、数据
MBAP:Modbus Application Protocol (modbus报文头)
PDU:Protocol Data Unit(协议数据单元)
Modbus TCP/IP协议最大数据帧长度为260字节

1.报文头

包含7个字节

2. 寄存器

一共有四种类型的寄存器

线圈寄存器支持读也支持写,对应3个功能码
写在功能码里面又分为写单个线圈寄存器和写多个线圈寄存器。

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

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

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

总结:
读都是可以一个功能码读多个或单个的。而写是分为写单个和写多个,需要两个功能码。
所以对于只读的寄存器都只有一个功能码,而可读可写的寄存器都有三个功能码。

3. 功能码

功能码占一个字节

读数据:
主机→从机
报文头----功能码---起始地址---数量
从机→主机
报文头----功能码---字节计数---数据

写单个:
主机--》从机
报文头---功能码---地址--- 通/断标志 /数据
从机--》主机
原文返回

写多个
主机-->从机
报文头---功能码--起始地址--数量--字节计数--数据
从机-->主机
报文头---功能码--起始地址--数量

主机询问数据流
00 00 00 00 00 06 0103 00 6300 02
03:功能码
0x0063:起始地址 6*16+3=99 ,40100
0002:个数 40100 40101
从机应答数据流
00 00 00 00 00 07 01 030402 1330 08
03:功能码
04:字节计数
0213 :40100数据
3008: 40101数据

练习:
1. 读传感器数据,读1个寄存器数据,写出主从数据收发协议。
00 00 00 00 00 06 11 0100 0100 01
00 00 00 00 00 04 11  01 01 00
2. 写出控制IO设备开关的协议数据,操作1个线圈,置1。
00 00 00 00 00 06 11 05 00 63 ff 00
00 00 00 00 00 06 11 0500 63 ff 00

三、工具软件的使用

1. Modbus Slave/Poll

1) 软件默认安装
2) 破解 点击connection->connect ,输入序列号即可
3) 使用 先设置从机 从机相当于服务器

image.png

image.png


C/S Client /Server
B/S Browser /Server
 

image.png




image.png

2. 网络调试助手

02 2B      555

3. wireshark的使用

4. 网络恢复

保证虚拟机关机

image.png


点击更改设置,如果此时你可以点还原默认设置,直接点还原默认设置

image.png

点击还原默认设置

image.png


等待即可
重置完后重启虚拟机

然后进入虚拟机

如何确认网络可以了
1. ping命令,ping www.baidu.com
如果ping通了则调试成功
2. 打开浏览器看一看能不能打开网页
3. ifconfig看一看网段和windows的网段一不一样

可以对多个从站地址进行排版

03功能码实现封装

05功能码实现

整体代码

//客户端架构
#include <stdio.h>
#include <stdlib.h> // atoi
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>
int sockfd;
void set_slave_id(uint8_t*p,uint8_t id);
void read_registers(uint8_t *p,uint16_t addr,uint16_t nb,uint8_t* dest);
void write_coil(uint8_t *p,uint16_t addr,int op,uint8_t *dest);
int main(int argc, char const *argv[])
{//1.创建套接字sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0){perror("socket err");return -1;}socklen_t len = sizeof(struct sockaddr_in);struct sockaddr_in s;//2.填充结构体s.sin_family = AF_INET;s.sin_port = htons(atoi(argv[2]));s.sin_addr.s_addr = inet_addr(argv[1]);//3.连接if (connect(sockfd, (struct sockaddr *)&s, len) < 0){perror("connect err");return -1;}//实现03功能码 uint8_t buf[32]={0};uint8_t data[32]={0};set_slave_id(buf,0x02);
//     read_registers(buf,0x0000,0x0002,data);
// //  buf 00 00 00 00 00 06 01 03 00 00 00 02   
//     for (int i = 0; i < data[8]; i++)
//     {
//         printf("%02x ",data[9+i]);
//     }
//     printf("\n");write_coil(buf,0x0000,0,data);close(sockfd);return 0;
}
//buf 00 00 00 00 00 06 xx 03 00 00 00 00
//  buf 00 00 00 00 00 06 xx 03 xx xx xx xx
//设置从站地址
void set_slave_id(uint8_t*p,uint8_t id)
{p[6]=id;
}
//03功能码  读保持寄存器 发送的数组地址 指定其起始地址 指定数量 接收地址
void read_registers(uint8_t *p,uint16_t addr,uint16_t nb,uint8_t* dest)
{p[5]=0x06;p[7]=0x03;p[8]=addr >> 8; // 0000 0000 0000 0001p[9]=addr ;p[10]=nb >> 8;p[11]=nb ;//主机发送请求数据send(sockfd,p,32,0);//接收从机的回复recv(sockfd,dest,32,0);    
}//05功能码函数
}

四、Modbus RTU

1.与Modbus TCP的区别

在一般工业场景使用modbus RTU的场景还是更多一些,modbus RTU基于串行协议进行收发数据,包括RS232/485等工业总线协议。
与modbus TCP不同的是RTU没有报文头MBAP字段,但是在尾部增加了两个CRC检验字节(CRC16),因为网络协议中自带校验,所以在ModbusTCP协议中不需要使用CRC校验码。
RTU和TCP的总体使用方法基本一致,只是在创建modbus对象时有所不同,TCP需要传入网络socket信息;而RTU需要传入串口相关信息。
2、 Modbus RTU特点
Modbus RTU也是主从问答协议,由主机发起,一问一答
设置串口参数:
波特率为9600,8位数据位,1位停止位,无流控

当两台设备进行串口通信,假如他们对数据的处理速度不同。如果接收端数据缓冲区已满,则此时继续发送来的数据就会丢失。使用流控机制时,当接收端数据处理能力饱和时,就发出“不再接收”的信号,发送端就停止发送,直到接收端处理能力释放,发送“可以继续发送”的信号给发送端时,发送端才继续发送数据;

3、 Modbus RTU协议格式
ModbusRTU数据帧包含:地址码 功能码 数据 校验码
地址码:从机ID
功能码:同TCP
数据: 起始地址
校验码: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 B4 44
01:地址码 从机地址
03:功能码
02:字节计数
00 14:数据
B4 44:校验码

五、模拟器的使用

由于实际硬件产品成本较高,我们这里可以使用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端的配置如下:

五、可能会遇到的问题
1. 虚拟串口完成主机与vmware下虚拟机进行串口通信
https://blog.csdn.net/baidu_33232390/article/details/54954931
2. VSPD虚拟串口工具——从此告别硬件串口调试
https://blog.csdn.net/qq_34202873/article/details/88391265
3. vmware虚拟机检测不到vspd虚拟串口问题
https://blog.csdn.net/readnap/article/details/116659657
实现03功能码

#include "Crc_Calc.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
//串口实现ModbusRtu 并完成03功能码某一功能
int main(int argc, char const *argv[])
{//1.打开串口文件//2.初始化串口//3.创建要发送的03功能码数组// 01 03 00 00 00 01//4.根据创建的数组产生CRC校验,大小两个字节//5.把生成的CRC校验码放到要发送的03功能码数组中//6.往串口文件中写入拼好的03功能码数组//7.接收从机回应--即往串口文件中读取信息//8.打印从机回应//9.关闭文件return 0;
}

六、 Modbus库

库的安装
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,用于存放产生的头文件、库文件等
库的使用
要想编译方便,可以将头文件和库文件放到系统路径下
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

函数接口

modbus_t*   modbus_new_tcp(const char *ip, int port)
功能:以TCP方式创建Modbus实例,并初始化
参数:ip   :ip地址port:端口号
返回值:成功:Modbus实例失败:NULLint modbus_set_slave(modbus_t *ctx, int slave)
功能:设置从机ID
参数:ctx   :Modbus实例slave:从机ID
返回值:成功:0失败:-1int   modbus_connect(modbus_t *ctx)
功能:和从机(slave)建立连接
参数:ctx:Modbus实例
返回值:成功:0失败:-1void   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   :寄存器个数失败:-1

编程流程

1. 创建实例
modbus_new_tcp
2. 设置从机ID
modbus_set_slave
3. 建立连接
modbus_connect
4. 寄存器操作
功能码所对应的函数
5. 关闭套接字
modbus_close
6. 释放实例
modbus_free

练习:通过库函数实现03功能码采集数据
注意:编译不要忘了链接库、查看网络是否能用,查看slave端协议是否正确,查看slave端是否有对应的寄存器类型,查看slave id是否一致
gcc modbus.c -lmodbus


完成以下任务:
1.任务:编程实现采集传感器数据和控制硬件设备(传感器和硬件通过slave模拟)
传感器:2个,光线传感器、加速度传感器
硬件设备:2个,led灯、蜂鸣器
要求:
1.多任务编程:多线程
2.循环1s采集一次数据,并将数据打印至终端
3.同时从终端输入指令控制硬件设备
0 1 :led灯打开
0 0:led灯关闭
1 1:蜂鸣器开
1 0 : 蜂鸣器关
记得链接库 -lmodbus -lpthread

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

一、 http简介
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于Web Browser(浏览器)到Web Server(服务器)进行数据交互的传输协议。
HTTP是应用层协议,基于TCP通信协议传输来传递数据(HTML 文件, 图片文件, 查询结果等)
HTTP协议工作于B/S架构上,浏览器作为HTTP客户端通过URL主动向HTTP服务端即WEB服务器发送所有请求,Web服务器根据接收到的请求后,向客户端发送响应信息。
HTTP默认端口号为80,但是你也可以改为8080或者其他端口
二、 http特点
HTTP是短连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
HTTP是媒体独立的:这意味着,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。客户端以及服务器指定使用适合的MIME-type内容类型。
HTTP是无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

三、 Http协议格式

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

请求行是由请求方法字段、url字段、http协议版本字段3个部分组成。请求行定义了本次请求的方式,格式如下:GET /example.html HTTP/1.1(CRLF)。
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。
2)服务器响应消息格式
HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。
状态行:由三部分组成,HTTP协议的版本号、状态码、以及对状态码的文本描述。例如:HTTP/1.1 200 OK(CRLF) 。(200表示请求已经成功)

HTML

开发环境:vscode

可以在 www/root下面新建一个文件,例如:example.html

安装库open in browser

库安装完成后,在编写文本位置右击->open in other browser->选择合适的浏览器即可在网页显示html标签内容

输入html,选择html:5或者!回车可以将框架进行搭建

2. Html简介

HTML(英文Hyper Text Markup Language的缩写)中文译为“超文本标记语言”。是用来描述网页的一种语言。

所谓超文本,因为它可以加入图片、声音、动画、多媒体等内容,不仅如此,它还可以从一个文件跳转到另一个文件,与世界各地主机的文件连接。

HTML 不是一种编程语言,而是一种标记语言 (markup language)

Web 浏览器的作用是读取 HTML 文档,并以网页的形式显示出它们。浏览器不会显示 HTML 标签,而是使用标签来解释页面的内容

3.html标签

1.标签格式:

(1)有尖括号包围的关键字,如:<html>

(2)通常成对存在,如:<body> </body>

(3)上面的标签前面是开始标签,后面是结束标签

2.标签分类:

(1)单标签:也称空标签 <标签名 /> 如:<br/>

(2)双标签:成对存在 <标签名> 内容 </标签名>

常用标签:

1)h1-h6标题标签

格式:<hn> 标题文本 </hn>

举例:

<h1>这是标题标签</h1>

<h2>这是标题标签</h2>

<h3>这是标题标签</h3>

<h4>这是标题标签</h4>

<h5>这是标题标签</h5>

<h6>这是标题标签</h6>

2)p段落标签:

一个段落中会根据浏览器窗口的大小自动换行

格式:<p> 文本内容 </p>

3)br换行标签:

格式:<br />

4)div标签:

是一个块级元素,可以把文档分割为独立的、不同的部分,可以在div中嵌套标签

举例:

<div class="news">

<h2>News headline 1</h2>

<p>some text. some text. some text...</p>

</div>

注:可以给div设置class或id,通过选择器设置属性,则内部成员具有相同属性

5)Input表单标签:

表示输入意思,是单标签

格式:<input type=”” name=”” value=”” id=””.....>

属性有多种:

这里重点讲type为text、radio
当type为text,表示是文本输入框
        用法:<input type=”text” value=”文本框默认值” >

当type为radio,表示是单选框

        用法:<input type=”radio” name=”控件名称” value=”提交的数值” οnclick=”处理函数” checked=”checked”>

        解释:name:控件名称,同一组单选框设置相同名称

                //Value:必须要有,是当点击时会提交的数据

                Onclick:点击时会执行双引号中的处理函数

                Checked:默认选中,同一组中只设置一个即可

用‘,’拆分响应的字符串

var rep=response.split(',');

600,700

rep[0]=600

rep[1]=700

WebServer

基础服务器

#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 80
#define BUFFER_SIZE 1024void handle_request(int client_socket) {char buffer[BUFFER_SIZE];char response[] = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\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() {
}

强化服务器原码分析

web服务器原码分析 (qq.com)
1. 初始化服务器
2. 循环等待连接,连接后创建线程,调用msg_request函数,并在该函数中继续调用handler_msg函数分析数据
3. handler_msg中,首先查看协议内容,其次获取请求方法、url、参数,判断方法是什么并对need_handler赋值,确定请求资源路径,如果请求地址没有携带任何资源,那么默认返回index.html,如果资源不存在就返回404.如果需要处理(post请求或get请求带参数),调用handle_request函数,如果不需要(get请求不带参数)echo_www,直接返回资源
4. handle_request主要用来获取post请求消息正文,调用parse_and_process函数处理正文内容(需要自己添加需要功能)

安装使用postman

结合Modbus部分整体流程分析

通过postman模拟浏览器,实现Modbus Slave端数据采集和设备控制

注意:

存在共享内存和消息队列数据收发问题时。

解决方案:

  1. 在代码中加打印语句,确保两个进程用的是同一个id
  2. 由于程序是强制结束,再下次运行代码时,将消息队列删除一下查看和删除共享内存和消息队列:

        ipcs -m :查看共享内存

        ipcrm -m shmid:删除共享内存

        ipcs -q:查看消息队列

        ipcrm -q semid:删除消息队列

key值的创建路径指定/目录下的某个新建文件

多使用打印语句,排查错误位置

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

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

相关文章

python将字典数据保存为json文件

目录 一、json库介绍 二、字典生成json文件 1、导入 json 模块 2、将字典数据保存为 json 文件 (1) 创建一个python字典 (2) 指定要保存的 json 文件路径 (3) 将字典数据存为 json 文件 3、读取 json文件&#xff0c;并打印 一、json库介绍 方法作用json.dumps()将py…

对数据处理过程中,缺失值和异常值应该怎么处理?

创作不易&#xff0c;您的关注、点赞、收藏和转发是我坚持下去的动力&#xff01; 大家有技术交流指导、论文及技术文档写作指导、项目开发合作的需求可以私信联系我。 在数据处理过程中&#xff0c;缺失值和异常值的处理是非常重要的步骤&#xff0c;它们可能会对模型的性能…

Datawhale AI夏令营第五期学习!

学习日志 日期&#xff1a; 2024年8月27日 今日学习内容&#xff1a; 今天&#xff0c;我学习了如何在深度学习任务中使用卷积神经网络&#xff08;CNN&#xff09;进行图像分类的基本流程&#xff0c;并成功地在JupyterLab中运行了一个完整的项目。以下是我今天的学习和操作…

【扩散模型(六)】IP-Adapter 是如何训练的?2 源码篇(IP-Adapter Plus)

系列文章目录 【扩散模型&#xff08;二&#xff09;】IP-Adapter 从条件分支的视角&#xff0c;快速理解相关的可控生成研究【扩散模型&#xff08;三&#xff09;】IP-Adapter 源码详解1-训练输入 介绍了训练代码中的 image prompt 的输入部分&#xff0c;即 img projection…

【Verilog 数字系统设计教程】Verilog 基础:硬件描述语言入门指南

目录 摘要 1. 引言 2. Verilog 历史与发展 3. Verilog 基本语法 4. Verilog 模块与端口 5. 组合逻辑与时序逻辑 6. 时钟域与同步设计 7. 测试与仿真 8. Verilog 高级特性 任务&#xff08;Tasks&#xff09; 函数&#xff08;Functions&#xff09; 多维数组 结构体…

【二叉树】OJ题目

&#x1f31f;个人主页&#xff1a;落叶 目录 单值⼆叉树 【单值二叉树】代码 相同的树 【相同二叉树】代码 对称⼆叉树 【对称二叉树】代码 另一颗树的子树 【另一颗树的子树】代码 二叉树的前序遍历 【二叉树前序遍历】代码 二叉树的中序遍历 【二叉树中序遍历】…

【大模型】llama系列模型基础

前言&#xff1a;llama基于transformer架构&#xff0c;与GPT相似&#xff0c;只用了transformer的解码器部分。本文主要是关于llama&#xff0c;llama2和llama3的结构解读。 目录 1. llama1.1 整体结构1.2 RoPE1.3 SwiGLU 激活函数 2. llama22.2 GQA架构2.3 RLHF3. llama3 参考…

CAD中命令和系统变量

屏幕去除菜单全屏显示&#xff1a; ThisDrawing.SendCommand ("CLEANSCREENON ") 恢复原始&#xff1a;ThisDrawing.SendCommand ("CLEANSCREENOFF ") CAD中系统变量决定图形的基本设置。 第一个系统变量&#xff1a;uscicon vba代码如下&#xff1a; …

【Linux】——Rocky Linux配置静态IP

Rocky Linux配置静态IP Rocky Linux Rocky Linux 进入官网进行下载&#xff0c;下载版本自定义 官网link 获取ip地址 ip addr 获取服务器ip地址 进入网络配置文件目录&#xff1a; cd /etc/NetworkManager/system-connections/vi打开ens33.nmconnection 在IPv4下输入配置信…

Ubuntu美化为类Windows风格

博主的系统为 Ubuntu22.04 参考文献&#xff1a;How to Make Ubuntu Look Like Windows 11 | 22.04 GNOME 43 / 42 | Linux AF Tech 可能遇到的bug的解决方法&#xff1a;如何在 Linux 中安装和更改 GNOME 主题 先来一下视频演示&#xff1a; 下面正式开始安装。在主文件夹下打…

DWF 支持的 TON 链 Telegram 免费宠物游戏 Gatto_game,推出 “Paws Up! 世界锦标赛”

TON 链在这轮牛市里无疑是一匹脱缰的黑马&#xff0c;创造了一个又一个爆款&#xff0c;为持有者带来了不菲的收益。 Gatto_game 是一款 TON链 Tamagotchi 电子宠物风格的 P2E web3 游戏。可以通过喂养升级&#xff0c;参加比赛赚取 $TON 或者 $GTON &#xff0c;或许就是下一个…

python解释器[源代码层面]

1 PyDictObject 在c中STL中的map是基于 RB-tree平衡二元树实现&#xff0c;搜索的时间复杂度为O(log2n) Python中PyDictObject是基于散列表(散列函数)实现&#xff0c;搜索时间最优为O(1) 1.1 散列列表 问题&#xff1a;散列冲突&#xff1a;多个元素计算得到相同的哈希值 …

软件设计原则之依赖倒置原则

依赖倒置原则&#xff08;Dependency Inversion Principle, DIP&#xff09;是软件设计中一个非常重要的原则&#xff0c;它属于面向对象设计的SOLID原则之一。这个原则的核心在于通过抽象来降低模块间的耦合度&#xff0c;使得系统更加灵活和可维护。 目录 依赖倒置原则的基本…

「软件测试」最全面试问题和回答,全文背熟不拿下offer算我输

3.公司这边测试人员分配比例 4.进入公司&#xff0c;我这边大概的工作安排 5&#xff0c;公司这么后续发展机会还有培养 6&#xff0c;有没有培训 7&#xff0c;面试没有回答上的问题&#xff0c;再去请教 2.5 你的职业发展规划和职业目标 根据公司况&#xff0c;个人原因…

【Spring Boot 3】自定义拦截器

【Spring Boot 3】自定义拦截器 背景介绍开发环境开发步骤及源码工程目录结构总结背景 软件开发是一门实践性科学,对大多数人来说,学习一种新技术不是一开始就去深究其原理,而是先从做出一个可工作的DEMO入手。但在我个人学习和工作经历中,每次学习新技术总是要花费或多或…

机器学习 之 DBSCAN算法 及实现

1.K-means 与 DBSCAN 的比较 K-means 和 DBSCAN 都是聚类算法&#xff0c;但它们之间有显著的区别&#xff1a; K-means&#xff1a; 基于中心点的方法&#xff0c;要求用户提前指定簇的数量。适用于球形簇&#xff0c;且簇大小相近。无法处理噪声数据和任意形状的簇。 DBSCAN…

SQLi-LABS靶场36-40通过攻略

less-36 这一关是转义函数换成了mysql_real_escape_string,绕过方法与35关一致 1.判断注入点 2.判断闭合方式 id1A0 -- 3.查看页面回显点 ?id-1%A0%27%20%20union%20select%201,2,3-- 4.查询数据库名 ?id-1%A0%27%20%20union%20select%201,database(),3-- 5.查询数据库的…

音视频封装格式之FLV

FLV&#xff08;Flash Video&#xff09;是一种常见的视频文件格式&#xff0c;FLV 格式最初是由 Adobe 公司开发的&#xff0c;旨在为网络视频提供一种高效、可扩展且易于流式传输的解决方案。随着在线视频的迅速发展&#xff0c;FLV 因其良好的兼容性和流式传输性能&#xff…

喜羊羊做Python二级(模拟考试--易错点)

今天距离Python二级考试&#xff0c;还有28天左右。坚持每天做几套试卷&#xff0c;保持记忆和手感。 个人在做题的过程中是先不断练习选择题。当你选择题不达标的时候&#xff0c;系统不会看大题&#xff08;大概是觉得选择题都做的那么差&#xff0c;大题也不会那么好&#…

mac 虚拟机PD19运行E-prime实验遇到E-prime unable to set display mode:0*80004001问题解决

作者&#xff1a;50% unable to set display mode问题 总结&#xff1a; 1. 修改该Experiment的Devices中的Dispaly为640*680&#xff0c;Color Bit Depth设置为32。&#xff08;这个分辨率仅限于学习用&#xff0c;实际实验应该还是在真机上&#xff09; 2. 右键开始菜单中的E…