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

0915,SOCKET网络编程部分,三种I/O多路复用模型(select ,poll,epoll)

目录   nc 127.0.0.1 port

01_socket_client.cc

01_socket_server.cc

02_select_client.cc

02_select_server.cc

03_poll_server.cc

04_epoll_server.cc

01_socket_client.cc

#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <error.h>
#include <error.h>#include <iostream>
#include <string>using std::cout;
using std::endl;
using std::string;int main(int argc,char** argv)
{//socket-->listenfdint listenfd=socket(AF_INET,SOCK_STREAM,0);if(listenfd<0){error(1,errno,"socket");}//sockaddr_in --> connectstruct sockaddr_in seraddr;memset(&seraddr,0,sizeof(seraddr));seraddr.sin_family=AF_INET;seraddr.sin_port=htons(atoi(argv[2]));//portseraddr.sin_addr.s_addr=inet_addr(argv[1]);//ipint ret=connect(listenfd,(struct sockaddr*)&seraddr,sizeof(seraddr));if(ret<0){error(1,errno,"connect");}//三次握手建立成功while(1){cout<<"propose send message to server"<<endl;string line;getline(std::cin,line);ret=send(listenfd,line.data(),line.size(),0);if(ret<0){cout<<"send error"<<endl;}else if(ret==0){cout<<"ret==0"<<endl;}else{cout<<"send sucessfully"<<endl;}char buff[128]={0};ret=recv(listenfd,buff,sizeof(buff),0);if(ret<0){cout<<"recv error"<<endl;}else if(ret==0){cout<<"ret==0"<<endl;}else{cout<<"recv sucessfully>>>"<<buff<<endl;}}close(listenfd);return 0;
}

01_socket_server.cc

#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <error.h>
#include <error.h>#include <iostream>
#include <string>using std::cout;
using std::endl;
using std::string;int main(int argc,char** argv)
{int listenfd=socket(AF_INET,SOCK_STREAM,0);if(listenfd<0){error(1,errno,"socket");}//port ip 复用int opt=1;int retval=setsockopt(listenfd,SOL_SOCKET,SO_REUSEPORT,&opt,sizeof(opt));if(retval<0){error(1,errno,"setscockopt");}int opt2=1;retval=setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt2,sizeof(opt2));if(retval<0){error(1,errno,"setscockopt2");}//bindstruct sockaddr_in seraddr;memset(&seraddr,0,sizeof(seraddr));seraddr.sin_addr.s_addr=inet_addr(argv[1]);seraddr.sin_port=htons(atoi(argv[2]));seraddr.sin_family=AF_INET;int ret=bind(listenfd,(struct sockaddr*)&seraddr,sizeof(seraddr));if(ret<0){error(1,errno,"bind");}//监听ret=listen(listenfd,128);if(ret<0){error(1,errno,"listen");}cout<<"server is listen"<<endl;//从listenfd队列中取下一个peerfdint connfd=accept(listenfd,nullptr,nullptr);if(connfd<0){error(1,errno,"accept");}//三次握手建立成功while(1){char buff[128]={0};ret=recv(connfd,buff,sizeof(buff),0);if(ret<0){cout<<"recv error"<<endl;}else if(ret==0){cout<<"ret==0"<<endl;}else{cout<<"recv sucessfully>>>"<<buff<<endl;}cout<<"propose send message to client"<<endl;string line;getline(std::cin,line);int ret1=send(connfd,line.data(),line.size(),0);if(ret1<0){cout<<"send error"<<endl;}else if(ret1==0){cout<<"ret1==0"<<endl;}else{cout<<"send sucessfully"<<endl;}}close(listenfd);close(connfd);return 0;
}

02_select_client.cc

#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <error.h>
#include <error.h>#include <iostream>
#include <string>#define SERV_IP "192.168.235.128"
#define SERV_PORT 8000using std::cout;
using std::endl;
using std::string;int main(int argc,char** argv)
{//socket-->listenfdint listenfd=socket(AF_INET,SOCK_STREAM,0);if(listenfd<0){error(1,errno,"socket");}//sockaddr_in --> connectstruct sockaddr_in seraddr;memset(&seraddr,0,sizeof(seraddr));seraddr.sin_family=AF_INET;seraddr.sin_port=htons(SERV_PORT);//port/* seraddr.sin_addr.s_addr=inet_addr(SERV_IP);//ip *//* inet_pton(listenfd, SERV_IP, &serv_addr.sin_addr.s_addr); */seraddr.sin_addr.s_addr=htonl(INADDR_ANY);//服务器绑定所有可用接口int ret=connect(listenfd,(struct sockaddr*)&seraddr,sizeof(seraddr));if(ret<0){error(1,errno,"connect");}//三次握手建立成功char buff[BUFSIZ];//标准io操作的缓冲区大小int nByte;while(1){fgets(buff,sizeof(buff),stdin);//helloc-->hello\n\0write(listenfd,buff,strlen(buff));//buff有效长度//buff的内容写入listenfd(套接字本质文件描述符)nByte=read(listenfd,buff,sizeof(buff));//读取服务器的响应,nByte实际读取的字节数write(STDOUT_FILENO,buff,nByte);//写到stdout}close(listenfd);return 0;
}

