Linux IO多路复用之epoll网络编程
前言
本章节是用基本的Linux基本函数加上epoll调用编写一个完整的服务器和客户端例子,可在Linux上运行,客户端和服务端的功能如下:
- 客户端从标准输入读入一行,发送到服务端
- 服务端从网络读取一行,然后输出到客户端
- 客户端收到服务端的响应,输出这一行到标准输出
服务端
代码如下:
#include#include /*basicsystemdatatypes*/ #include /*basicsocketdefinitions*/ #include /*sockaddr_in{}andotherInternetdefns*/ #include /*inet(3)functions*/ #include /*epollfunction*/ #include /*nonblocking*/ #include /*setrlimit*/ #include #include #include #include #defineMAXEPOLLSIZE10000 #defineMAXLINE10240 inthandle(intconnfd); intsetnonblocking(intsockfd) { if(fcntl(sockfd,F_SETFL,fcntl(sockfd,F_GETFD,0)|O_NONBLOCK)==-1){ return-1; } return0; } intmain(intargc,char**argv) { intservPort=6888; intlistenq=1024; intlistenfd,connfd,kdpfd,nfds,n,nread,curfds,acceptCount=0; structsockaddr_inservaddr,cliaddr; socklen_tsocklen=sizeof(structsockaddr_in); structepoll_eventev; structepoll_eventevents[MAXEPOLLSIZE]; structrlimitrt; charbuf[MAXLINE]; /*设置每个进程允许打开的最大文件数*/ rt.rlim_max=rt.rlim_cur=MAXEPOLLSIZE; if(setrlimit(RLIMIT_NOFILE,&rt)==-1) { perror("setrlimiterror"); return-1; } bzero(&servaddr,sizeof(servaddr)); servaddr.sin_family=AF_INET; servaddr.sin_addr.s_addr=htonl(INADDR_ANY); servaddr.sin_port=htons(servPort); listenfd=socket(AF_INET,SOCK_STREAM,0); if(listenfd==-1){ perror("can'tcreatesocketfile"); return-1; } intopt=1; setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)); if(setnonblocking(listenfd)<0){ perror("setnonblockerror"); } if(bind(listenfd,(structsockaddr*)&servaddr,sizeof(structsockaddr))==-1) { perror("binderror"); return-1; } if(listen(listenfd,listenq)==-1) { perror("listenerror"); return-1; } /*创建epoll句柄,把监听socket加入到epoll集合里*/ kdpfd=epoll_create(MAXEPOLLSIZE); ev.events=EPOLLIN|EPOLLET; ev.data.fd=listenfd; if(epoll_ctl(kdpfd,EPOLL_CTL_ADD,listenfd,&ev)<0) { fprintf(stderr,"epollsetinsertionerror:fd=%d\n",listenfd); return-1; } curfds=1; printf("epollserverstartup,port%d,maxconnectionis%d,backlogis%d\n",servPort,MAXEPOLLSIZE,listenq); for(;;){ /*等待有事件发生*/ nfds=epoll_wait(kdpfd,events,curfds,-1); if(nfds==-1) { perror("epoll_wait"); continue; } /*处理所有事件*/ for(n=0;n =MAXEPOLLSIZE){ fprintf(stderr,"toomanyconnection,morethan%d\n",MAXEPOLLSIZE); close(connfd); continue; } if(setnonblocking(connfd)<0){ perror("setnonblockingerror"); } ev.events=EPOLLIN|EPOLLET; ev.data.fd=connfd; if(epoll_ctl(kdpfd,EPOLL_CTL_ADD,connfd,&ev)<0) { fprintf(stderr,"addsocket'%d'toepollfailed:%s\n",connfd,strerror(errno)); return-1; } curfds++; continue; } //处理客户端请求 if(handle(events[n].data.fd)<0){ epoll_ctl(kdpfd,EPOLL_CTL_DEL,events[n].data.fd,&ev); curfds--; } } } close(listenfd); return0; } inthandle(intconnfd){ intnread; charbuf[MAXLINE]; nread=read(connfd,buf,MAXLINE);//读取客户端socket流 if(nread==0){ printf("clientclosetheconnection\n"); close(connfd); return-1; } if(nread<0){ perror("readerror"); close(connfd); return-1; } write(connfd,buf,nread);//响应客户端 return0; }
编译
编译和启动服务端
gccepollserver.c-oepollserver ./epollserver
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对毛票票的支持。如果你想了解更多相关内容请查看下面相关链接
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。