帮助文档
专业提供香港服务器、香港云服务器、香港高防服务器租用、香港云主机、台湾服务器、美国服务器、美国云服务器vps租用、韩国高防服务器租用、新加坡服务器、日本服务器租用 一站式全球网络解决方案提供商!专业运营维护IDC数据中心,提供高质量的服务器托管,服务器机房租用,服务器机柜租用,IDC机房机柜租用等服务,稳定、安全、高性能的云端计算服务,实时满足您的多样性业务需求。 香港大带宽稳定可靠,高级工程师提供基于服务器硬件、操作系统、网络、应用环境、安全的免费技术支持。
服务器资讯 / 香港服务器租用 / 香港VPS租用 / 香港云服务器 / 美国服务器租用 / 台湾服务器租用 / 日本服务器租用 / 官方公告 / 帮助文档
Linux学习之网络编程3(高并发服务器)
发布时间:2024-03-06 15:28:10   分类:帮助文档
Linux学习之网络编程3(高并发服务器) 写在前面 Linux网络编程我是看视频学的,Linux网络编程,看完这个视频大概网络编程的基础差不多就掌握了。这个系列是我看这个Linux网络编程视频写的笔记总结。 高并发服务器 问题: 根据上一个笔记,我们可以写出一个简单的服务端和客户端通信,但是我们发现一个问题——服务器只能连接一个客户端。然而在实际生活中,我们发现一个服务器连接的客户端远远不止一个,所以我们就要做一个高并发服务器。 解决方法: 回看之前的代码,之所以只能一对一通信,是因为服务器只有一次执行accept的机会,一旦建立连接成功,就会去进行通信处理业务,而其他想要建立连接的服务器就没办法建立连接。因此我们想到在Linux系统编程中学的进程和线程,我们可以让父进程(主线程)去监听,一定有客户端请求建立连接,我们就创建子进程(其他线程)去和客户端建立连接进行通信,父进程(主线程)继续监听。 多进程并发服务器 思路(步骤): 前期准备工作: 先用socket()生成一个套接字lfd用来监听用bind()对第一步生成的套接字绑定地址结构(绑的是服务器的地址结构)用listen()函数设置lfd的监听上限,最大是128. 进入循环,accept与客户端建立连接,得到用于通信的套接字的文件描述符cfdfork()创建子进程对于父进程,由于父进程只是监听,不需要与客户端进行通信,所以我们就关闭cfd,注册信号捕捉函数,用来回收子进程,然后一直循环监听。对于子进程,由于子进程只是进行通信,不需要监听,所以我们就关闭lfd,然后就与客户端进行通信,处理业务。 源代码: #include #include #include #include #include #include #include #include #define PORT 6666 void sys_err(char* str) { perror(str); exit(-1); } void wait_child(int signum) //信号捕捉,回收子进程 { while((waitpid(0,NULL,WNOHANG))>0); // if(waitpid(0,NULL,0)!=-1) // printf("disconnect a client successfully\n"); return; } int main() { struct sockaddr_in addr_s,addr_c; socklen_t addr_c_len=sizeof addr_c; int lfd,cfd,res,n; pid_t pid; struct sigaction act; char buf[BUFSIZ],client_IP[1024]; lfd=socket(AF_INET,SOCK_STREAM,0); if(lfd<0) sys_err("socket error"); addr_s.sin_family=AF_INET; addr_s.sin_port=htons(PORT); addr_s.sin_addr.s_addr=htonl(INADDR_ANY); res=bind(lfd,(struct sockaddr*)&addr_s,sizeof addr_s); if(res==-1) sys_err("bind error"); res=listen(lfd,128); if(res==-1) sys_err("listen error"); while(1) { cfd=accept(lfd,(struct socket*)&addr_c,&addr_c_len); pid=fork(); //创建子进程 if(pid==0) //子进程 { close(lfd); //打印客户端的IP和端口号,可以省略 printf("connect successfully,client IP:%s,port:%d\n",inet_ntop(AF_INET,&addr_c.sin_addr.s_addr,&client_IP,sizeof client_IP),ntohs(addr_c.sin_port)); break; } else if(pid>0) { close(cfd); act.sa_handler=wait_child; sigemptyset(&act.sa_mask); act.sa_flags=0; sigaction(SIGCHLD,&act,NULL); continue; } } if(pid==0) //父进程 { while(1) { n=read(cfd,buf,sizeof buf); for(int i=0;i #include #include #include #include #include #include #include #define PORT 6666 void sys_err(char* str) { perror(str); exit(-1); } void* fun(void* arg) { int cfd=(int) arg,n; char buf[BUFSIZ]; while(1) { n=read(cfd,buf,sizeof buf); if(n==0) { printf("one client closed......\n"); break; } for(int i=0;i