02_select_server.cc

#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <error.h>
#include <error.h>
#include <sys/select.h>
#include <sys/time.h>#include <iostream>
#include <string>#define SERV_PORT 8000using std::cout;
using std::endl;
using std::string;int main(int argc,char** argv)
{int cnt ;//debugint connfd,sockfd;int listenfd=socket(AF_INET,SOCK_STREAM,0);if(listenfd<0){error(1,errno,"socket");}//port ip 复用int opt=1;int retval=setsockopt(listenfd,SOL_SOCKET,SO_REUSEPORT,&opt,sizeof(opt));if(retval<0){error(1,errno,"setscockopt");}int opt2=1;retval=setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt2,sizeof(opt2));if(retval<0){error(1,errno,"setscockopt2");}//bindstruct sockaddr_in seraddr;bzero(&seraddr,sizeof(seraddr));/* memset(&seraddr,0,sizeof(seraddr)); */seraddr.sin_addr.s_addr=htonl(INADDR_ANY);seraddr.sin_port=htons(SERV_PORT);seraddr.sin_family=AF_INET;int ret=bind(listenfd,(struct sockaddr*)&seraddr,sizeof(seraddr));if(ret<0){error(1,errno,"bind");}//监听ret=listen(listenfd,128);if(ret<0){error(1,errno,"listen");}cout<<"server is listen"<<endl;//三次握手建立成功char buff[BUFSIZ],str[BUFSIZ];int maxfd=listenfd;int maxi=-1;fd_set rset,allset;int client[FD_SETSIZE];//多1024,可以监视的最大文件描述符数量//定义在/usr/include/linux/posix_types.hfor(int i=0;i<FD_SETSIZE;++i){client[i]=-1;}FD_ZERO(&allset);FD_SET(listenfd,&allset);while(1){rset=allset;int nready=select(maxfd+1,&rset,NULL,NULL,NULL);//nready就绪的描述符数量if(nready<0){error(1,errno,"select");}//01,监听到listenfd 新的链接进来if(FD_ISSET(listenfd,&rset)){struct sockaddr_in clie_addr;socklen_t clie_addr_len=sizeof(clie_addr);//新连接的套接字connfd=accept(listenfd,(struct sockaddr*)&clie_addr,&clie_addr_len);if(connfd==-1){error(1,errno,"accept");}printf("receive from %s : %d\n",inet_ntop(AF_FILE,&clie_addr.sin_addr,str,sizeof(str)),ntohs(clie_addr.sin_port));//三次握手成功int i;for(i=0;i<FD_SETSIZE;++i){if(client[i]<0){client[i]=connfd;break;//加入监听数组} }//==============================cout<<cnt++<<"  "<<i<<endl;if(i==FD_SETSIZE){fputs("too much client\n",stderr);exit(1);}FD_SET(connfd,&allset);//添加新连接//更新maxi,maxfdif(connfd>maxfd){maxfd=connfd;}if(i>maxi){maxi=i;}//如果nready=1.继续while循环,不用走下面的for循环if(--nready==0){continue;}}//02遍历client数组,元素为正,被监听到//是老连接,可以进行数据发送接受for(int i=0;i<=maxi;++i){//caution:i<=maxiif((sockfd=client[i])<0){continue;}
//==============================cout<<cnt++<<"  "<<sockfd<<endl;if(FD_ISSET(sockfd,&rset)){int nByte=read(sockfd,buff,sizeof(buff));if(nByte==0){//数据读完了,(缓冲区没有数据//连接要断开了close(sockfd);cout<<"client "<<sockfd<<" closed connection\n"<<endl;FD_CLR(sockfd,&allset);client[i]=-1;}else if(nByte>0){for(int j=0;j<nByte;++j){buff[j]=toupper(buff[j]);//a->A}write(sockfd,buff,nByte);write(STDOUT_FILENO,buff,nByte);}if(--nready==0){break;}}}}close(listenfd);close(connfd);return 0;
}

