epoll 实例

来源:互联网 发布:网络系统集成中的软件 编辑:程序博客网 时间:2024/06/01 12:40

#include<iostream>
#include<sys/socket.h>
#include<sys/epoll.h>
#include<netinet/in.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>

using namespace std;

#define MAXLINE 100
#define OPEN_MAX 100
#define LISTENQ 20
#define SERV_PORT 5004
#define INFTIM 1000

void setnonblocking(int sock)
{
   int opts;
   opts = fcntl(sock,F_GETFL);
   if(opts<0)
   {
     perror("fcntl(sock,SETFL,opts)");
     exit(1);
   }

}

int main(int argc,char* argv[])
{
   int i,maxi,listenfd,connfd,sockfd,epfd,nfds,portnumber;
   ssize_t n;
   char line[MAXLINE];
   socklen_t client;
  
   if(2==argc)
   {
      if((portnumber = atoi(argv[1]))<0)
      {
         fprintf(stderr,"usage:%s portnumber/a/n",argv[0]);
         return 1;
      }
   }
   else
   {
  
     if((portnumber = atoi(argv[1]))<0)
      {
         fprintf(stderr,"usage:%s portnumber/a/n",argv[0]);
         return 1;
      }
   }
  
   struct epoll_event ev,events[20];
  
   epfd = epoll_create(60);
   cout<<"epfd = "<<epfd<<endl;
   int tmp;
   cin>>tmp;
   struct sockaddr_in clientaddr;
   struct sockaddr_in serveraddr;
   listenfd = socket(AF_INET,SOCK_STREAM,0);
  
   //设置与要处理的事件相关的文件描述符
   ev.data.fd = listenfd;
   //设置要处理的事件类型
   ev.events = EPOLLIN|EPOLLET;
  
   //注册epoll事件
   if(epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev)==-1)
      cout<<"注册监听事件失败"<<endl;
   else
      cout<<"注册监听事件成功"<<endl;
  
   cin>>tmp;
  
   bzero(&serveraddr,sizeof(serveraddr));
   serveraddr.sin_family = AF_INET;
   char *local_addr = "127.0.0.1";
  
   inet_aton(local_addr,&(serveraddr.sin_addr));
  
   serveraddr.sin_port = htons(portnumber);
   bind(listenfd,(sockaddr *)&serveraddr,sizeof(serveraddr));
  
  
   listen(listenfd,LISTENQ);
   cout<<"listening..."<<endl;
   cin>>tmp;
  
   maxi = 0;
   while(1)
   {
     //等待epoll事件的发生
     cout<<"waiting..."<<endl;
     nfds = epoll_wait(epfd,events,20,-1);
     cout<<"nfds = "<<nfds<<endl;
     for(i=0;i<nfds;++i)
     {
        if(events[i].data.fd == listenfd)//新连接
        {
          cout<<"new clinet connecting"<<endl;
           connfd = accept(listenfd,(sockaddr *)&clientaddr,&client);
           if(connfd<0)
           {
             perror("connfd<0");
             continue;
           }
           char *str = inet_ntoa(clientaddr.sin_addr);
           cout<<"accept a connectiong from "<<str<<endl;
          
           ev.data.fd = connfd;
           ev.events = EPOLLIN|EPOLLET;
          
           epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev);
        }
       else if(events[i].events&EPOLLIN)////可读
       {
         cout<<"有数据可读"<<endl;
         if((sockfd = events[i].data.fd)<0)
           continue;
         if((n = read(sockfd,line,MAXLINE))<0)
         {
           if(errno==ECONNRESET)
           {
              close(sockfd);
              events[i].data.fd = -1;
           }else
             cout<<"read error"<<endl;
            
         }else if( 0 ==n)
         {
           close(sockfd);
           events[i].data.fd = -1;
          
         }
         line[n] = '/0';
         cout<<"recv "<<line<<endl;
       
        ev.data.fd = sockfd;
        ev.events = EPOLLOUT|EPOLLET;
        epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);//精髓
       
       }
      else if(events[i].events&EPOLLOUT)
      {
          sockfd = events[i].data.fd;
          write(sockfd,line,n);
          ev.data.fd = sockfd;
          ev.events = EPOLLIN|EPOLLET;
          epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);//精髓
      }
  
     }
  
  }
   close(epfd);
return 0;
}

 

0 0
原创粉丝点击