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

day37:网编day4,多点通信和并发服务器

一、广播接收方:

#include <myhead.h>#define ERR_MSG(msg) do{\
fprintf(stderr,"__%d__\n",__LINE__);\
perror(msg);\
}while(0)#define BRD_IP "192.168.114.255"
#define BRD_PORT 8888int main(int argc, const char *argv[])
{//创建报式套接字int sfd = -1;if((sfd = socket(AF_INET,SOCK_DGRAM,0)) < 0){ERR_MSG("socket");}printf("socket success sfd=%d\n",sfd);//填充地址信息结构体给bind用struct sockaddr_in sin;sin.sin_family = AF_INET; 	//必须填AF_INETsin.sin_port = htons(BRD_PORT); 	//广播端口号sin.sin_addr.s_addr = inet_addr(BRD_IP); 	//广播IP//bind绑定地址信息if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin)) < 0){ERR_MSG("bind");return -1;}printf("bind success[%s:%d]\n",BRD_IP,BRD_PORT);socklen_t addrlen = sizeof(sin);char buf[128]="";ssize_t len;while(1){if((len = recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&addrlen)) < 0){ERR_MSG("recvfrom");return -1;}printf("recvfrom success %s\n",buf);}close(sfd);return 0;
}

二、广播发送方:

#include <myhead.h>#define ERR_MSG(msg) do{\
fprintf(stderr,"__%d__\n",__LINE__);\
perror(msg);\
}while(0)#define BRD_IP "192.168.114.255"
#define BRD_PORT 8888int main(int argc, const char *argv[])
{//创建报式套接字int cfd = -1;if((cfd = socket(AF_INET,SOCK_DGRAM,0)) < 0){ERR_MSG("socket");}printf("socket success cfd=%d\n",cfd);int broad = 1;if(setsockopt(cfd,SOL_SOCKET,SO_BROADCAST,(int*)&broad,sizeof(broad)) < 0){ERR_MSG("setsockpot");return-1;}printf("setsockpot success\n");//非必须绑定//填充地址信息结构体给sendtostruct sockaddr_in sin;sin.sin_family = AF_INET; 	//必须填AF_INETsin.sin_port = htons(BRD_PORT); 	//广播端口号sin.sin_addr.s_addr = inet_addr(BRD_IP); 	//广播IPprintf("bind success[%s:%d]\n",BRD_IP,BRD_PORT);char buf[128]="";ssize_t len;while(1){//清空bufbzero(buf,sizeof(buf));//从终端输入数据保存到buf中fscanf(stdin,"%s",buf);while(getchar()!=10);if(sendto(cfd,buf,strlen(buf),0,(struct sockaddr*)&sin,sizeof(sin)) < 0){ERR_MSG("sendto");return -1;}printf("sendto success\n");}close(cfd);return 0;
}

三、组播接收方:

#include <myhead.h>#define ERR_MSG(msg) do{\
fprintf(stderr,"__%d__\n",__LINE__);\
perror(msg);\
}while(0)#define GRP_IP "224.1.2.3" 	//组播IP
#define IP "192.168.114.94" //本机IP
#define GRP_PORT 8888int main(int argc, const char *argv[])
{//创建报式套接字int sfd = -1;if((sfd = socket(AF_INET,SOCK_DGRAM,0)) < 0){ERR_MSG("socket");}printf("socket success sfd=%d\n",sfd);//填充结构体,来完成组播连接struct ip_mreqn grp;grp.imr_multiaddr.s_addr = inet_addr(GRP_IP); //组播IPgrp.imr_address.s_addr = inet_addr(IP); //本机IPgrp.imr_ifindex = 0; //自动//设置连接组播if(setsockopt(sfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&grp,sizeof(grp)) < 0){ERR_MSG("setsockopt");return -1;}printf("setsockopt success\n");//填充地址信息结构体给bind用struct sockaddr_in sin;sin.sin_family = AF_INET; 	//必须填AF_INETsin.sin_port = htons(GRP_PORT); 	//组播端口号sin.sin_addr.s_addr = inet_addr(GRP_IP); 	//组播IP//bind绑定地址信息if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin)) < 0){ERR_MSG("bind");return -1;}printf("bind success[%s:%d]\n",GRP_IP,GRP_PORT);socklen_t addrlen = sizeof(sin);char buf[128]="";ssize_t len;while(1){if((len = recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&addrlen)) < 0){ERR_MSG("recvfrom");return -1;}printf("recvfrom success %s\n",buf);}close(sfd);return 0;
}

