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

Linux网络编程:libevent事件通知库

文章目录:

一:libevent库

二:libevent框架

1.常规事件event

1.1 创建事件event(event_new) 

1.2 添加事件到 event_base(event_add) 

1.3 从event_base上摘下事件(event_del)

1.4 销毁事件(event_free)

1.5 未决和非未决

read_fifo.c

write_fifo.c

2.带缓冲区的事件bufferevent

2.1 带缓冲区的事件 bufferevent

2.2 创建、销毁bufferevent(bufferevent_socket_new 、bufferevent_socket_free)

2.3 给bufferevent设置回调(bufferevent_setcb)

2.4 启动、关闭 bufferevent的 缓冲区(bufferevent_enable、bufferevnet_disable)

三:网络通信 

1.服务端

1.1 创建和释放监听服务器(evconnlistener_new_bind、evconnlistener_free) 

1.2 服务器端 libevent 创建TCP连接流程

ev_server.c

2.客户端

2.1 连接客户端(bufferevent_socket_connect) 

2.2 Libevent实现TCP客户端流程 

ev_client.c


一:libevent库

libevent官网

libevent库开源;精简;跨平台(Windows、Linux、maxos、unix);专注于网络通信源码包安装:  参考 README、readme./configure		    检查安装环境 生成 makefilemake			    生成 .o 和 可执行文件sudo make install	将必要的资源cp置系统指定目录进入 sample 目录,运行demo验证库安装使用情况编译使用库的 .c 时,需要加 -levent 选项库名 libevent.so --> /usr/local/lib   查看的到特性:基于“事件”异步通信模型。--- 回调

二:libevent框架

libevent框架:1. 创建 event_base		(乐高底座)struct event_base *event_base_new(void);struct event_base *base = event_base_new();2. 创建 事件evnet	   (积木)常规事件       event	   --> event_new(); 带缓冲区的事件 bufferevent --> bufferevent_socket_new();3. 将事件 添加到 base上	int event_add(struct event *ev, const struct timeval *tv)4. 循环监听事件满足int event_base_dispatch(struct event_base *base);event_base_dispatch(base);5. 释放 event_baseevent_base_free(base);

1.常规事件event

1.1 创建事件event(event_new) 

创建事件event:struct event *ev;struct event *event_new(struct event_base *base,evutil_socket_t fd,short what,event_callback_fn cb;  void *arg);base: event_base_new()返回值fd: 绑定到 event 上的 文件描述符what:对应的事件(r、w、e)EV_READ		一次 读事件EV_WRTIE	一次 写事件EV_PERSIST	持续触发。 结合 event_base_dispatch 函数使用,生效cb:一旦事件满足监听条件,回调的函数typedef void (*event_callback_fn)(evutil_socket_t fd,  short,  void *)	arg: 回调的函数的参数返回值:成功创建的 event

1.2 添加事件到 event_base(event_add) 

添加事件到 event_baseint event_add(struct event *ev, const struct timeval *tv);ev: event_new() 的返回值tv:NULL

1.3 从event_base上摘下事件(event_del)

从event_base上摘下事件				【了解】int event_del(struct event *ev);ev: event_new() 的返回值

1.4 销毁事件(event_free)


销毁事件int event_free(struct event *ev);ev: event_new() 的返回值

1.5 未决和非未决

未决和非未决:非未决: 没有资格被处理未  决:有资格被处理,但尚未被处理event_new --> event ---> 非未决 --> event_add --> 未决 --> dispatch() && 监听事件被触发 --> 激活态 --> 执行回调函数 --> 处理态 --> 非未决 event_add && EV_PERSIST --> 未决 --> event_del --> 非未决

read_fifo.c

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>
#include <event2/event.h>// 对操作处理函数
void read_cb(evutil_socket_t fd, short what, void *arg)
{// 读管道char buf[1024] = {0};int len = read(fd, buf, sizeof(buf));printf("read event: %s \n", what & EV_READ ? "Yes" : "No");printf("data len = %d, buf = %s\n", len, buf);sleep(1);
}// 读管道
int main(int argc, const char* argv[])
{unlink("myfifo");//创建有名管道mkfifo("myfifo", 0664);// open file//int fd = open("myfifo", O_RDONLY | O_NONBLOCK);int fd = open("myfifo", O_RDONLY);if(fd == -1){perror("open error");exit(1);}// 创建个event_basestruct event_base* base = NULL;base = event_base_new();// 创建事件struct event* ev = NULL;ev = event_new(base, fd, EV_READ | EV_PERSIST, read_cb, NULL);// 添加事件event_add(ev, NULL);// 事件循环event_base_dispatch(base);  // while(1) { epoll();}// 释放资源event_free(ev);event_base_free(base);close(fd);return 0;
}

