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;
}

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

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

相关文章

three.js 场景中如何彻底删除模型和性能优化

three.js 场景中如何彻底删除模型和性能优化 删除外部模型 在three.js场景中&#xff0c;要彻底删除外部模型&#xff0c;需要执行以下几个步骤&#xff1a; 从场景中移除模型 你可以使用 scene.remove(model) 或者 scene.remove(model.children[0]) 将模型从场景中移除。如果…

【⑰MySQL】 变量 | 循环 | 游标 | 处理程序

前言 ✨欢迎来到小K的MySQL专栏&#xff0c;本节将为大家带来MySQL变量 | 循环 | 游标 | 处理程序的分享✨ 目录 前言1. 变量1.1系统变量1.2 用户变量 2. 定义条件与处理程序2.1 案例分析2.2 定义条件2.3 定义处理程序2.4 案例解决 3. 流程控制3.1 分支结构3.2 循环结构3.3 跳转…

ELK安装、部署、调试 (八)logstash配置语法详解

input {#输入插件 }filter {#过滤插件 }output {#输出插件 } 1.读取文件。 使用filewatch的ruby gem库来监听文件变化&#xff0c;并通过.sincedb的数据库文件记录被监听日志we年的读取进度&#xff08;时间 搓&#xff09; 。sincedb数据文件的默认路径为<path.data>/…

sentinel-core

引入依赖<dependencies><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-core</artifactId></dependency><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-anno…

Revit SDK 介绍:DWGFamilyCreation 导入DWG

前言 这个例子介绍了如何导入 DWG。 内容 核心逻辑代码&#xff1a; // 设置导入选项 DWGImportOptions options new DWGImportOptions(); options.Placement Autodesk.Revit.DB.ImportPlacement.Origin; options.OrientToView true; ElementId elementId null; // 导入…

【Vue2.0源码学习】生命周期篇-初始化阶段(initInjections)

文章目录 1. 前言2. initInjections函数分析resolveInject函数分析 3. 总结 1. 前言 本篇文章介绍生命周期初始化阶段所调用的第四个初始化函数——initInjections。从函数名字上来看&#xff0c;该函数是用来初始化实例中的inject选项的。说到inject选项&#xff0c;那必然离…

labview卸载重装碰到的问题

目录 labeiw卸载重装过程当中总是碰到一些问题&#xff0c;记录一下解决办法&#xff0c;碰到后好查找。 个人推荐卸载 用laview自带的卸载软件进行卸载&#xff0c;卸载的比较干净。 卸载完全第一步 启动 labview自带的卸载软件进行卸载。一般进行完这一步&#xff0c;就…

设计模式-9--迭代器模式(Iterator Pattern)

一、什么是迭代器模式 迭代器模式&#xff08;Iterator Pattern&#xff09;是一种行为型设计模式&#xff0c;用于提供一种统一的方式来访问一个聚合对象中的各个元素&#xff0c;而不需要暴露该聚合对象的内部结构。迭代器模式将遍历集合的责任从集合对象中分离出来&#xf…

【深入解析spring cloud gateway】07 自定义异常返回报文

Servlet的HttpResponse对象&#xff0c;返回响应报文&#xff0c;一般是这么写的&#xff0c;通过输出流直接就可以将返回报文输出。 OutputStream out response.getOutputStream(); out.write("输出的内容"); out.flush();在filter中如果发生异常&#xff08;例如…

Java中的网络编程------基于Socket的TCP编程和基于UDP的网络编程,netstat指令

Socket 在Java中&#xff0c;Socket是一种用于网络通信的编程接口&#xff0c;它允许不同计算机之间的程序进行数据交换和通信。Socket使得网络应用程序能够通过TCP或UDP协议在不同主机之间建立连接、发送数据和接收数据。以下是Socket的基本介绍&#xff1a; Socket类型&…

1775_树莓派3B键盘映射错误解决

全部学习汇总&#xff1a; GitHub - GreyZhang/little_bits_of_raspberry_pi: my hacking trip about raspberry pi. 入手树莓派3B之后用了没有多长时间&#xff0c;最初的这段时间感觉想让它代替我的PC机是不肯能的。性能先不说&#xff0c;我完全没有找到当初在我的笔记本上使…

css网格布局

css网格布局 常用属性 display: grid; //开启网格grid-template-columns: 2fr 1fr 1fr 1fr 1fr; //设置多少列每列宽度grid-gap: 10px; // 设置表格之间间距grid-template-rows: 50px 50px 50px 50px; // 设置多少行 每行的高度grid-column : 1 //占据位置 占据1格grid-colu…

ChatGPT分析日本排放核污水对世界的影响

文章目录 1 背景2 环境影响3 健康影响4 国际关系影响5 应对措施 近段时间被日本排放核污水到海里的消息刷屏了&#xff0c;这一举措引发了广泛的关注和担忧。本文结合ChatGPT来分析这件事的前因后果、会对世界造成的影响、以及应对措施。 1 背景 受2011年发生的大地震及海啸影响…

机器人中的数值优化(九)——拟牛顿方法(下)、BB方法

本系列文章主要是我在学习《数值优化》过程中的一些笔记和相关思考&#xff0c;主要的学习资料是深蓝学院的课程《机器人中的数值优化》和高立编著的《数值最优化方法》等&#xff0c;本系列文章篇数较多&#xff0c;不定期更新&#xff0c;上半部分介绍无约束优化&#xff0c;…

某物联网数智化园区行业基于 KubeSphere 的云原生实践

公司简介 作为物联网 数智化园区一体化解决方案提供商&#xff0c;我们致力于为大中型园区、停车场提供软硬件平台&#xff0c;帮助园区运营者实现数字化、智能化运营。 在使用 K8s 之前我们使用传统的方式部署上线&#xff0c;使用 spug&#xff08;一款轻量级无 Agent 的自…

网络版五子棋C++实现

目录 1.项目介绍 2.开发环境 3.核心技术 4.环境搭建 5.WebSocketpp介绍 5.1WebSocketpp是什么 5.2为什么使用WebSocketpp 5.3原理解析&#xff1a; 5.4WebSocketpp主要特性 6.WebSocketpp使用 7.JsonCpp使用 8.MySQL API 9.项目模块设计以及流程图 10.封装日志宏…

NewStarCTF 2022 web方向题解 wp

----------WEEK1---------- BUU NewStarCTF 公开赛赛道 WEEK1 [NotPHP] 先看题目&#xff0c;要传参加绕过。 分析一下代码&#xff1a;首先get一个datadata://test/plain,Wel…。然后key1和2用数组可以绕过。num2077a可以绕过弱类型。eval()中的php语句被#注释了&#xff0c…

【jvm】jvm系统线程

目录 一、虚拟机线程二、周期任务线程三、GC线程四、编译线程五、信号调度线程 一、虚拟机线程 1.这种线程的操作是需要jvm达到安全点才会出现 2.这些操作必须在不同的线程中发生的原因是它们都需要jvm达到安全点&#xff0c;这样堆才不会变化 3.这种线程的执行类型包括stop-th…

并发编程的故事——JUC

JUC 文章目录 JUC一、Semaphore二、CountDownLatch三、线程安全类 一、Semaphore 为什么需要用到Semaphore? 限流 Semaphore的场景&#xff1f; 秒杀商品的时候&#xff0c;不能够让那些没有秒杀成功的线程进入&#xff0c;只有占了坑位的才可以使用&#xff0c;这里可以用re…

【Hello Algorithm】二叉树相关算法

本篇博客介绍&#xff1a;介绍二叉树的相关算法 二叉树相关算法 二叉树结构遍历二叉树递归序二叉树的交集非递归方式实现二叉树遍历二叉树的层序遍历 二叉树难题二叉树的序列化和反序列化lc431求二叉树最宽的层二叉树的后继节点谷歌面试题 二叉树结构 如果对于二叉树的结构还有…