四、组播发送方:

#include <myhead.h>#define ERR_MSG(msg) do{\
fprintf(stderr,"__%d__\n",__LINE__);\
perror(msg);\
}while(0)#define BRD_IP "224.1.2.3"
#define BRD_PORT 8888int main(int argc, const char *argv[])
{//创建报式套接字int cfd = -1;if((cfd = socket(AF_INET,SOCK_DGRAM,0)) < 0){ERR_MSG("socket");}printf("socket success cfd=%d\n",cfd);int broad = 1;if(setsockopt(cfd,SOL_SOCKET,SO_BROADCAST,(int*)&broad,sizeof(broad)) < 0){ERR_MSG("setsockpot");return-1;}printf("setsockpot success\n");//非必须绑定//填充地址信息结构体给sendtostruct sockaddr_in sin;sin.sin_family = AF_INET; 	//必须填AF_INETsin.sin_port = htons(BRD_PORT); 	//广播端口号sin.sin_addr.s_addr = inet_addr(BRD_IP); 	//广播IPprintf("bind success[%s:%d]\n",BRD_IP,BRD_PORT);char buf[128]="";ssize_t len;while(1){//清空bufbzero(buf,sizeof(buf));//从终端输入数据保存到buf中fscanf(stdin,"%s",buf);while(getchar()!=10);if(sendto(cfd,buf,strlen(buf),0,(struct sockaddr*)&sin,sizeof(sin)) < 0){ERR_MSG("sendto");return -1;}printf("sendto success\n");}close(cfd);return 0;
}

五、TCP多线程并发服务器:

#include <myhead.h>#define ERR_MSG(msg) do{\fprintf(stderr,"__%d__\n",__LINE__);\perror(msg);\
}while(0)#define IP "192.168.114.94"
#define PORT 8888int del_cli_msg(int newfd,struct sockaddr_in cin);
void handler(int num)
{if(num == SIGCHLD){while(waitpid(-1,NULL,WNOHANG) > 0);}
}
int main(int argc, const char *argv[])
{if(signal(SIGCHLD,handler) == SIG_ERR){ERR_MSG("signal");return -1;}printf("signal success\n");//创建流式套接字int sfd = -1;if((sfd = socket(AF_INET,SOCK_STREAM,0)) < 0){ERR_MSG("socket");return -1;}printf("socket success sfd = %d\n",sfd);//允许端口快速的被复用int reuse = 1;                                                            if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0){ERR_MSG("setsockopt");return -1;}printf("允许端口快速的被复用成功\n");	//填充地址信息结构体给bind使用struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(PORT); 	//服务器端口号sin.sin_addr.s_addr = inet_addr(IP); 	//服务器IP//bind必须绑定IP和端口号if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin)) < 0){ERR_MSG("bind");return -1;}printf("bind success [%s:%d]\n",IP,PORT);//listen把sfd切换成监听模式if(listen(sfd,128) < 0){ERR_MSG("listen");return -1;}printf("listen success sfd = %d\n",sfd);struct sockaddr_in cin;socklen_t addrlen=sizeof(cin);int newfd =-1;pid_t pid;while(1){//accept接收客户端发送过来的地址信息,创建一个newfd与其通讯accept//父进程专门负责连接if((newfd = accept(sfd,(struct sockaddr*)&cin,&addrlen)) < 0){ERR_MSG("accept");return -1;}printf("[%s:%d]客户端连接成功 newfd = %d\n",\inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),newfd);pid = fork();if(0 == pid){close(sfd);//子进程专门负责交互del_cli_msg(newfd,sin);exit(0);}close(newfd);}close(sfd);return 0;
}
int del_cli_msg(int newfd,struct sockaddr_in cin)
{char buf[128] ="";ssize_t len = 0;while(1){bzero(buf,sizeof(buf));len = recv(newfd,buf,sizeof(buf),0);if(len< 0){ERR_MSG("recvfrom");return -1;}else if(len == 0){printf("[%s:%d]客户端已下线 newfd = %d\n",\inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),newfd);break;}printf("recv success [%s:%d],newfd=%d buf=%s\n",\inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),newfd,buf);/*bzero(buf,sizeof(buf));printf("请输入数据发送给客户端");fscanf(stdin,"%s",buf);while(getchar()!=10);*/strcat(buf,">-<");if(send(newfd,buf,strlen(buf),0) < 0){ERR_MSG("send");return -1;}printf("send success buf = %s\n",buf);}
}

