Linux下IO多路轉接技術之epoll
阿新 • • 發佈:2019-01-22
<span style="font-family:Microsoft YaHei;">while(1) { switch((nums=epoll_wait(epfd,_ready_ev,_ready_evs,_timeout)))//wait n fd ready { case 0: printf("timeout......\n"); break; case -1: perror("epoll_wait"); break; default: { int i=0; for(;i<nums;++i) { int _fd=_ready_ev[i].data.fd; if(_fd==listen_sock && _ready_ev[i].events & EPOLLIN)//get a link { struct sockaddr_in peer; socklen_t len=sizeof(peer); int new_sock=accept(listen_sock,(struct sockaddr*)&peer,&len); if(new_sock>0) { printf("client info,socket:%s:%d\n",inet_ntoa(peer.sin_addr),ntohs(peer.sin_port)); _ev.events=EPOLLIN | EPOLLET;//ET _ev.data.fd=new_sock; set_noblock(new_sock); epoll_ctl(epfd,EPOLL_CTL_ADD,new_sock,&_ev); } }else { if(_ready_ev[i].events & EPOLLIN) { char buf[102400]; memset(buf,'\0',sizeof(buf)); ssize_t _s=recv(_fd,buf,sizeof(buf)-1,0); if(_s>0) { printf("client#%s\n",buf); _ev.events=EPOLLOUT | EPOLLET; _ev.data.fd=_fd; epoll_ctl(epfd,EPOLL_CTL_MOD,_fd,&_ev); }else if(_s==0) { printf("client close....\n"); epoll_ctl(epfd,EPOLL_CTL_DEL,_fd,NULL); close(_fd); }else { perror("recv"); exit(6); } }else if(_ready_ev[i].events & EPOLLOUT) { const char* msg="HTTP/1.1 200 OK\r\n\r\n<h1>hello world =_=||</h1>\r\n"; send(_fd,msg,strlen(msg),0); epoll_ctl(epfd,EPOLL_CTL_DEL,_fd,NULL); close(_fd); } } } } break; } }</span>
<span style="font-family:Microsoft YaHei;">static int set_noblock(int sock)
{
int fl=fcntl(sock,F_GETFL);
return fcntl(sock,F_SETFL,fl | O_NONBLOCK);
}</span>
至此,一個伺服器就寫好了。我們可以開啟自己的瀏覽器輸入127.0.0.1:8080通過本機環回來測試。