03_poll_server.cc

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <error.h>
#include <errno.h>
#include <poll.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/socket.h>#include <iostream>
#include <string>#define OPEN_MAX 1024
/* #define SERV_IP "192.168.235.128" */
#define SERV_IP "127.0.0.1"
#define SERV_PORT 7888using std::cout;
using std::endl;
using std::string;/* struct pollfd */
/* { */
/*     int   fd;       //要监听的文件描述符 */
/*     short events;   //待监听的文件描述符的事件 POLLIN/POLLOUT/POLLERR */
/*     short revents;  //revents & POLLIN */
/* }; */int main(int argc,char** argv)
{int cnt ;//debugint connfd,sockfd;int listenfd=socket(AF_INET,SOCK_STREAM,0);if(listenfd<0){error(1,errno,"socket");}//port ip 复用int opt=1;int retval=setsockopt(listenfd,SOL_SOCKET,SO_REUSEPORT,&opt,sizeof(opt));if(retval<0){error(1,errno,"setscockopt");}int opt2=1;retval=setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt2,sizeof(opt2));if(retval<0){error(1,errno,"setscockopt2");}//bindstruct sockaddr_in seraddr;bzero(&seraddr,sizeof(seraddr));/* memset(&seraddr,0,sizeof(seraddr)); */seraddr.sin_addr.s_addr=htonl(INADDR_ANY);/* seraddr.sin_addr.s_addr=inet_pton( *//*        listenfd, SERV_IP, &seraddr.sin_addr.s_addr); */seraddr.sin_port=htons(SERV_PORT);seraddr.sin_family=AF_INET;int ret=bind(listenfd,(struct sockaddr*)&seraddr,sizeof(seraddr));if(ret<0){error(1,errno,"bind");}//监听ret=listen(listenfd,128);if(ret<0){error(1,errno,"listen");}cout<<"server is listen"<<endl;//三次握手建立成功char buff[BUFSIZ],str[INET_ADDRSTRLEN];//IPV4地址的字符串表示形式的最大长度int maxi=0;struct pollfd client[OPEN_MAX];//FOPEN_MAX:一个程序可以同时打开的最大文件流数量//poll类型,listenfd加入监听client[0].fd=listenfd;client[0].events=POLLIN;for(int i=1;i<OPEN_MAX;++i){//i=0,会把listenfd删掉,注意初始化顺序client[i].fd=-1;}while(1){int nready=poll(client,maxi+1,-1);if(nready<0){error(1,errno,"select");}
//==============================cout<<cnt++<<"  "<<client[0].fd<<endl;//01,监听到listenfd 新的链接进来if(client[0].revents & POLLIN){struct sockaddr_in clie_addr;socklen_t clie_addr_len=sizeof(clie_addr);//新连接的套接字connfd=accept(listenfd,(struct sockaddr*)&clie_addr,&clie_addr_len);if(connfd==-1){error(1,errno,"accept");}printf("receive from %s : %d\n",inet_ntop(AF_FILE,&clie_addr.sin_addr,str,sizeof(str)),ntohs(clie_addr.sin_port));//三次握手成功int i;for(i=1;i<OPEN_MAX;++i){if(client[i].fd<0){client[i].fd=connfd;break;//加入监听数组} }client[i].events=POLLIN;//设置要监听的类型if(i==OPEN_MAX){fputs("too much client\n",stderr);exit(1);}//更新maxi,fd有新增if(i>maxi){maxi=i;}//如果nready=1.继续while循环,不用走下面的for循环if(--nready==0){continue;}}//02遍历client数组,元素为正,被监听到//是老连接,可以进行数据发送接受for(int i=0;i<=maxi;++i){//caution:i<=maxiif((sockfd=client[i].fd)<0){continue;}//老连接上有数据if(client[i].revents & POLLIN){int nByte=read(sockfd,buff,sizeof(buff));if(nByte<0){if(errno==ECONNRESET){//客户端被强制关闭cout<<"client ["<<i<<"] abort connect"<<endl;close(sockfd);client[i].fd=-1;}else{perror("read nByte=0 error");}}else if(nByte>0){for(int j=0;j<nByte;++j){buff[j]=toupper(buff[j]);//a->A}write(sockfd,buff,nByte);write(STDOUT_FILENO,buff,nByte);}else{close(sockfd);cout<<"client ["<<i<<"] closed connection"<<endl;client[i].fd=-1;}if(--nready==0){break;}}}}close(listenfd);close(connfd);return 0;
}