六、TCP多线程并发服务器:

#include <myhead.h>#define ERR_MSG(msg) do{\fprintf(stderr,"__%d__\n",__LINE__);\perror(msg);\
}while(0)#define IP "192.168.114.94"
#define PORT 8888
struct Data
{int newfd;struct sockaddr_in cin;
};
void *del_cli_msg(void *arg);
int main(int argc, const char *argv[])
{printf("signal success\n");//创建流式套接字int sfd = -1;if((sfd = socket(AF_INET,SOCK_STREAM,0)) < 0){ERR_MSG("socket");return -1;}printf("socket success sfd = %d\n",sfd);//允许端口快速的被复用int reuse = 1;                                                            if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0){ERR_MSG("setsockopt");return -1;}printf("允许端口快速的被复用成功\n");	//填充地址信息结构体给bind使用struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(PORT); 	//服务器端口号sin.sin_addr.s_addr = inet_addr(IP); 	//服务器IP//bind必须绑定IP和端口号if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin)) < 0){ERR_MSG("bind");return -1;}printf("bind success [%s:%d]\n",IP,PORT);//listen把sfd切换成监听模式if(listen(sfd,128) < 0){ERR_MSG("listen");return -1;}printf("listen success sfd = %d\n",sfd);struct sockaddr_in cin;socklen_t addrlen=sizeof(cin);int newfd =-1;pthread_t tid;while(1){//accept接收客户端发送过来的地址信息,创建一个newfd与其通讯accept//父进程专门负责连接if((newfd = accept(sfd,(struct sockaddr*)&cin,&addrlen)) < 0){ERR_MSG("accept");return -1;}printf("[%s:%d]客户端连接成功 newfd = %d\n",\inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),newfd);struct Data data;data.newfd = newfd;data.cin = cin;if(pthread_create(&tid,NULL,del_cli_msg,&data)){printf("pthread_create error\n");return -1;}printf("create success\n");pthread_detach(tid);}close(sfd);return 0;
}
void *del_cli_msg(void *arg)
{int newfd = ((struct Data*)arg)->newfd;struct sockaddr_in cin = ((struct Data*)arg)->cin;char buf[128] ="";ssize_t len = 0;while(1){bzero(buf,sizeof(buf));len = recv(newfd,buf,sizeof(buf),0);if(len< 0){ERR_MSG("recvfrom");break;}else if(len == 0){printf("[%s:%d]客户端已下线 newfd = %d\n",\inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),newfd);break;}printf("recv success [%s:%d],newfd=%d buf=%s\n",\inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),newfd,buf);/*bzero(buf,sizeof(buf));printf("请输入数据发送给客户端");fscanf(stdin,"%s",buf);while(getchar()!=10);*/strcat(buf,">-<");if(send(newfd,buf,strlen(buf),0) < 0){ERR_MSG("send");break;}//printf("send success buf = %s\n",buf);}
}

七、多线程并发服务器为什么不能将newfd定义成全局?

不能,因为如果newfd设成全局变量,而多线程之间共享0-3G用户空间,临界资源,所以会导致newfd变化后,原先线程进行交互。

八、基于UDP的TFTP文件传输,完成下载和上传功能,制作的是客户端,与tftp服务器进行交互