write_fifo.c

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>
#include <event2/event.h>// 对操作处理函数
void write_cb(evutil_socket_t fd, short what, void *arg)
{// write管道char buf[1024] = {0};static int num = 0;sprintf(buf, "hello,world-%d\n", num++);write(fd, buf, strlen(buf)+1);sleep(1);
}// 写管道
int main(int argc, const char* argv[])
{// open file//int fd = open("myfifo", O_WRONLY | O_NONBLOCK);int fd = open("myfifo", O_WRONLY);if(fd == -1){perror("open error");exit(1);}// 写管道struct event_base* base = NULL;base = event_base_new();// 创建事件struct event* ev = NULL;// 检测的写缓冲区是否有空间写//ev = event_new(base, fd, EV_WRITE , write_cb, NULL);ev = event_new(base, fd, EV_WRITE | EV_PERSIST, write_cb, NULL);// 添加事件event_add(ev, NULL);// 事件循环event_base_dispatch(base);// 释放资源event_free(ev);event_base_free(base);close(fd);return 0;
}

2.带缓冲区的事件bufferevent

2.1 带缓冲区的事件 bufferevent

带缓冲区的事件 bufferevent#include <event2/bufferevent.h> read/write 两个缓冲. 借助 队列原理: bufferent利用队列实现两个缓冲区(数据读走就没, FIFO);读: 有数据, 读回调函数被调用, 使用bufferevent_read()读数据;写: 使用bufferevent_write, 向写缓冲中写数据, 该缓冲区中有数据自动写出, 写完后, 回调函数被调用(鸡肋);

2.2 创建、销毁bufferevent(bufferevent_socket_new 、bufferevent_socket_free)

创建bufferevent:struct bufferevent* bufferevent_socket_new(struct event_base* base,evutil_socket_t fd,enum bfferevent_options options)base: 基事件, event_base_new函数的返回值;fd:封装到bufferevent内的fd(绑定在一起);enum表示枚举类型, 一般取BEV_OPT_CLOSE_ON_FREE;成功返回bufferevent事件对象;销毁bufferevent:void bufferevent_socket_free(struct bufferevent* ev)

2.3 给bufferevent设置回调(bufferevent_setcb)

给bufferevent设置回调:对比event:	event_new( fd, callback );  					event_add() -- 挂到 event_base 上。bufferevent_socket_new(fd)					bufferevent_setcb( callback )void bufferevent_setcb(struct bufferevent * bufev,bufferevent_data_cb readcb,bufferevent_data_cb writecb,bufferevent_event_cb eventcb,void *cbarg );bufev: bufferevent_socket_new() 返回值readcb: 设置 bufferevent 读缓冲,对应回调  read_cb{  bufferevent_read() 读数据  }writecb: 设置 bufferevent 写缓冲,对应回调 write_cb {  } -- 给调用者,发送写成功通知。  可以 NULLeventcb: 可传NULL;cbarg: 回调函数的参数;eventcb: 设置 事件回调。   也可传NULLtypedef void (*bufferevent_event_cb)(struct bufferevent *bev,  short events, void *ctx);void event_cb(struct bufferevent *bev,  short events, void *ctx){。。。。。}events: BEV_EVENT_CONNECTEDread 读回调函数类型(read_cb :bufferevent_read()):typedef void (*bufferevent_data_cb)(struct bufferevent *bev, void*ctx);void read_cb(struct bufferevent *bev, void *cbarg ){.....bufferevent_read();   --- read();}bufferevent_read()函数的原型:size_t bufferevent_read(struct bufferevent *bev, void *buf, size_t bufsize);write 写回调函数类型(bufferevent_write):int bufferevent_write(struct bufferevent *bufev, const void *data,  size_t size); 

2.4 启动、关闭 bufferevent的 缓冲区(bufferevent_enable、bufferevnet_disable)

启动、关闭 bufferevent的 缓冲区:void bufferevent_enable(struct bufferevent* bufev,short events);		//启用缓冲区void bufferevnet_disable(struct bufferevent* bufev,short events);		//禁用	events的值可传入三个宏: EV_READ、EV_WRITE、EV_READ|EV_WRITE默认、write 缓冲是 enable、read 缓冲是 disablebufferevent_enable(evev, EV_READ);		-- 开启读缓冲

三:网络通信 

1.服务端

