网络编程-TCP并发服务器-多点通信-域套接字

多进程实现TCP并发:依赖于while循环模式可初步实现并发功能,但是由于accpet函数和读写函数是阻塞的,导致必须要等待阻塞结束下一个用户才能连接,所以考虑使用多进程。

思路:将与客户端建立连接设置成父进程,将与客户端通信设置成子进程,考虑到客户结束通信需退出子进程,并防止僵尸进程,需回收子进程资源,故将回收进程函数设置成非阻塞,同时利用signal函数(SIGCHLD)实现一旦发现子进程死亡,立即发送信号回收进程资源,最后还需考虑子进程是完全拷贝父进程内存,需分别关闭文件描述符。

#include<head.h>
void handler(int signo);
int main(int argc, const char *argv[])
{if(signal(SIGCHLD,handler)==SIG_ERR){perror("signal");return -1;}//创建进程并发服务端//创建端点int sfd=socket(AF_INET,SOCK_STREAM,0);//参数1表示使用ipv4通信域//参数2表示使用TCP面向连接的通信方式//参数3表示补充通信协议,由于第二个参数已经指定通信方式,故写0if(sfd==-1){perror("socket");return 1;}else{printf("创建端点成功\n");}//调用端口快速重用函数int reuse=1;if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1){perror("setsockopt");return -1;}//将套结文件与IP地址与端口绑定struct sockaddr_in ip_port;char* ip="192.168.176.130";uint16_t port=8888;ip_port.sin_family=AF_INET;ip_port.sin_port=htons(port);ip_port.sin_addr.s_addr=inet_addr(ip);int retbind=bind(sfd,(struct sockaddr*)&ip_port,sizeof(ip_port));if(retbind==-1){perror("bind");return 1;}else if(retbind==0){printf("端口和IP绑定成功\n");}//将套接字设置为被动监听模式int retlisten=listen(sfd,128);if(retlisten==-1){perror("listen");return 1;}else if(retlisten==0){printf("设置监听成功\n");}//阻塞等待客户端连接struct sockaddr_in ser_ip_port;socklen_t addrlen=sizeof(ser_ip_port);int retaccept=-1;while(1){//父进程负责等待客户连接retaccept=accept(sfd,(struct sockaddr*)&ser_ip_port,&addrlen);if(retaccept==-1){perror("accept");return 1;}else{printf("客户端连接成功\n");printf("客户端IP:%s 客户端端口:%d\n",inet_ntoa(ser_ip_port.sin_addr),ntohs(ser_ip_port.sin_port));}pid_t pid=fork();if(pid>0){//父进程close(retaccept);}//与客户端相互通信else if(pid==0){close(sfd);//子进程完全拷贝父进程,所以需要关闭sfdchar wbuf[128]={0};char rbuf[128]={0};while(1){bzero(wbuf,0);bzero(rbuf,0);int retread=read(retaccept,rbuf,128);if(retread==0){//套结断开连接printf("客户端断开连接\n");break;}printf("读取客户端内容:%s\n",rbuf);strcat(rbuf,"<服务端已成功读取>");write(retaccept,rbuf,128);printf("成功回复客服端\n");}close(retaccept);//退出子进程exit(EXIT_SUCCESS);}else{perror("fork");return -1;}}close(sfd);return 0;
} 
void handler(int signo){if(signo==SIGCHLD){//设置成非阻塞while(waitpid(-1,NULL,WNOHANG)>0);}}

多线程实现TCP并发:

思路:主线程实现与客户端的连接,子线程实现与客户端实现通信,由于线程是去运行指定的代码片,所以避免不了局部变量问题,所以需注意指定运行的代码与主函数之间变量的关系,需要传参。

#include<head.h>
void* interaction(void* arg);
int main(int argc, const char *argv[])
{//使用线程实现服务端并发//创建端点int sfd=socket(AF_INET,SOCK_STREAM,0);//参数1表示使用ipv4通信域//参数2表示使用TCP面向连接的通信方式//参数3表示补充通信协议,由于第二个参数已经指定通信方式,故写0if(sfd==-1){perror("socket");return 1;}else{printf("创建端点成功\n");}//将套结文件与IP地址与端口绑定struct sockaddr_in ip_port;char* ip="192.168.176.130";uint16_t port=9999;ip_port.sin_family=AF_INET;ip_port.sin_port=htons(port);ip_port.sin_addr.s_addr=inet_addr(ip);int retbind=bind(sfd,(struct sockaddr*)&ip_port,sizeof(ip_port));if(retbind==-1){perror("bind");return 1;}else if(retbind==0){printf("端口和IP绑定成功\n");}//将套接字设置为被动监听模式int retlisten=listen(sfd,128);if(retlisten==-1){perror("listen");return 1;}else if(retlisten==0){printf("设置监听成功\n");}//阻塞等待客户端连接struct sockaddr_in ser_ip_port;socklen_t addrlen=sizeof(ser_ip_port);while(1){int retaccept=accept(sfd,(struct sockaddr*)&ser_ip_port,&addrlen);if(retaccept==-1){perror("accept");return 1;}else{printf("客户端连接成功\n");printf("客户端IP:%s 客户端端口:%d\n",inet_ntoa(ser_ip_port.sin_addr),ntohs(ser_ip_port.sin_port));}int inter_parameter=retaccept;pthread_t id;int retpthread_create=pthread_create(&id,0,interaction,&inter_parameter);if(retpthread_create!=0){perror("pthread_creat");return -1;}pthread_detach(id);}close(sfd);return 0; 
}
void* interaction(void* arg){//与客户端相互通信//解析argint retaccept=*(int*)arg;char wbuf[128]={0};char rbuf[128]={0};while(1){bzero(wbuf,0);bzero(rbuf,0);                                        int retread=read(retaccept,rbuf,128);if(retread==0){//套结断开连接printf("客户端断开连接\n");break;}printf("读取客户端内容:%s\n",rbuf);strcat(rbuf,"<服务端已成功读取>");write(retaccept,rbuf,128);printf("成功回复客服端\n");}close(retaccept);pthread_exit(NULL);
}

多点通信——广播发送端实现:

#include<head.h>
int main(int argc, const char *argv[])
{//发送端实现//创建套接文件int rtsocket=socket(AF_INET,SOCK_DGRAM,0);if(rtsocket==-1){perror("socket");return -1;}else{printf("creat success\n");}//设置属性允许发送广播数据int res=-1;int reslen=sizeof(res);int rtgetsockopt=getsockopt(rtsocket,SOL_SOCKET,SO_BROADCAST,&res,&reslen);if(rtgetsockopt==-1){perror("getsockopt");return -1;}else{printf("res=%d\n",res);}int reluse=1;int rtsetsockopt=setsockopt(rtsocket,SOL_SOCKET,SO_BROADCAST,&reluse,sizeof(reluse));if(rtsetsockopt==-1){perror("setsockopt");return -1;}getsockopt(rtsocket,SOL_SOCKET,SO_BROADCAST,&res,&reslen);if(rtgetsockopt==-1){perror("getsockopt");return -1;}else{printf("res=%d\n",res);}//绑定ipyu端口(可选)//向广播发送消息struct sockaddr_in rin;char* bip="192.168.176.255";uint16_t bport=6666;                 rin.sin_family=AF_INET;rin.sin_port=htons(bport);rin.sin_addr.s_addr=inet_addr(bip);char wbuf[128]={0};while(1){bzero(wbuf,128);fgets(wbuf,128,stdin);wbuf[strlen(wbuf)-1]=0;ssize_t rtsendto=sendto(rtsocket,wbuf,sizeof(wbuf),0,(struct sockaddr*)&rin,sizeof(rin));if(rtsendto==-1){perror("sendto");return -1;}if(strcmp(wbuf,"over")==0){break;}}close(rtsocket);return 0;
} 

多点通信——广播接收端实现:

#include<head.h>
int main(int argc, const char *argv[])
{//接收端实现//创建套接文件int rtsocket=socket(AF_INET,SOCK_DGRAM,0);if(rtsocket==-1){perror("socket");return -1;}//填充结构体信息struct sockaddr_in rin;char* bip="192.168.176.255";uint16_t bport=6666;rin.sin_family=AF_INET;rin.sin_port=htons(bport);rin.sin_addr.s_addr=inet_addr(bip);//绑定广播端口号和IP(必须绑定)int rtbind=bind(rtsocket,(struct sockaddr*)&rin,sizeof(rin));if(rtbind==-1){perror("bind");return -1;}//接收广播信息char rbuf[128]={0};while(1){memset(rbuf,0,128);ssize_t rtrecv=recv(rtsocket,rbuf,sizeof(rbuf),0);if(rtrecv==-1){perror("recv");return -1;}printf("广播消息%s\n:",rbuf);if(strcmp(rbuf,"over")==0){break;}}close(rtsocket);return 0;
} 

多点通信——组播接收端实现:

#include<head.h>
int main(int argc, const char *argv[])
{//使用组播通信方式实现接收端int rtsocket=socket(AF_INET,SOCK_DGRAM,0);if(rtsocket==-1){perror("socket");return -1;}//将套接字加入多播组struct ip_mreqn ip_m;ip_m.imr_multiaddr.s_addr=inet_addr("224.1.2.3");ip_m.imr_address.s_addr=inet_addr("192.168.176.130");ip_m.imr_ifindex=2;int rtsetsockopt=setsockopt(rtsocket,IPPROTO_IP,IP_ADD_MEMBERSHIP,&ip_m,sizeof(ip_m));if(rtsetsockopt==-1){perror("setsockopt");return -1;}//填充地址信息结构体 struct sockaddr_in rin;rin.sin_family=AF_INET;uint16_t rport=5555;rin.sin_port=htons(rport);rin.sin_addr.s_addr=inet_addr("224.1.2.3");//绑定(必须)int rtbind=bind(rtsocket,(struct sockaddr*)&rin,sizeof(rin));if(rtbind==-1){perror("bind");return -1;}//接收消息char rbuf[128]={0};while(1){bzero(rbuf,128);int rtrecv=recv(rtsocket,rbuf,sizeof(rbuf),0);if(rtrecv==-1){perror("recv");return -1;}printf("接收的消息:%s\n",rbuf);if(strcmp(rbuf,"over")==0){break;}}close(rtsocket);return 0;
}

多点通信——组播发送端实现:

#include<head.h>
int main(int argc, const char *argv[])
{//组播发送端int rtsocket=socket(AF_INET,SOCK_DGRAM,0);if(rtsocket==-1){perror("socket");return -1;}struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(5555);sin.sin_addr.s_addr=inet_addr("224.1.2.3");char wbuf[128]={0};while(1){memset(wbuf,0,128);fgets(wbuf,sizeof(wbuf),stdin);wbuf[strlen(wbuf)-1]=0;ssize_t rtsendto=sendto(rtsocket,wbuf,sizeof(wbuf),0,(struct sockaddr*)&sin,sizeof(sin));if(rtsendto==-1){perror("sendto");return -1;}printf("发送成功\n");if(strcmp(wbuf,"over")==0){break;}}close(rtsocket);return 0;
}
u

流式域套接字——服务端实现:

#include<head.h>
int main(int argc, const char *argv[])
{//使用域套接创建服务端//创建端点int sfd=socket(AF_UNIX,SOCK_STREAM,0);//参数1表示使用域套接通信域//参数2表示使用TCP面向连接的通信方式//参数3表示补充通信协议,由于第二个参数已经指定通信方式,故写0if(sfd==-1){perror("socket");return 1;}else{printf("创建端点成功\n");}//判断套接文件是否存在,因为存在再重新创建并绑定会报错if(access("./unix",F_OK)==0){unlink("./unix");//存在则删除文件}//删除后,将套结文件与通信域与套接文件路径绑定struct sockaddr_un un;un.sun_family=AF_UNIX;strcpy(un.sun_path,"./unix");int retbind=bind(sfd,(struct sockaddr*)&un,sizeof(un));if(retbind==-1){perror("bind");return 1;}else if(retbind==0){printf("端口和IP绑定成功\n");}//将套接字设置为被动监听模式int retlisten=listen(sfd,128);if(retlisten==-1){perror("listen");return 1;}else if(retlisten==0){printf("设置监听成功\n");}//阻塞等待客户端连接 struct sockaddr_un sun;socklen_t addrlen=sizeof(sun);int retaccept=accept(sfd,(struct sockaddr*)&sun,&addrlen);if(retaccept==-1){perror("accept");return 1;}else{printf("客户端连接成功\n");printf("套接文件:[%s]\n",sun.sun_path);}//与客户端相互通信char wbuf[128]={0};char rbuf[128]={0};while(1){bzero(wbuf,0);bzero(rbuf,0);int retread=read(retaccept,rbuf,128);if(retread==0){//套结断开连接printf("客户端断开连接\n");break;}printf("读取客户端内容:%s\n",rbuf);strcat(rbuf,"<服务端已成功读取>");write(retaccept,rbuf,128);printf("成功回复客服端\n");}close(retaccept);close(sfd);return 0;
} 

流式域套接字——客户端实现:

#include<head.h>
int main(int argc, const char *argv[])
{//使用域套接创建一个客户端//创建端点int sfd=socket(AF_UNIX,SOCK_STREAM,0);if(sfd==-1){perror("socket");return 1;}else{printf("创建成功\n");}//判断文件是否存在 if(access("./lunix",F_OK)==0){unlink("./lunix");//存在则删除文件}//将套结文件绑定struct sockaddr_un un;un.sun_family=AF_UNIX;strcpy(un.sun_path,"./lunix");int retbind=bind(sfd,(struct sockaddr*)&un,sizeof(un));if(retbind==-1){perror("bind");return 1;}else if(retbind==0){printf("IP与端口绑定成功\n");}//与服务器连接struct sockaddr_un run;run.sun_family=AF_UNIX;strcpy(run.sun_path,"./unix");//填充需要发送服务端的套接文件int retconnect=connect(sfd,(struct sockaddr*)&run,sizeof(run));if(retconnect==-1){perror("connect");return 1;}else if(retconnect==0){printf("连接成功\n");}//与服务器相互通信char rbuf[128]={0};char wbuf[128]={0};while(1){memset(rbuf,0,128);memset(wbuf,0,128); printf("请向服务端发送信息:");fgets(wbuf,128,stdin);wbuf[strlen(wbuf)-1]=0;send(sfd,wbuf,sizeof(wbuf),0);printf("向服务端发送消息成功\n");ssize_t retrecv=recv(sfd,rbuf,128,0);printf("接受服务端信息:%s\n",rbuf);}close(sfd);return 0;
}

报式域套接字——服务端实现:

#include<head.h>
int main(int argc, const char *argv[])
{//使用域套接创建服务端//创建一个端点int retsocket=socket(AF_UNIX,SOCK_DGRAM,0);if(retsocket==-1){perror("socket");return -1;}else{printf("创建端点成功\n");}//判断要绑定的套接文件是否存在,存在则删除(存在文件再重新绑定会报错)if(access("./udpunix",F_OK)==0){unlink("./udpunix");//存在则删除}//绑定套接字文件struct sockaddr_un un;un.sun_family=AF_UNIX;strcpy(un.sun_path,"./udpunix");int retbind=bind(retsocket,(struct sockaddr*)&un,sizeof(un));if(retbind==-1){perror("bind");return -1;}else if(retbind==0){printf("绑定成功\n");}//与客服端相互通信struct sockaddr_un sun;char rbuf[128]={0};char wbuf[128]={0};socklen_t addrlen=sizeof(sun);while(1){bzero(rbuf,0);bzero(wbuf,0);ssize_t retrecvfrom=recvfrom(retsocket,rbuf,128,0,(struct sockaddr*)&sun,&addrlen);if(retrecvfrom==-1){perror("recvfrom");return -1;}else{printf("读取客服端消息成功\n");printf("读取客服端消息:%s\n",rbuf);}//判断消息内容,只与一个人连接if(strcmp(rbuf,"connect")==0){connect(retsocket,(struct sockaddr*)&sun,sizeof(sun));}else if(strcmp(rbuf,"disconnect")==0){//断开连接sun.sun_family=AF_UNSPEC;connect(retsocket,(struct sockaddr*)&sun,sizeof(sun));}printf("请向客服端发送消息\n");fgets(wbuf,128,stdin);wbuf[strlen(wbuf)-1]=0;//清除空格ssize_t retsendto=sendto(retsocket,wbuf,strlen(wbuf),0,(struct sockaddr*)&sun,addrlen);if(retsendto==-1){perror("sendto");return -1;}else{printf("向客服端发送消息成功\n"); }}close(retsocket);return 0;
}

报式域套接字——客户端实现:

#include<head.h>
int main(int argc, const char *argv[])
{//创建客服端//创建一个端点,即套接字文件int retsocket=socket(AF_UNIX,SOCK_DGRAM,0);if(retsocket==-1){perror("socket");return -1;}else{printf("创建端点成功\n");}//判断要绑定的套接文件是否存在,存在则删除(存在文件再重新绑定会报错)if(access("./ludpunix",F_OK)==0){unlink("./ludpunix");//存在则删除}//使套接字绑定struct sockaddr_un un;un.sun_family=AF_UNIX;strcpy(un.sun_path,"./ludpunix");int retbind=bind(retsocket,(struct sockaddr*)&un,sizeof(un));if(retbind==-1){perror("bind");return -1;}else if(retbind==0){printf("绑定成功\n");}//与服务端相互通信struct sockaddr_un serun;serun.sun_family=AF_UNIX;strcpy(serun.sun_path,"./udpunix");char rbuf[128]={0};char wbuf[128]={0};socklen_t addrlen=sizeof(serun);while(1){bzero(rbuf,0);bzero(wbuf,0);printf("请向服务端发送消息\n");fgets(wbuf,128,stdin);wbuf[strlen(wbuf)-1]=0;//清除空格ssize_t retsendto=sendto(retsocket,wbuf,strlen(wbuf),0,(struct sockaddr*)&serun,addrlen);if(retsendto==-1){perror("sendto");return -1;}ssize_t retrecv=recvfrom(retsocket,rbuf,128,0,(struct sockaddr*)&serun,&addrlen);if(retrecv==-1){perror("sendto");return -1;}else{printf("读取服务端消息成功\n");printf("读取服务端消息:%s\n",rbuf);}}close(retsocket);return 0;
}

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

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

相关文章

Tower在深度学习中的概念,tower没有确切定义

在论文UniTS中&#xff0c;来自Havard的工作。 tower更像是针对一个task的组件 tower这个概念貌似在REC&#xff08;recommendation&#xff09;推荐系统中使用较多 deep learning - What is a tower? - Data Science Stack Exchange https://developers.google.com/machin…

Android APP在debug模式下,如何避免activity被系统destroy

最近在调式APP时发现&#xff0c;如果在APP运行时&#xff08;比如&#xff1a;进入了某个子模块的某个列表项的详情页&#xff1a;InfoShowActivity&#xff09;&#xff0c;点击home按钮&#xff0c;返回主屏幕。然后再返回APP时&#xff0c;APP不会显示之前的界面&#xff0…

技术前沿 |【VL-BEIT:引领未来的极简单阶段多模态预训练方案】

VL-BEIT&#xff1a;引领未来的极简单阶段多模态预训练方案 引言一、VL-BEIT的基本介绍二、VL-BEIT的原理和工作方式三、VL-BEIT的特点四、VL-BEIT的应用场景五、总结与展望 引言 在人工智能蓬勃发展的今天&#xff0c;多模态预训练模型正逐渐成为研究和应用的热点。这些模型能…

二叉树OJ题目

一.二叉树第k层结点个数 有这样的一个思路&#xff1a;我既然要求第k层的结点个数&#xff0c;我肯定是要用到递归&#xff0c;那么当我在递归到第k层的时候我就开始判断&#xff0c;这一层是不是我所需要的那一层&#xff0c;如果是&#xff0c;就计数有几个节点&#xff0c;…

边框渐变样式

实现样式&#xff1a; 对应代码&#xff1a; div {min-height: 40vh;border: 10px solid transparent;background-image: linear-gradient(#222, #222), var(--gradient);background-origin: border-box;background-clip: padding-box, border-box;border-radius: 10px;positi…

一周开发一个在线客服系统

使用 Go 和 Gin 框架开发在线客服系统是一种高效且性能优越的选择。以下是具体的开发计划&#xff0c;专注于使用 Gin 框架来实现后端&#xff1a; 演示效果&#xff1a;gofly.v1kf.com 第一天&#xff1a;需求分析和设计 需求分析&#xff1a; 确定系统功能&#xff1a;实时聊…

【数组】Leetcode 228. 汇总区间【简单】

汇总区间 给定一个 无重复元素 的 有序 整数数组 nums 。 返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表 。也就是说&#xff0c;nums 的每个元素都恰好被某个区间范围所覆盖&#xff0c;并且不存在属于某个范围但不属于 nums 的数字 x 。 列表中的每个区间范围 [a,…

粉丝问,有没有UI的统计页面,安排!

移动应用的数据统计页面具有以下几个重要作用&#xff1a; 监控业务指标&#xff1a;数据统计页面可以帮助用户监控关键业务指标和数据&#xff0c;例如用户活跃度、销售额、转化率等。通过实时更新和可视化呈现数据&#xff0c;用户可以及时了解业务的整体状况和趋势。分析用…

每日练习之字符串——得分

得分 题目描述 运行代码 #include <iostream> using namespace std; int main(){int n;cin>>n;while(n--){string s;cin>>s;int ls.length();int a0;int t1;for(int i0;i<l;i){if(s[i]O){at;t;}else if(s[i]X){t1;}}cout<<a<<endl;} } 代码…

QT7_视频知识点笔记_5_线程,数据库

多线程 两种办法&#xff1a;第一种&#xff1a;Qt4.7之前的线程使用的方法&#xff08;简单&#xff09;&#xff1b;第二种&#xff1a;Qt4.7之后的&#xff08;灵活–推荐&#xff09;----connect最后一个参数的作用&#xff1a;默认连接&#xff0c;队列连接&#xff0c;直…

操作系统总结4----死锁的处理策略总结

目录 2.4.2 死锁的处理策略-----预防死锁 &#xff08;1&#xff09;知识总览 &#xff08;2&#xff09;破环互斥条件 &#xff08;3&#xff09;破环不剥夺条件 &#xff08;4&#xff09;破环求情和保持条件 &#xff08;5&#xff09;破环循环等待条件 总结 2.4.3 死…

AI革命:生活无处不智能

AI革命&#xff1a;生活无处不智能 &#x1f604;生命不息&#xff0c;写作不止 &#x1f525; 继续踏上学习之路&#xff0c;学之分享笔记 &#x1f44a; 总有一天我也能像各位大佬一样 &#x1f3c6; 博客首页 怒放吧德德 To记录领地 &#x1f31d;分享学习心得&#xff0…

使用FFmpeg推流实现在B站24小时点歌直播

使用FFmpeg推流实现在B站24小时点歌直播 本文首发于个人博客 安装FFmpeg centos7 https://www.myfreax.com/how-to-install-ffmpeg-on-centos-7/ https://linuxize.com/post/how-to-install-ffmpeg-on-centos-7/ 使用FFmpeg在B站直播 https://zhuanlan.zhihu.com/p/2395…

竞赛 基于深度学习的动物识别 - 卷积神经网络 机器视觉 图像识别

文章目录 0 前言1 背景2 算法原理2.1 动物识别方法概况2.2 常用的网络模型2.2.1 B-CNN2.2.2 SSD 3 SSD动物目标检测流程4 实现效果5 部分相关代码5.1 数据预处理5.2 构建卷积神经网络5.3 tensorflow计算图可视化5.4 网络模型训练5.5 对猫狗图像进行2分类 6 最后 0 前言 &#…

FreeRTOS任务间通信“IPC”

---------------信号量--------------- 信号量的定义&#xff1a; 操作系统中一种解决问题的机制&#xff0c;可以实现 “共享资源的访问” 信号&#xff1a;起通知作用量&#xff1a;还可以用来表示资源的数量当"量"没有限制时&#xff0c;它就是"计数型信…

C++原创人工智能QPBS01G大功告成!!!

俗话说得好&#xff0c;你周五周六不写作业&#xff0c;要上学了才着急了 我之前的版本bug太多&#xff0c;结果这两天晚上改的我两眼发白&#xff0c;太烦人了 这次这娃学聪明了&#xff0c;遇到不会的问题上网搜&#xff0c;我还更新了反骂人骂人功能&#xff0c;第一次测试…

盟军敢死队1, 修改版300夺关下载

http://www.mj141319.imotor.com/viewthread.php?tid2706&extrapage%3D1

抖音小店新规又来了!平台下调了两项门槛,惊掉商家下巴!

大家好&#xff0c;我是电商糖果 平台这几年为了快速发展电商项目&#xff0c;一直在向商家释放友好政策&#xff0c;目的就是为了吸引更多的商家入驻。 这不官方5月30日起下调了两个门槛&#xff0c;让不少商家大呼不可思议。 第一个就是保证金下调。 平台按照商家经营类目…

代码随想录算法训练营第十六天 | 104.二叉树的最大深度、559.n叉树的最大深度、111.二叉树的最小深度、222.完全二叉树的节点个数

104.二叉树的最大深度 题目链接&#xff1a;https://leetcode.cn/problems/maximum-depth-of-binary-tree/ 文档讲解&#xff1a;https://programmercarl.com/0104.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9C%80%E5%A4%A7%E6%B7%B1%E5%BA%A6.html#%E7%AE%97%E6%B3%95%E5%85%A…

infoq读书笔记-省钱在于“架构师”!亚马逊CTO 20年架构经 验之道:俭约架构师的七大黄金法则

“俭约架构师”的七大黄金法则 法则一&#xff1a;将成本视为一种非功能性需求:可访问性、可用性、可扩展性、安全性、可移植性、可维护性和合规性等都在此列。而成本往往是其中受到忽略的一条 法则二&#xff1a;确保系统的最终成本与业务保持一致: 在设计和构建系统时&#…