#include <myhead.h>#define ERR(s) do\
{\fprintf(stderr,"__%d__",__LINE__);\perror(s);\
}while(0)
#define PORT 69
#define IP "192.168.114.103"int do_download(int cfd,struct sockaddr_in sin);
int do_upload(int cfd,struct sockaddr_in sin);
int main(int argc, const char *argv[])
{//创建报式套接字socketint cfd;if((cfd = socket(AF_INET,SOCK_DGRAM,0)) < 0){ERR("socket");return -1;}printf("socket success\n");struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(PORT);sin.sin_addr.s_addr = inet_addr(IP);char choose = 0;while(1){system("clear");printf("--------------------------------\n");printf("-------------1下载--------------\n");printf("-------------2上传--------------\n");printf("-------------3退出--------------\n");printf("--------------------------------\n");printf("请输入>>>");scanf("%c",&choose);while(getchar()!=10); 	//吸收垃圾字符switch(choose){case '1':do_download(cfd,sin);break;case '2':do_upload(cfd,sin);break;case '3':goto END;break;default :printf("输入错误,请重新输入\n");}printf("请输入任意字符清屏\n");while(getchar()!=10);}
END://关闭套接字close(cfd);return 0;
}int do_download(int cfd,struct sockaddr_in sin)
{/*//组下载请求包char buf[516] = "";char f_n[20] = "";//操作码unsigned short *ptr1 = (unsigned short*)buf;*ptr1 = htons(1); 	//组操作码//文件名char *ptr2 = (char *)(ptr1+1);strcpy(ptr2,f_n);//模式char *ptr3 = ptr2 + strlen(f_n) + 1;strcpy(ptr3,"octet");int size = 2+strlen(ptr2)+1+strlen(ptr3)+1;*/char buf[516] = "";char f_n[20] = "";int num=1;printf("请输入文件名>>> ");//终端输入要下载的文件名fgets(f_n,sizeof(f_n),stdin);f_n[strlen(f_n)-1] = '\0';int fd;if((fd = open(f_n,O_RDONLY|O_CREAT|O_TRUNC,0664)) == -1){ERR("open");return -1;}//用sprintf拼接int size = sprintf(buf,"%c%c%s%c%s%c",0,1,f_n,0,"octet",0);//发送下载请求sendtoif(sendto(cfd,buf,size,0,(struct sockaddr*)&sin,sizeof(sin)) < 0 ){ERR("sendto askpackage");return -1;}printf("sendto askpackage success\n");ssize_t len = -1;struct sockaddr_in addrin;socklen_t addrlen=sizeof(addrin);while(1){//清空bufbzero(buf,sizeof(buf));//接收数据recvfrom,接收地址信息if((len = recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&addrin,&addrlen)) < 0){ERR("recvfrom datapackage");return -1;}unsigned short ptr2=ntohs(*(unsigned short*)(buf+2));printf("%hu\n",ptr2);	//当操作码为5时if(5 == buf[1]){fprintf(stderr, "错误码:%d,错误信息:%s\n", ntohs(*(unsigned short*)(buf+2)), buf+4);			break;}//当操作码为3,并且块编号正确时else if(3 == buf[1] && num == ptr2){printf("%d\n",fd);//跳过前四个字节,写入文件if(write(fd,buf+4,len-4)<0){ERR("write");return -1;}//组ACK包buf[1] = 4;	//发送ACK包,sendtoif(sendto(cfd,buf,4,0,(struct sockaddr*)&addrin,addrlen) < 0){ERR("sendto ACKpackage");return -1;}num++;//判断数据是否小于512个字节,若小于则下载完成if(len < 516){printf("download success\n");break;}}}close(fd);return 0;
}int do_upload(int cfd,struct sockaddr_in sin)
{char f_n[20]="";printf("请输入传输文件名>>>");fscanf(stdin,"%s",f_n);while(getchar()!=10);//打开文件int srcfd = -1;if((srcfd = open(f_n,O_RDONLY)) < 0){if(errno == ENOENT){printf("文件不存在,请重新输入>>>");return -2;}else{ERR("open srcfile");return -1;}}char buf[516]="";//用sprintf拼接读写请求封包int size=sprintf(buf,"%c%c%s%c%s%c",0,2,f_n,0,"octet",0);if(sendto(cfd,buf,size,0,(struct sockaddr*)&sin,sizeof(sin)) < 0){ERR("sendto askpackage");return -1;}printf("sendto askpackage success\n");//记录块编号int num=0;unsigned short* ptr = (unsigned short *)(buf+2);//记录我要传过去数据的大小ssize_t len = -1;socklen_t addrlen = sizeof(sin);while(1){bzero(buf,sizeof(buf));//接受ACKif(recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&addrlen) < 0){ERR("recvfrom ACKpackage");return -1;}printf("recvfrom ACKpackage success\n");//当传过来的是ACK并且对应的块编号是需要的块编号时if(buf[1] == 4){if(*ptr == htons(num)){num++;//把操作码改为3,向服务器发送数据buf[1] = 3;//*(unsigned short *)(buf+2)= htons(num);*ptr = htons(num);//从文件中读取数据,保存到buf中len = read(srcfd,buf+4,sizeof(buf)-4);if(len < 0){ERR("read srcfd");return -1;}else if(0 == len){printf("文件上传完毕\n");break;}//向服务器发送打包好的数据包if(sendto(cfd,buf,len+4,0,(struct sockaddr*)&sin,addrlen) < 0){ERR("sendto datapackage");return -1;}printf("sendto datapackage success\n");}else{printf("网络不好,上传数据失败\n");break;}}else if(buf[1] == 5){fprintf(stderr,"错误码:%d,错误信息:%s\n",\ntohs(*(unsigned short*)(buf+2)),buf+4);break;}}return 0;
}