1.1 创建和释放监听服务器(evconnlistener_new_bind、evconnlistener_free) 

创建监听服务器:------ socket();bind();listen();accept();struct evconnlistener * listner//这一个函数可以完成`socket(),bind(),listen(),accept()`四个函数的作用struct evconnlistener *evconnlistener_new_bind (	struct event_base *base,evconnlistener_cb cb, void *ptr, unsigned flags,int backlog,const struct sockaddr *sa,int socklen);base: event_basecb: 回调函数。 一旦被回调,说明在其内部应该与客户端完成, 数据读写操作,进行通信ptr: 回调函数的参数flags: LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLEbacklog: listen() 2参。 -1 表最大值sa:服务器自己的地址结构体socklen:服务器自己的地址结构体大小返回值:成功创建的监听器//回调函数的类型typedef void (*evconnlistener_cb)(struct evconnlistener* listener,evutil_socker_t sock,struct sockaddr* addr,int len,void* ptr);listener:evconnlistener_new_bind函数的返回值;sock:用于通信的文件描述符;addr:客户端的地址结构;len:客户端地址结构的长度;ptr:外部ptr传进来的值;释放监听服务器:void evconnlistener_free(struct evconnlistener *lev);

1.2 服务器端 libevent 创建TCP连接流程

服务器端 libevent 创建TCP连接:1. 创建event_base2. 创建bufferevent事件对象。bufferevent_socket_new()3. 使用bufferevent_setcb() 函数给 bufferevent的 read、write、event 设置回调函数4. 当监听的 事件满足时,read_cb会被调用, 在其内部 bufferevent_read()读5. 使用 evconnlistener_new_bind 创建监听服务器, 设置其回调函数,当有客户端成功连接时,这个回调函数会被调用6. 封装 listner_cb() 在函数内部。完成与客户端通信7. 设置读缓冲、写缓冲的 使能状态 enable、disable8. 启动循环 event_base_dispath()9. 释放连接

ev_server.c

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <event2/event.h>
#include <event2/listener.h>
#include <event2/bufferevent.h>// 读缓冲区回调
void read_cb(struct bufferevent *bev, void *arg)
{char buf[1024] = {0}; // 借助读缓冲,从客户端拿数据  bufferevent_read(bev, buf, sizeof(buf));printf("client say: %s\n", buf);char *p = "我是服务器, 已经成功收到你发送的数据!";// 借助写缓冲,写数据回给客户端bufferevent_write(bev, p, strlen(p)+1);sleep(1);
}// 写缓冲区回调
void write_cb(struct bufferevent *bev, void *arg)
{printf("I'm服务器, 成功写数据给客户端,写缓冲区回调函数被回调...\n"); 
}// 事件
void event_cb(struct bufferevent *bev, short events, void *arg)
{if (events & BEV_EVENT_EOF){printf("connection closed\n");  }else if(events & BEV_EVENT_ERROR)   {printf("some other error\n");}bufferevent_free(bev);    printf("buffevent 资源已经被释放...\n"); 
}// 被回调,说明有客户端成功连接, cfd已经传入该参数内部。 创建bufferevent事件对象
//与客户端完成读写操作
void cb_listener(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *addr, int len, void *ptr)
{printf("connect new client\n");struct event_base* base = (struct event_base*)ptr;// 通信操作// 创建添加新事件bufferevent 对象struct bufferevent *bev;bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);// 给bufferevent缓冲区设置回调 read、write、eventvoid bufferevent_setcb(struct bufferevent * bufev,bufferevent_data_cb readcb,bufferevent_data_cb writecb,bufferevent_event_cb eventcb,void *cbarg );//设置回调函数bufferevent_setcb(bev, read_cb, write_cb, event_cb,NULL,NULL);//启动 read 缓冲区的 使能状态bufferevent_enable(bev, EV_READ);
}int main(int argc, const char* argv[])
{// 定义服务器地址结构init server struct sockaddr_in serv;memset(&serv, 0, sizeof(serv));serv.sin_family = AF_INET;serv.sin_port = htons(9876);serv.sin_addr.s_addr = htonl(INADDR_ANY);// 创建event_basestruct event_base* base;base = event_base_new();// 创建套接字// 绑定// 创建服务器监听器:接收连接请求struct evconnlistener* listener;                                            //监听器listener = evconnlistener_new_bind(base, cb_listener, base, LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, 36, (struct sockaddr*)&serv, sizeof(serv));//启动监听循环event_base_dispatch(base);//销毁event_baseevconnlistener_free(listener);event_base_free(base);return 0;
}

2.客户端

