您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 销售管理 > epoll并发连接测试
亲测epoll最大并发数,通过测试并发书为30000时,服务端会容易死机。下面是服务端的程序:#includestdio.h#includestdlib.h#includeerrno.h#includestring.h#includesys/types.h#includenetinet/in.h#includesys/socket.h#includesys/wait.h#includeunistd.h#includearpa/inet.h#includefcntl.h#includesys/epoll.h#includesys/time.h#includesys/resource.h#defineMAXBUF1024#defineMAXEPOLLSIZE3000/*setnonblocking-设置句柄为非阻塞方式*/intsetnonblocking(intsockfd){if(fcntl(sockfd,F_SETFL,fcntl(sockfd,F_GETFD,0)|O_NONBLOCK)==-1)return-1;return0;}intmain(intargc,char*argv[]){intlistener,new_fd,epfd,nfds,n,ret,curfds;socklen_tlen;structsockaddr_inmy_addr,their_addr;unsignedintmyport,lisnum;structepoll_eventev;structepoll_eventevents[MAXEPOLLSIZE];structrlimitrt;charbuffer[MAXBUF];charrsp_msg[2]=ok;myport=5000;lisnum=100;/*设置每个进程允许打开的最大文件数*/rt.rlim_max=rt.rlim_cur=MAXEPOLLSIZE;if(setrlimit(RLIMIT_NOFILE,&rt)==-1){perror(setrlimit);exit(1);}/*开启socket监听*/if((listener=socket(PF_INET,SOCK_STREAM,0))==-1){perror(socket);exit(1);}elseprintf(socket创建成功!\n);setnonblocking(listener);my_addr.sin_family=PF_INET;my_addr.sin_port=htons(myport);my_addr.sin_addr.s_addr=INADDR_ANY;bzero(&(my_addr.sin_zero),8);if(bind(listener,(structsockaddr*)&my_addr,sizeof(structsockaddr))==-1){perror(bind);exit(1);}elseprintf(IP地址和端口绑定成功\n);if(listen(listener,lisnum)==-1){perror(listen);exit(1);}elseprintf(开启服务成功!\n);/*创建epoll句柄,把监听socket加入到epoll集合里*/epfd=epoll_create(MAXEPOLLSIZE);len=sizeof(structsockaddr_in);ev.events=EPOLLIN|EPOLLET;ev.data.fd=listener;if(epoll_ctl(epfd,EPOLL_CTL_ADD,listener,&ev)0)//注册{fprintf(stderr,epollsetinsertionerror:fd=%d\n,listener);return-1;}elseprintf(监听socket加入epoll成功!\n);curfds=0;while(1){/*等待有事件发生*/nfds=epoll_wait(epfd,events,MAXEPOLLSIZE,-1);if(nfds==-1){perror(epoll_wait);break;}printf(当前并发连接数:%d\n,curfds);printf(nfds=%d\n,nfds);for(n=0;nnfds;++n){if(events[n].data.fd==listener){new_fd=accept(listener,(structsockaddr*)&their_addr,&len);if(new_fd0){perror(accept);continue;}else{printf(有连接来自于:%s:%d,分配的socket为:%d\n,inet_ntoa(their_addr.sin_addr),ntohs(their_addr.sin_port),new_fd);}setnonblocking(new_fd);ev.events=EPOLLIN|EPOLLET;ev.data.fd=new_fd;if(epoll_ctl(epfd,EPOLL_CTL_ADD,new_fd,&ev)0){fprintf(stderr,把socket'%d'加入epoll失败!%s\n,new_fd,strerror(errno));return-1;}curfds++;}elseif(events[n].events&EPOLLIN){printf(startrecv\t);//bzero(buffer,sizeof(buffer));ret=recv(events[n].data.fd,buffer,MAXBUF,0);if(ret0){perror(read);return-1;//exit(EXIT_FAILURE);}if(ret==0){printf(文件描述服%d\n,events[n].data.fd);ev.data.fd=events[n].data.fd;epoll_ctl(epfd,EPOLL_CTL_DEL,events[n].data.fd,&ev);close(events[n].data.fd);curfds--;continue;}printf(recvmessageis:%s\n,buffer);ev.data.fd=events[n].data.fd;ev.events=EPOLLOUT|EPOLLET;epoll_ctl(epfd,EPOLL_CTL_MOD,events[n].data.fd,&ev);}elseif(events[n].events&EPOLLOUT){printf(startsend\n);/*ret=send(events[n].data.fd,rsp_msg,strlen(rsp_msg),0);if(ret0){perror(send);return-1;}ev.data.fd=events[n].data.fd;ev.events=EPOLLIN|EPOLLET;epoll_ctl(epfd,EPOLL_CTL_MOD,events[n].data.fd,&ev);*/}}}close(listener);//return0;}此处并没有让服务端来处理数据,只是单纯链接并发数。注释部分就是处理数据部分,如果需要可以取消注释。下面是客户端的程序:#includestdio.h#includestring.h#includeerrno.h#includesys/socket.h#includestdlib.h#includeresolv.h#includenetinet/in.h#includearpa/inet.h#includeunistd.h#includefcntl.h#includesys/types.h#includetime.h#defineMAXBUF128#defineLOOP_TIMES10intmain(intargc,char*argv[]){intsockfd,i,j;structsockaddr_indest;charsendbuf[]=helloworld;charrecvbuf[MAXBUF];intpid[1000];//srand((unsignedint)time(NULL));if(argc!=5){printf(errorformat,itmustbe:\n\t%sIPport\n,argv[0]);exit(EXIT_FAILURE);}for(j=0;jatoi(argv[3]);j++){if((pid[j]=fork())==-1){perror(fork);exit(EXIT_FAILURE);}if(pid[j]==0){pid_tpid=getpid();for(i=0;i500;i++){printf(socketcreated1pid=%dfd=%d\n,pid,sockfd);if((sockfd=socket(AF_INET,SOCK_STREAM,0))0){perror(socket);exit(EXIT_FAILURE);}printf(socketcreated2pid=%dfd=%d\n,pid,sockfd);//bzero(&dest,sizeof(dest));dest.sin_family=AF_INET;dest.sin_port=htons(atoi(argv[2]));if(inet_aton(argv[1],(structin_addr*)&dest.sin_addr.s_addr)==0){perror(argv[1]formaterror);exit(EXIT_FAILURE);}printf(connect1pid=%dfd=%d\n,pid,sockfd);if(connect(sockfd,(structsockaddr*)&dest,sizeof(dest))==-1){perror(connect);exit(EXIT_FAILURE);}printf(connect2pid=%dfd=%d\n,pid,sockfd);//printf(serverconnectedsuccessful\n);//send(sockfd,sendbuf,sizeof(sendbuf),0);//recv(sockfd,recvbuf,2,0);//printf(recvmessageis:%s\n,recvbuf);//sleep(0+(int)(2.0*rand()/(RAND_MAX+1.0)));//close(sockfd);//exit(EXIT_SUCCESS);}printf(sleep1pid=%d\n,pid);sleep(atoi(argv[4]));printf(sleep2pid=%d\n,pid);exit(0);}}for(i=0;iatoi(argv[3]);i++){waitpid(pid[i],NULL,0);}}
本文标题:epoll并发连接测试
链接地址:https://www.777doc.com/doc-2911550 .html