相关文章:

day37:网编day4,多点通信和并发服务器

一、广播接收方&#xff1a; #include <myhead.h>#define ERR_MSG(msg) do{\ fprintf(stderr,"__%d__\n",__LINE__);\ perror(msg);\ }while(0)#define BRD_IP "192.168.114.255" #define BRD_PORT 8888int main(int argc, const char *argv[]) {//…...

STM32 硬件IIC 控制OLED I2C卡死问题

1. STM32L151C8T6 硬件IIC 控制OLED 屏&#xff0c;OLED 驱动IC CH1116G, 查阅OLED 数据手册 2. STM32 硬件IIC 初始化&#xff0c;用的标准库&#xff0c;固件库 // stm32l151c8t6 as master, oled control ic (CH1116G) as slave, and communicate by master iic2 void STM3…...

Redis图文指南

1、什么是 Redis&#xff1f; Redis&#xff08;REmote DIctionary Service&#xff09;是一个开源的键值对数据库服务器。 Redis 更准确的描述是一个数据结构服务器。Redis 的这种特殊性质让它在开发人员中很受欢迎。 Redis不是通过迭代或者排序方式处理数据&#xff0c;而是…...

C++17 std::string_view介绍与使用

std::string_view介绍 std::string_view是C17增加的新内容。它是一个轻量级的、只读的字符串视图&#xff0c;可以用来表示一个字符串或字符串的一部分。std::string_view可以提高代码的可读性、可维护性和性能。 std::string_view与std::string的主要区别在于&#xff0c;st…...

写得了代码,焊得了板!嵌入式开发工程师必修之代码管理方案(下)

目录 极狐GitLab嵌入式开发场景解决方案 3.1 高可用部署与灾备 3.2 组织管理 3.3 分支策略 3.4 分支保护 3.5 推送规则 3.6 代码评审 3.7 数据保护 3.8 其他相关 本文来自 武让 极狐GitLab 高级解决方案架构师 &#x1f4a1; 前两篇文章&#xff0c;作者介绍了嵌入式开…...

Matlab论文插图绘制模板第110期—水平双向柱状图

在之前的文章中&#xff0c;分享了很多Matlab柱状图的绘制模板&#xff1a; 进一步&#xff0c;再来看一种特殊的柱状图&#xff1a;水平双向柱状图。 先来看一下成品效果&#xff1a; 特别提示&#xff1a;本期内容『数据代码』已上传资源群中&#xff0c;加群的朋友请自行下…...

【广州华锐互动】VR全景工厂虚拟导览,虚拟现实技术提升企业数字化信息管理水平

随着工业4.0的到来&#xff0c;VR工厂全景制作成为了越来越多工业企业的选择。传统的工厂管理方式往往存在诸多问题&#xff0c;如信息不对称、安全隐患等。为了解决这些问题&#xff0c;VR工厂全景制作应运而生&#xff0c;它通过结合虚拟现实现实技术和数据采集技术&#xff…...

idea 创建mybatis xml文件时找不到

1、File >Settings 如图 &#xff1a; 2、添加模板&#xff1a;如下图 3、添加xml模板 如下图&#xff1a; 模板内容&#xff1a; <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//E…...

Python钢筋混凝土结构计算.pdf-混凝土构件计算

计算原理&#xff1a; 代码实现&#xff1a; #钢筋混凝土参数 def c_hrb(): global fcuk,HRB,Ec,fc,ft,ftk,Es,fy,fyp,fyk global a1,epsilon_cu fcukEcfcftftk0.0 HRBEsfyfypfyk0.0 #矩形应力图系数a1&#xff0c;C50以下为1.0 a11.0 #正截面混凝土极限压应变epsilon_cu&#…...

mysql5.7-基于docker-compose搭建主从同步