2.1 连接客户端(bufferevent_socket_connect) 

连接客户端:socket();connect();int bufferevent_socket_connect(struct bufferevent *bev, struct sockaddr *address, int addrlen);bev: bufferevent 事件对象(封装了fd)address、len:等同于 connect() 参2/3

2.2 Libevent实现TCP客户端流程 

Libevent实现TCP客户端流程1.创建event_basev2.使用bufferevnet_socket_new()创建一个用跟服务器通信的 bufferevnet事件对象3.使用bufferevnet_socket_connect()连接服务器4.使用bufferevent_setcb()给 bufferevnet对象的 read、write、event设置回调5.设置bufferevnet 对象的读写缓冲区enable / disable6.接受、发送数据bufferevent_read() / bufferevent_write()7.启动循环监听event_base_dispatch8.释放资源

ev_client.c

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <event2/bufferevent.h>
#include <event2/event.h>
#include <arpa/inet.h>void read_cb(struct bufferevent *bev, void *arg)
{char buf[1024] = {0}; bufferevent_read(bev, buf, sizeof(buf));printf("fwq say:%s\n", buf);bufferevent_write(bev, buf, strlen(buf)+1);sleep(1);
}void write_cb(struct bufferevent *bev, void *arg)
{printf("----------我是客户端的写回调函数,没卵用\n"); 
}void event_cb(struct bufferevent *bev, short events, void *arg)
{if (events & BEV_EVENT_EOF){printf("connection closed\n");  }else if(events & BEV_EVENT_ERROR)   {printf("some other error\n");}else if(events & BEV_EVENT_CONNECTED){printf("已经连接服务器...\\(^o^)/...\n");return;}// 释放资源bufferevent_free(bev);
}// 客户端与用户交互,从终端读取数据写给服务器
void read_terminal(evutil_socket_t fd, short what, void *arg)
{// 读数据char buf[1024] = {0};int len = read(fd, buf, sizeof(buf));struct bufferevent* bev = (struct bufferevent*)arg;// 发送数据bufferevent_write(bev, buf, len+1);
}int main(int argc, const char* argv[])
{struct event_base* base = NULL;base = event_base_new();int fd = socket(AF_INET, SOCK_STREAM, 0);// 通信的fd放到bufferevent中struct bufferevent* bev = NULL;bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);// init server infostruct sockaddr_in serv;memset(&serv, 0, sizeof(serv));serv.sin_family = AF_INET;serv.sin_port = htons(9876);inet_pton(AF_INET, "127.0.0.1", &serv.sin_addr.s_addr);// 连接服务器bufferevent_socket_connect(bev, (struct sockaddr*)&serv, sizeof(serv));// 设置回调bufferevent_setcb(bev, read_cb, write_cb, event_cb, NULL);// 设置读回调生效// bufferevent_enable(bev, EV_READ);// 创建事件struct event* ev = event_new(base, STDIN_FILENO, EV_READ | EV_PERSIST,read_terminal, bev);// 添加事件                     event_add(ev, NULL);event_base_dispatch(base);event_free(ev);event_base_free(base);return 0;
}

相关文章:

Linux网络编程:libevent事件通知库

文章目录&#xff1a; 一&#xff1a;libevent库 二&#xff1a;libevent框架 1.常规事件event 1.1 创建事件event&#xff08;event_new&#xff09; 1.2 添加事件到 event_base&#xff08;event_add&#xff09; 1.3 从event_base上摘下事件&#xff08;event_del&a…...

java.lang.reflect.InvocationTargetException:null报未知异常

在项目上线过程中&#xff0c;突然出现大量异常信息&#xff0c;堆栈信息如下&#xff1a; java.lang.reflect.InvocationTargetException: null at jdk .internal.reflect.GeneratedMethodAccessor792 .invoke(Unknown Source) ~[?:?] at jdk.internal.reflect.DelegatingM…...

MySQL高级篇——MySQL架构篇1(Linux下MySQL8的安装与使用)

目录 0 安装前0.1 Linux系统及工具的准备0.2 查看是否安装过MySQL0.3 MySQL的卸载 1 MySQL8的Linux版安装1.1 MySQL的4大版本1.2 下载MySQL指定版本1.3 CentOS7下检查MySQL依赖1.4 CentOS7下MySQL安装过程 2 MySQL登录2.1 首次登录2.2 修改密码2.3 设置远程登录 3 MySQL 8 的密…...

解决 go mod tidy 加载模块超时

如果go mod tidy 加载模块超时 解决方法 修改GOPROXY: 查看go环境相关信息&#xff1a; go envgo env -w GOPROXYhttps://goproxy.cn...