04_epoll_server.cc

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <error.h>
#include <errno.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/epoll.h>#include <iostream>
#include <string>#define OPEN_MAX 1024
/* #define SERV_IP "192.168.235.128" */
#define SERV_IP "127.0.0.1"
#define SERV_PORT 6888using std::cout;
using std::endl;
using std::string;/* typedef union epoll_data { */
/*     void        *ptr; */
/*     int          fd; */
/*     uint32_t     u32; */
/*     uint64_t     u64; */
/* } epoll_data_t; *//* struct epoll_event { */
/*     uint32_t     events; //EPOLLIN/EPOLLOUT/EPOLLERR */
/*     epoll_data_t data;        /1* User data variable *1/ */
/* }; */int main(int argc,char** argv)
{int cnt ;//debugint connfd,sockfd;int listenfd=socket(AF_INET,SOCK_STREAM,0);if(listenfd<0){error(1,errno,"socket");}//port ip 复用int opt=1;int retval=setsockopt(listenfd,SOL_SOCKET,SO_REUSEPORT,&opt,sizeof(opt));if(retval<0){error(1,errno,"setscockopt");}int opt2=1;retval=setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt2,sizeof(opt2));if(retval<0){error(1,errno,"setscockopt2");}//bindstruct sockaddr_in seraddr;bzero(&seraddr,sizeof(seraddr));seraddr.sin_addr.s_addr=htonl(INADDR_ANY);/* seraddr.sin_addr.s_addr=inet_pton( *//*        listenfd, SERV_IP, &seraddr.sin_addr.s_addr); */seraddr.sin_port=htons(SERV_PORT);seraddr.sin_family=AF_INET;int ret=bind(listenfd,(struct sockaddr*)&seraddr,sizeof(seraddr));if(ret<0){error(1,errno,"bind");}//监听ret=listen(listenfd,128);if(ret<0){error(1,errno,"listen");}cout<<"server is listen"<<endl;char buff[BUFSIZ],str[INET_ADDRSTRLEN];//IPV4地址的字符串表示形式的最大长度//创建红黑树的根节点(红黑树+就绪链表)int epfd=epoll_create(OPEN_MAX);/* int epfd=epoll_create1(1); */if(epfd==-1){error(1,errno,"epoll_create1");}//赋值evt,listenfd加入监听struct epoll_event evt,ep[OPEN_MAX];evt.events=EPOLLIN;evt.data.fd=listenfd;ret=epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&evt);if(ret<0){error(1,errno,"epoll_ctl(add) listenfd");}while(1){int nready=epoll_wait(epfd,ep,OPEN_MAX,-1);if(nready<0){error(1,errno,"select");}
//==============================
cout<<cnt++<<"  "<<ep[0].data.fd<<endl;
//递增的ep[0].data.fd,记录的是接收到的事件的数量
//这个上下文中是用来输出当前处理的事件的文件描述符,
//可能会是新连接的文件描述符,所以会看起来是递增的                    //02遍历nreadyfor(int i=0;i<nready;++i){//异常处理if(!(ep[i].events & EPOLLIN)){continue;}//监听到listenfd,新连接//(监听到连接事件)if(ep[i].data.fd == listenfd){struct sockaddr_in clie_addr;socklen_t clie_addr_len=sizeof(clie_addr);//新连接的套接字connfd=accept(listenfd,(struct sockaddr*)&clie_addr,&clie_addr_len);if(connfd==-1){error(1,errno,"accept");}printf("receive from %s : %d\n",inet_ntop(AF_FILE,&clie_addr.sin_addr,str,sizeof(str)),ntohs(clie_addr.sin_port));//三次握手成功//新连接加入监听evt.events=EPOLLIN;evt.data.fd=connfd;ret=epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&evt);if(ret<0){error(1,errno,"epoll_ctl(add) connfd");}}//不是连接事件--> 读写事件-->有消息else {sockfd=ep[i].data.fd;int nByte=read(sockfd,buff,sizeof(buff));//缓冲区空,即将断开if(nByte==0){ret=epoll_ctl(epfd,EPOLL_CTL_DEL,sockfd,NULL);if(ret<0){error(1,errno,"epoll_ctl(delete)");}close(sockfd);cout<<"client ["<<sockfd<<"] closed connecttion"<<endl;}//连接异常else if(nByte<0){perror("epoll_wait error");ret=epoll_ctl(epfd,EPOLL_CTL_DEL,sockfd,NULL);if(ret<0){error(1,errno,"epoll_ctl(delete)");}close(sockfd);}//正常通信else{for(int j=0;j<nByte;++j){buff[j]=toupper(buff[j]);//a->A}write(sockfd,buff,nByte);write(STDOUT_FILENO,buff,nByte);}}}}close(listenfd);close(connfd);return 0;
}