一、环境信息 系统版本&#xff1a;CentOS Linux release 7.9.2009 (Core) cat /etc/centos-release Docker版本&#xff1a;Docker version 20.10.6, build 370c289 docker --version Docker-compose版本&#xff1a;Docker Compose version v2.10.2 docker-compose --versio…...

【USRP】调制解调系列5:16QAM、32QAM、64QAM、256QAM、1024QAM、基于labview的实现

QAM 正交振幅键控是一种将两种调幅信号&#xff08;2ASK和2PSK&#xff09;汇合到一个信道的方法&#xff0c;因此会双倍扩展有效带宽&#xff0c;正交调幅被用于脉冲调幅。正交调幅信号有两个相同频率的载波&#xff0c;但是相位相差90度&#xff08;四分之一周期&#xff0c…...

Odoo|5分钟创建自定义的业务系统唯一序列号

在业务操作中&#xff0c;经常会遇到需要生成全局唯一序列号数据的情况&#xff0c;比如订单号、报价单号等。为了确保数据的唯一性和准确性&#xff0c;通常我们会使用Redis或其他分布式锁机制来实现。然而&#xff0c;很多人可能不知道&#xff0c;odoo框架本身提供了一个原生…...

mysql索引为什么提高查询速度(底层原理)

一、索引原理图 二、索引数据存储到硬盘而不是内存&#xff1f; 硬盘内存 成本低成本高 容量大容量小 读写速度一般读取速度快 断电后数据永久存储断电后数据清空 三、硬盘数据为什么要读取到内存&#xff1f;为啥不直接…...

算法通关村——位运算在查找重复元素中的妙用

用4KB内存寻找重复元素 给定一个数组&#xff0c;包含从1到N的整数&#xff0c;N最大为32000&#xff0c;数组可能还有重复值&#xff0c;且N的取值不定&#xff0c;若只有4KB的内存可用&#xff0c;该如何打印数组中所有重复元素。 如果不要求使用4KB&#xff0c;最简单就是…...

使用环境中的视觉地标和扩展卡尔曼滤波器定位移动机器人研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

【python基础知识】5.for循环和while循环

文章目录 前言for...in...循环语句for循环&#xff1a;空房间for循环&#xff1a;一群排队办业务的人range()函数for循环&#xff1a;办事流程 while循环while循环&#xff1a;放行条件while循环&#xff1a;办事流程 两种循环对比 前言 上一关&#xff0c;我们学习了两种新的…...

STM32CUBEMX_创建时间片轮询架构的软件框架

STM32CUBEMX_创建时间片轮询架构的软件框架 说明&#xff1a; 1、这种架构避免在更新STM32CUBEMX配置后把用户代码清除掉 2、利用这种时间片的架构可以使得代码架构清晰易于维护 创建步骤&#xff1a; 1、使用STM32CUBEMX创建基础工程 2、新建用户代码目录 3、构建基础的代码框…...

vue 插槽Slots

vue插槽官网 <button class"fancy-btn"><slot></slot> <!-- 插槽出口 --> </button><slot> 元素是一个插槽出口 (slot outlet)&#xff0c;标示了父元素提供的插槽内容 (slot content) 将在哪里被渲染。 // 定义一个Child.vue…...

论文阅读《Nougat:Neural Optical Understanding for Academic Documents》

摘要 科学知识主要存储在书籍和科学期刊中&#xff0c;通常以PDF的形式。然而PDF格式会导致语义信息的损失&#xff0c;特别是对于数学表达式。我们提出了Nougat&#xff0c;这是一种视觉transformer模型&#xff0c;它执行OCR任务&#xff0c;用于将科学文档处理成标记语言&a…...

较难的换根dp:P6213 「SWTR-04」Collecting Coins

传送门 前题提要:感觉这道换根dp可以说是集中了换根dp的所有较高难度的操作和思想,以及较高的一些实现细节,可以说能够完全写出这道题才叫真正理解了换根dp,非常值得一做. 首先读完题意,不难发现这道题有很多限制.点的访问次数限制,必须访问某一个点,想要获得最大的贡献,没有…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

Spring AI与Spring Modulith核心技术解析

Spring AI核心架构解析 Spring AI&#xff08;https://spring.io/projects/spring-ai&#xff09;作为Spring生态中的AI集成框架&#xff0c;其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似&#xff0c;但特别为多语…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...