金融市场中的机器学习;快手推出自研语言模型“快意”

&#x1f989; AI新闻 &#x1f680; OpenAI可能面临《纽约时报》的起诉&#xff0c;侵犯知识产权引发争议 摘要&#xff1a;OpenAI使用《纽约时报》的文章和图片来训练AI模型&#xff0c;违反了《纽约时报》的服务条款&#xff0c;可能面临巨大损失。此前&#xff0c;也有其…...

【面试刷题】——什么是深拷贝和浅拷贝?

深拷贝&#xff08;Deep Copy&#xff09;和浅拷贝&#xff08;Shallow Copy&#xff09;是在编程中用来描述对象拷贝的两个概念&#xff0c;特别是在涉及对象包含其他对象&#xff08;如嵌套数据结构、指针等&#xff09;的情况下。 浅拷贝&#xff08;Shallow Copy&#xff…...

物联网(IoT)安全挑战与解决方案: 分析物联网设备面临的安全威胁,以及如何设计和管理安全的IoT生态系统

第一章&#xff1a;引言 随着科技的飞速发展&#xff0c;物联网&#xff08;IoT&#xff09;作为连接世界的桥梁&#xff0c;已经成为现代社会不可或缺的一部分。然而&#xff0c;随着IoT设备数量的不断增加&#xff0c;其安全问题也日益显著。本文将深入探讨IoT领域面临的安全…...

Ubuntu 22.04.3 LTS 维护更新发布

近日消息&#xff0c;Canonical 今天发布了代号为 Jammy Jellyfish、长期支持的 Ubuntu 22.04 第 3 个维护版本更新&#xff0c;距离上个版本相隔 6 周时间。 Ubuntu 22.04.3 LTS 最大的亮点在于内核升级到 Linux Kernel 6.2&#xff0c;此外 Mesa 图形堆栈也升级到 23.0.4 版…...

平安健康,找到了医疗服务的价值密码

健康是人类的永恒需求&#xff0c;围绕医疗和健康服务衍生的产业&#xff0c;却苦于无法和用户建立足够紧密、长期的联系。由此&#xff0c;也不得不面临价值从何而来的问题。 作为医疗服务领域的代表性企业&#xff0c;平安健康医疗科技有限公司&#xff08;股票简称“平安好…...

❤ vue 使用原生组件

❤ vue 使用原生组件 1、做一个input输入框验证开始 ① 想让我们的input输入框类型为时间&#xff0c;只需要为我们的输入框简单的加一个类型的type即可 <input type"date" id"birthday" name"birthday" placeholder"年/月/日"&…...

4.12 TCP 连接,一端断电和进程崩溃有什么区别?

目录 TCP keepalive TCP 的保活机制 主机崩溃 进程崩溃 有数据传输的场景 客户端主机宕机&#xff0c;又迅速重启 客户端主机宕机&#xff0c;一直没有重启 TCP连接服务器宕机和进程退出情况总结 TCP keepalive TCP 的保活机制 TCP 保活机制需要通过 socket 接口设置 S…...

十二、pikachu之URL重定向

文章目录 1、URL重定向概述2、实战3、URL跳转的几种方式:3.1 META标签内跳转3.2 javascript跳转3.3 header头跳转 1、URL重定向概述 不安全的url跳转问题可能发生在一切执行了url地址跳转的地方。如果后端采用了前端传进来的&#xff08;可能是用户传参&#xff0c;或者之前预埋…...

贝叶斯公式中的动词 命名技巧

一项血液化验有95%的把我诊断某种疾病&#xff0c;但是&#xff0c;这项化验用于健康人也会有1%的“伪阳性”结果(即如果一个健康人接受这项化验&#xff0c;则化验结果乌镇此人患有该疾病的概率是0.01)。如果该疾病的患者事实上只占总人口的0.5%&#xff0c;若某人化验结果为阳…...

ctfshow-web13 文件上传

0x00 前言 CTF 加解密合集CTF Web合集 0x01 题目 0x02 Write Up 首先看到是一个上传页面&#xff0c;测试其他无果&#xff0c;遂进行目录遍历&#xff0c;发现upload.php.bak文件 可以看到这里的限制条件&#xff0c;大小&#xff0c;以及内容&#xff0c;这里可以使用.use…...

Python项目开发案例————学生信息管理系统(附源码)

一、学生信息管理系统 本文使用Python语言开发了一个学生信息管理系统&#xff0c;该系统可以帮助教师快速录入学生的信息&#xff0c;并且对学生的信息进行基本的增、删、改、查操作&#xff1b;还可以实时地将学生的信息保存到磁盘文件中。 1.1 需求分析 为了顺应互联网时代…...