相关文章:

0915,SOCKET网络编程部分,三种I/O多路复用模型(select ,poll,epoll)

目录 nc 127.0.0.1 port 01_socket_client.cc 01_socket_server.cc 02_select_client.cc 02_select_server.cc 03_poll_server.cc 04_epoll_server.cc 01_socket_client.cc #include <stdlib.h> #include <string.h> #include <sys/stat.h> #inclu…...

HarmonyOS 应用获取公钥和 MD5 指纹签名信息

鸿蒙版本获取 MD5 指纹和公钥可参考如下方式; 首先,通过 AGC 官网 将所需证书下载至本地; 其次,通过记事本或者文本编译器的方式将其正式打开,将其内容中前两项 BEGIN CERTIFICATE 和 END CERTIFICATE 的段落删除,仅保留最后一段中的内容(包括 BEGIN CERTIFICATE 和 END CERTI…...

封装一个录音声音振动效果的组件

目标&#xff1a;根据声音的大小实现声音振动特效 实现步骤&#xff1a; 通过 getAudioCapturerMaxAmplitude 观察音频区间封装振动组件&#xff0c;通过声音振幅数据实现振动效果 落地代码&#xff1a; 1&#xff09;获取振幅数据&#xff0c;出入振动组件 AudioPage.ets …...

Java、JS与Go的扩展操作符,揭秘它们的‘魔法’!

在这个快节奏的互联网时代&#xff0c;程序员们总是希望能够用更简洁、更高效的方式来编写代码。扩展操作符&#xff08;Spread Operator&#xff09;是 JavaScript ES6 引入的重要特性&#xff0c;而 Java 和 Go 也有各自的方式来实现类似的功能。今天&#xff0c;我们就来深入…...

ROS学习笔记13——rosbag功能包的简单使用

rosbag是用于录制和回放 ROS 主题的一个工具集&#xff0c;实现了数据的复用&#xff0c;方便调试和测试。rosbag本质也是ros的节点&#xff0c;当录制时&#xff0c;rosbag是一个订阅节点&#xff0c;可以订阅话题消息并将订阅到的数据写入磁盘文件&#xff1b;当重放时&#…...

Python Flask网页开发基本框架

注&#xff1a;Flask详细学习请见Flask学习合集。 直接上代码: app.py from flask import Flaskapp Flask(__name__)app.route("/") def hello():return "Hello, World!"if __name__ "__init__":app.run(host "127.0.0.1", port…...

Mybatis-plus进阶篇(五)

文章目录 条件构造器补充知识TypeHandlerWrappers示例&#xff1a; 线程安全性示例&#xff1a; 使用 Wrapper 自定义 SQL示例&#xff1a;使用方法 使用注解查询使用XML配置查询链式调用与Lambda式调用 条件构造器补充知识 TypeHandler 在 wrapper 中使用 typeHandler 需要特…...

交通标志识别系统Python+卷积神经网络算法+深度学习人工智能+TensorFlow模型训练+计算机课设项目+Django网页界面

一、介绍 交通标志识别系统。本系统使用Python作为主要编程语言&#xff0c;在交通标志图像识别功能实现中&#xff0c;基于TensorFlow搭建卷积神经网络算法模型&#xff0c;通过对收集到的58种常见的交通标志图像作为数据集&#xff0c;进行迭代训练最后得到一个识别精度较高…...

【QT】定时器使用

文章目录 关于 Qt 定时器使用的注意细节总结实例-检查工具使用周期时间是否合理UI设计头文件 remind.h源文件 remind.cpp实现效果 关于 Qt 定时器使用的注意细节总结 一、创建与初始化 使用 QTimer 类来创建定时器。可以在构造函数中指定父对象&#xff0c;确保定时器在正确的…...

虚拟机:3、(待更)WSL2安装Ubuntu系统+实现GPU直通

WSL2实现linux子系统GPU直通 安装WSL2和Ubuntu 见https://blog.csdn.net/bule_shake/article/details/135992375 问题&#xff1a;wsl --update进度卡住 如果命令wsl --update进度一直为0&#xff0c;可以先运行wsl --shutdown&#xff0c;然后再次升级。 微软商店打不开、…...

CSP-J2024年全真模拟题 阅读程序篇2

因为明天考试&#xff0c;这回给大家准备了超详细的解析~ 22.程序中 n 和 m 只有输入正整数&#xff0c;程序的输出值才可能是 YES A.对B.错 23.程序中用到了递归函数 bool fun&#xff08;int n&#xff09; A.对B.错 24.若输入 n 和 m 都是素数&#xff0c;程序的输出值…...

几种手段mfc140u.dll丢失的解决方法,了解mfc140u.dll

在使用Windows操作系统时&#xff0c;许多用户可能会遇到“找不到mfc140u.dll”或“mfc140u.dll未找到”的错误提示。这个错误通常是由于该文件丢失或损坏所致。本文将详细介绍mfc140u.dll文件的作用、丢失的原因及其解决方法&#xff0c;帮助您快速恢复系统的正常运行。 一、m…...

Scrapy爬虫框架 Spider Middleware 爬虫页中间件

在当今的互联网时代,数据的收集和分析变得越来越重要,爬虫技术作为数据获取的重要手段,受到广泛关注。Scrapy 是一个广受欢迎的 Python 爬虫框架,它以其高效、灵活和易于扩展的特点,成为了开发者的首选工具之一。Scrapy 框架中的中间件(Spider Middlewares)是扩展和定制…...

localectl 命令:系统语言、键盘布局和区域设置

一、命令简介 ​localectl​ 是 Linux 系统中用于查询和配置系统语言、键盘布局和区域设置的命令。它属于 systemd​ 系统和服务管理器的一部分&#xff0c;允许用户通过简单的命令行接口更改与本地化相关的配置。 ‍ 相关命令&#xff1a; 如果是时间相关的设置&#xff0…...

《微信小程序实战(3) · 推广海报制作》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…...

SS-MUSIC

SS-MUSIC 相干信号源带来的缺秩问题什么是中心对称阵列什么是前后向平均技术什么是 SS-MUSIC 算法SS-MUSIC 能解相干的原因SS-MUSIC 改进算法总结参考文献 本文讨论针对一维均匀线阵&#xff08;ULA&#xff0c;Uniform Linear Array&#xff09;的空间平滑 MUSIC&#xff08;S…...

Spring Cloud Gateway组件

Spring Cloud Gateway是Spring Cloud生态系统中的一个关键组件&#xff0c;它基于Spring Framework 5、Spring Boot 2和Project Reactor等技 术构建&#xff0c;为微服务架构提供了强大且灵活的网关服务。以下是对Spring Cloud Gateway的详细介绍&#xff1a;一、概述 Spring …...

激发AI创造力:掌握Prompt提示词的高效提问方法

AI内容创作的核心&#xff1a;提示词Prompt 在AI内容创作中&#xff0c;提示词&#xff08;Prompt&#xff09;是关键因素&#xff0c;能有效引导AI生成高质量、符合预期的内容。通过合理组织提示词&#xff0c;创作者可以大幅提升AI输出的准确性和专业度。掌握提示词的编写技…...

江科大笔记—STM32课程简介

课程简介...

使用 nvm 管理 node 版本:如何在 macOS 和 Windows 上安装使用nvm

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 一、引言二、nvm的安装与基本使用2.1 macOS安装nvm2.1.1 使用 curl 安装2.1.2 使用 Homebrew 安装 2.2 Windows安装nvm2.2.1 下载 nvm-windows2.2.2 安装 nvm-windows 2.3 安装node2.4 切换node版本 三、常见问题及解决方案…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

基础测试工具使用经验

背景 vtune&#xff0c;perf, nsight system等基础测试工具&#xff0c;都是用过的&#xff0c;但是没有记录&#xff0c;都逐渐忘了。所以写这篇博客总结记录一下&#xff0c;只要以后发现新的用法&#xff0c;就记得来编辑补充一下 perf 比较基础的用法&#xff1a; 先改这…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...

Redis:现代应用开发的高效内存数据存储利器

一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发&#xff0c;其初衷是为了满足他自己的一个项目需求&#xff0c;即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源&#xff0c;Redis凭借其简单易用、…...

MySQL 8.0 事务全面讲解

以下是一个结合两次回答的 MySQL 8.0 事务全面讲解&#xff0c;涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容&#xff0c;并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念&#xff08;ACID&#xff09; 事务是…...