1. 程式人生 > >Linux下IO多路轉接技術之epoll

Linux下IO多路轉接技術之epoll

<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通過本機環回來測試。