2023-08-25力扣每日一题

链接&#xff1a; 1448. 统计二叉树中好节点的数目 题意&#xff1a; 判断根节点到每个节点X的过程中&#xff0c;如果没有值大于X&#xff0c;则该节点为好节点&#xff0c;求好节点数量 解&#xff1a; 由于求根节点到其他节点的路径&#xff0c;则使用dfs算法&#xff…...

Vue3中的计算属性和属性监听

compute计算属性 Vue3中可以通过 compute进行监听计算属性&#xff0c;他返回的是一个ref的对象&#xff0c;也就是说 通过compuye这种方式计算属性实际上是进行了ref的操作 import { computed } from vue const user reactive({firstName: A,lastName: B }) // 只有getter的…...

微信开发之一键修改群公告的技术实现

简要描述&#xff1a; 设置群公告 请求URL&#xff1a; http://域名地址/setChatRoomAnnouncement 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-Type&#xff1a;application/jsonAuthorization&#xff1a;login接口返回 参数&#xff1a; 参数名必…...

【git】工作场景中常用的git命令

工作场景中常用的git命令 1. 必备改名改邮箱拉代码下来并且创建新分支git commit回滚某个文件删除分支 工作场景中常用的git命令&#xff0c;记录下来方便调取 1. 必备 改名改邮箱 一般与他人合作&#xff0c;至少你提交的名字得被人熟知或者遵循规范&#xff0c;因此需要更改…...

Vue路由(详解)

目录 路由原理 路由到底有什么作用&#xff1f; 路由安装和使用&#xff08;vue2&#xff09; 路由跳转 跳转实例&#xff1a; 路由的传值和取值 传值实例&#xff1a; 查询参和路由参的区别&#xff1a; 嵌套路由 嵌套实例&#xff1a; 路由守卫 守卫实例&#xff1…...

打开软件提示msvcp140.dll丢失的解决方法,msvcp140主要丢失原因

今天&#xff0c;我将为大家介绍一种非常常见的问题——msvcp140.dll丢失。这个问题可能会导致许多应用程序无法正常运行&#xff0c;甚至崩溃。但是&#xff0c;请不要担心&#xff0c;我会为大家提供5种解决方法&#xff0c;帮助大家轻松解决问题。 首先&#xff0c;我们来看…...

关于路由器和DNS解析的一些新理解

其实我本人对于交换机和路由器这些网络硬件是比较感兴趣的&#xff0c;也在一点一点的学习相关知识&#xff0c;每次解决一个问题&#xff0c;就让我对一些事情有新的思考。。 今天前台同事&#xff0c;的机器突然上不了网&#xff0c;&#xff0c;和领导一起去看了一波&#…...

vscode 与 C++

序 具体流程的话&#xff0c;官方文档里都有的&#xff1a;C programming with Visual Studio Code 浏览器下载一个mingw64&#xff0c;解压&#xff0c;配置环境变量vscode里安装c相关的插件没了 第一步只看文字&#xff0c;可能有点抽象&#xff0c;相关视频&#xff1a; …...

水果flstudio好用吗?中文版FL21最新版本如何下载

FL Studio21版是一款功能强大的音乐制作软件&#xff0c;广泛应用于电子音乐、流行音乐、电影配乐等领域。它提供了丰富多样的音频合成和编辑工具&#xff0c;使音乐制作变得更加灵活多样。无论是初学者还是专业音乐制作人&#xff0c;都可以通过直观的界面和丰富的音频特效来实…...

PHP is_array()函数详解,PHP判断是否为数组

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 is_array 一、基本使用二、空数组三、同时判断多个…...

面试题-React(三):什么是JSX?它与常规JavaScript有什么不同?

在React的世界中&#xff0c;JSX是一项引人注目的技术&#xff0c;它允许开发者在JavaScript中嵌套类似HTML的标签&#xff0c;用于描述UI组件的结构。本篇博客将通过丰富的代码示例&#xff0c;深入探索JSX语法&#xff0c;解析其在React中的用法和优势。 一、JSX基础语法 在…...

纯前端实现图片上传七牛云

首先安装下依赖&#xff1a; npm install qiniu-js crypto-js 然后封装一下 uploaderHelper.ts import * as qiniu from qiniu-js; // ts-ignore import CryptoJS from crypto-js// 请求接口上传图片 export function uploadFile(file: File) {const uptoken getToken(你的…...

win10+wsl2+Ubuntu20.2+Pycharm+WSL解释器

目的&#xff1a;创建一个ubuntu系统下的python解释器&#xff0c;作为win平台下的pycharm的解释器。 这样做的好处是可以直接在win系统里操作文件&#xff0c;相比于linux方便一点&#xff0c;而且也不用对wsl的子系统进行迁移。 一、安装前准备 1. 设置-Windows更新-window…...

EL与JSTL

目录 EL EL语法 EL运算符 JSTL JSTL标签分类 JSP脚本&#xff1a;代码结构混乱、脚本与HTML 混合易出错、代码不易维护。 EL表达式&#xff1a;优化程序代码&#xff0c;增加程序可读性。 EL EL语法 EL表达式 ${ EL 表达式 } EL操作符 操作符“ . ” 获取对象的属性&a…...

【Linux】动态库和静态库

动态库和静态库 软链接硬链接硬链接要注意 自定义实现一个静态库(.a)解决、使用方法静态库的内部加载过程 自定义实现一个动态库&#xff08;.so&#xff09;动态库加载过程 静态库和动态库的特点 软链接 命令:ln -s 源文件名 目标文件名 软链接是独立连接文件的&#xff0c;他…...

R语言:联合多指标的ROC曲线

# 加载数据和包rm(list=ls())library(pROC)library(ggplot2)setwd("C:/Users/syy/Desktop/MRI_lab/")data<- read.csv("test1.csv", header = T)data$Groups...

将一个树形结构的数据平铺成一个一维数组(vue3)

一、需求描述 由于自带组件库没有具体完善,无法实现像element-ui这种可以多选选择任意一级的选项,也就是说,选择父级的时候不会联动选择子级的全部 例如: 所以,才会出现【二、案例场景】类似的场景,可以用来多选 ,并可以实现单选父级而不关联子级,选择了将树状数据进…...

OSCS开源安全周报第 56 期:Apache Airflow Spark Provider 任意文件读取漏洞

本周安全态势综述 OSCS 社区共收录安全漏洞 3 个&#xff0c;公开漏洞值得关注的是 Apache NiFi 连接 URL 验证绕过漏洞(CVE-2023-40037)、PowerJob 未授权访问漏洞(CVE-2023-36106)、Apache Airflow Spark Provider 任意文件读取漏洞(CVE-2023-40272)。 针对 NPM 、PyPI 仓库…...

CleanMyMac2024永久版Mac清理工具

Mac电脑作为相对封闭的一个系统&#xff0c;它会中毒吗&#xff1f;如果有一天Mac电脑产生了疑似中毒或者遭到恶意不知名攻击的现象&#xff0c;那又应该如何从容应对呢&#xff1f;这些问题都是小编使用Mac系统一段时间后产生的疑惑&#xff0c;通过一番搜索研究&#xff0c;小…...

软考高级系统架构设计师(一)计算机硬件

【原文链接】软考高级系统架构设计师&#xff08;一&#xff09;计算机硬件 1.1 计算机硬件组成 1.1.1 计算机的基本硬件组成 运算器控制器存储器输入设备输出设备 1.1.2 中央处理单元&#xff08;CPU&#xff09; 中央处理单元&#xff08;CPU&#xff09;的组成 运算器…...

bat文件中自定义cmd命令;执行完退出命令提示符窗口

1. bat中启动cmd命令 start cmd /k " cmd中命令行里自定义的命令 " 2.编写规则 start cmd /k "命令1 & 命令2 & 命令3" (无论前面命令是否成功, 后面都会执行start cmd /k "命令1 && 命令2 && 命令3 " (仅…...

深度学习的经典算法的论文、解读和代码实现

文章目录 CNN网络的经典算法LeNet-5AlexNetVGGInceptionInception-v1(GoogLeNet)BN-Inception ResNetR-CNNR-CNNFast R-CNNFaster R-CNN YOLOYOLO v1YOLO v2YOLO v3YOLO v4 RNN的经典算法RNNGRULSTMEncoder-DecoderAttentionTransformer CNN网络的经典算法 LeNet-5 来源论文&…...

开源TTS+gtx1080+cuda11.7+conda+python3.9吊打百度TTS

一、简介 开源项目&#xff0c;文本提示的生成音频模型 https://github.com/suno-ai/bark Bark是由Suno创建的基于变换器的文本到音频模型。Bark可以生成极为逼真的多语种演讲以及其他音频 - 包括音乐、背景噪音和简单的声音效果。该模型还可以产生非言语沟通&#xff0c;如…...

【私有GPT】CHATGLM-6B部署教程

【私有GPT】CHATGLM-6B部署教程 CHATGLM-6B是什么&#xff1f; ChatGLM-6B是清华大学知识工程和数据挖掘小组&#xff08;Knowledge Engineering Group (KEG) & Data Mining at Tsinghua University&#xff09;发布的一个开源的对话机器人。根据官方介绍&#xff0c;这是…...

基于“R语言+遥感“水环境综合评价方法教程

详情点击链接&#xff1a;基于"R语言遥感"水环境综合评价方法教程 一&#xff1a;R语言 1.1 R语言特点&#xff08;R语言&#xff09; 1.2 安装R&#xff08;R语言&#xff09; 1.3 安装RStudio&#xff08;R语言&#xff09; &#xff08;1&#xff09;下载地址…...

To_Heart—题解——P6234 [eJOI2019] T形覆盖

link. 突然很想写这篇题解。虽然题目不算难。 考场只有30分是为什么呢&#xff1f;看来是我没有完全理解这道题目吧&#xff01; 首先很明显的转换是&#xff0c;把 T 型覆盖看成十字形&#xff0c;再考虑最后减去某一块的贡献。 然后然后直接往原图上面放十字形!对于每一个…...

[软件工具]精灵标注助手目标检测数据集格式转VOC或者yolo

有时候我们拿到一个数据集发现是xml文件格式如下&#xff1a; <?xml version"1.0" ?> <doc><path>C:\Users\Administrator\Desktop\test\000000000074.jpg</path><outputs><object><item><name>dog</name>…...

Spring BeanName自动生成原理

先看代码演示 项目先定义一个User类 public class User {private String name;Overridepublic String toString() {return "User{" "name" name \ };}public String getName() {return name;}public void setName(String name) {this.name name;} }…...

论文阅读_图形图像_U-NET

name_en: U-Net: Convolutional Networks for Biomedical Image Segmentation name_ch: U-Net&#xff1a;用于生物医学图像分割的卷积网络 addr: http://link.springer.com/10.1007/978-3-319-24574-4_28 doi: 10.1007/978-3-319-24574-4_28 date_read: 2023-02-08 date_publi…...

基于热交换算法优化的BP神经网络(预测应用) - 附代码

基于热交换算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码 文章目录 基于热交换算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码1.数据介绍2.热交换优化BP神经网络2.1 BP神经网络参数设置2.2 热交换算法应用 4.测试结果&#xff1a;5.Matlab代…...

基于秃鹰算法优化的BP神经网络(预测应用) - 附代码

基于秃鹰算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码 文章目录 基于秃鹰算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码1.数据介绍2.秃鹰优化BP神经网络2.1 BP神经网络参数设置2.2 秃鹰算法应用 4.测试结果&#xff1a;5.Matlab代码 摘要…...

2.文章复现《热电联产系统在区域综合能源系统中的定容选址研究》(附matlab程序)

0.代码链接 1.简述 光热发电是大规模利用太阳能的新兴方式&#xff0c;其储热系 统能够调节光热电站的出力特性&#xff0c;进而缓解光热电站并网带来的火电机组调峰问题。合理配置光热电站储热容量&#xff0c;能够 有效降低火电机组调峰成本。该文提出一种光热电站储热容 量配…...

如何开启esxi主机的ssh远程连接

环境&#xff1a;esxi主机&#xff0c;说明&#xff1a;esxi主机默认ssh是不开启的&#xff0c;需要人工手动启动&#xff0c;也可以设置同esxi主机一起开机启动。 1、找到esxi主机&#xff0c;点击“配置”那里&#xff0c;再点击右边的属性&#xff0c;如图所示&#xff1a; …...

Android Studio实现解析HTML获取json,解析json图片URL,将URL存到list,进行瀑布流展示

目录 效果build.gradle&#xff08;app&#xff09;添加的依赖&#xff08;用不上的可以不加&#xff09;AndroidManifest.xml错误activity_main.xmlitem_image.xmlMainActivityImage适配器ImageModel 接收图片URL 效果 build.gradle&#xff08;app&#xff09;添加的依赖&…...

Centos7 交叉编译QT5.9.9源码 AArch64架构

环境准备 centos7 镜像 下载地址&#xff1a;http://mirrors.aliyun.com/centos/7.9.2009/isos/x86_64/ aarch64交叉编译链 下载地址&#xff1a;https://releases.linaro.org/components/toolchain/binaries/7.3-2018.05/aarch64-linux-gnu/ QT5.9.9源代码 下载地址&#xff1…...