epoll_pool_select

1.Epoll

 常用操作:
  #include <sys/epoll.h>

 1,1 int epoll_create(int size);
  返回值:On  success,  these system calls return a non-negative file descriptor.
  
  
  
 1.2 int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
  返回值:When  successful,  epoll_ctl()  returns 0.
      
  這個函數通過之前創建的epfd來控制epoll,需要一些操作類型碼(op),來控制目標的描述符。
  This  system  call  performs  control  operations on the epoll instance
        referred to by the file descriptor epfd.  It requests that  the  operation op be performed for the target file descriptor- fd.
        
  
  Valid values for the op argument are :
   
       EPOLL_CTL_ADD
              Register  the  target  file  descriptor fd on the epoll instance
              referred to by the file descriptor epfd and associate the  event
              event with the internal file linked to fd.

        EPOLL_CTL_MOD
              Change  the event event associated with the target file descrip-
              tor fd.

        EPOLL_CTL_DEL
        
  //////////////////////////////////////////////////////////////////////////
    typedef union epoll_data {
               void        *ptr;
               int          fd;
               __uint32_t   u32;
               __uint64_t   u64;
           } epoll_data_t;

           struct epoll_event {
               __uint32_t   events;      /* Epoll events */
               epoll_data_t data;        /* User data variable */
           };
          
  The  events  member is a bit set composed using the following available event types:
        
        EPOLLIN :表示對應的文件描述符可以讀(包括對端SOCKET正常關閉);
  EPOLLOUT:表示對應的文件描述符可以寫;
  EPOLLPRI:表示對應的文件描述符有緊急的數據可讀(這裏應該表示有帶外數據到來);
  EPOLLERR:表示對應的文件描述符發生錯誤;
  EPOLLHUP:表示對應的文件描述符被掛斷;
  EPOLLET: 將EPOLL設爲邊緣觸發(Edge Triggered)模式,這是相對於水平觸發(Level Triggered)來說的。
  EPOLLONESHOT:只監聽一次事件,當監聽完這次事件之後,如果還需要繼續監聽這個socket的話,需要再次把這個socket加入到EPOLL隊列裏

  
        
   1.3  int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
   
   返回值:
    When  successful,  epoll_wait()  returns the number of file descriptors
       ready for the requested I/O, or zero if no file descriptor became ready
       during  the  requested  timeout  milliseconds. 
      
       //描述
       The epoll_wait() system call waits for events  on  the  epoll  instance
       referred to by the file descriptor epfd.  The memory area pointed to by
       events will contain the events that will be available for  the  caller.
       Up  to  maxevents are returned by epoll_wait().  The maxevents argument
       must be greater than zero.

       The call waits for a maximum time of timeout milliseconds.   Specifying
       a  timeout of -1 makes epoll_wait() wait indefinitely, while specifying
       a timeout equal to zero makes epoll_wait() to return  immediately  even
       if no events are available (return code equal to zero)
       
  示例代碼:
  #include <stdio.h>
  #include <string.h>
  #include <stdlib.h>
  
  #include <netinet/in.h>
  #include <arpa/inet.h>
  #include <unistd.h>
  #include <sys/epoll.h>
  #include <sys/types.h>       
  #include <sys/socket.h>
  #include <errno.h>
  
  int main()
  {
      int socketfd, ret, i;
       
      socketfd = socket(AF_INET,SOCK_STREAM,0);
      if(socketfd == -1)
      {
       perror("func socket\n");
       exit(0);
      }
    
      struct sockaddr_in srvaddr;
     
      srvaddr.sin_family = AF_INET;
      srvaddr.sin_port = htons(8001);
      srvaddr.sin_addr.s_addr = inet_addr("192.168.1.103");
     
      if(bind(socketfd,(struct sockaddr*)&srvaddr,sizeof(srvaddr))<0)
      {
       perror("func bind\n");
       exit(0);
      }
     
      if(listen(socketfd,SOMAXCONN)<0)
      {
       perror("func listen\n");
       exit(0);
      }
     
      struct epoll_event ev,events[20];
      int epollfd, nfds;
     
      struct sockaddr_in peeraddr;
      socklen_t peerlen = sizeof(peeraddr);
     
      char revbuf[1024] = {0};
      unsigned int connfd;
     
      epollfd = epoll_create(100);
  
      ev.data.fd = socketfd;
     
      ev.events = EPOLLIN|EPOLLET;
     
      epoll_ctl(epollfd,EPOLL_CTL_ADD,socketfd,&ev);
     
      while(1)
      {
    nfds = epoll_wait(epollfd, events, 20, 500);
    
    
                              
          for(i=0; i<nfds; i++)
    {
           if (events[i].data.fd == socketfd) {
                        
                 connfd = accept(socketfd,(struct sockaddr*)&peeraddr,
                       (socklen_t*)&peerlen);
                 if (connfd == -1) {
                    printf("accept");
                     exit(0);
                 }
                
                 printf("child process socketfd:%d, connfd%d\n",socketfd,connfd);
   
           printf("peeradd:%s \npeerport:%d\n",inet_ntoa(peeraddr.sin_addr),
                    ntohs(peeraddr.sin_port));
             
                 ev.events = EPOLLIN | EPOLLET;
                 ev.data.fd = connfd;
                 if (epoll_ctl(epollfd, EPOLL_CTL_ADD, connfd,
                     &ev) == -1) {
                     perror("epoll_ctl: conn_sock");
                     exit(EXIT_FAILURE);
                 }
              }else if(events[i].events & EPOLLIN){
                
                  ret = read(events[i].data.fd,revbuf,sizeof(revbuf));
      
         if(ret == 0)
         {
             printf("clt close \n");
             //exit(0);
         }
         
         fputs(revbuf,stdout);
         //memset(revbuf,0,sizeof(revbuf)); 
              } 
      
          }    
    }
      return 0;
  }

 
2.poll

    #include <poll.h>

       int poll(struct pollfd *fds, nfds_t nfds, int timeout);
      
      
        struct pollfd {
               int   fd;         /* file descriptor */
               short events;     /* requested events */
               short revents;    /* returned events */
           };
          
    The field fd contains a file descriptor for an open file.

       The  field  events  is  an  input  parameter, a bit mask specifying the
       events the application is interested in.

       The field revents is an output parameter, filled by the kernel with the
       events  that  actually  occurred.
      
      
           POLLIN There is data to read.

              POLLPRI
                     There is urgent data to read (e.g., out-of-band  data  on
                     TCP  socket;  pseudo-terminal  master  in packet mode has
                     seen state change in slave).

              POLLOUT
                     Writing now will not block.

              POLLRDHUP (since Linux 2.6.17)
                     Stream socket peer closed connection, or shut down  writ-
                     ing  half  of  connection.   The _GNU_SOURCE feature test
                     macro must be defined in order to obtain this definition.

             POLLERR
                     Error condition (output only).

              POLLHUP
                     Hang up (output only).

              POLLNVAL
                     Invalid request: fd not open (output only).

            When  compiling with _XOPEN_SOURCE defined, one also has the following,
            which convey no further information beyond the bits listed above:

              POLLRDNORM
                     Equivalent to POLLIN.

              POLLRDBAND
                     Priority band data  can  be  read  (generally  unused  on
                     Linux).

              POLLWRNORM
                     Equivalent to POLLOUT.

              POLLWRBAND
                     Priority data may be written.
  
    返回值:
       On success, a positive number is returned; this is the number of struc-
       tures  which  have  non-zero  revents  fields  (in  other  words, those
       descriptors with events or errors reported).  A value  of  0  indicates
       that  the call timed out and no file descriptors were ready.  On error,
       -1 is returned, and errno is set appropriately.
      
3.select
 
 #include <sys/select.h>

       /* According to earlier standards */
       #include <sys/time.h>
       #include <sys/types.h>
       #include <unistd.h>

       int select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);

       void FD_CLR(int fd, fd_set *set);
       int  FD_ISSET(int fd, fd_set *set);
       void FD_SET(int fd, fd_set *set);
       void FD_ZERO(fd_set *set);
 
 
 返回值:
   On  success,  select()  return the number of file descriptors contained
    in the three returned  descriptor  sets  (that  is,  the total  number 
    of  bits  that  are set in readfds, writefds, exceptfds)which may be zero
    if the timeout expires  before  anything  interesting happens.
     
         On error, -1 is returned, and errno is set appropriately; the
       sets and timeout become undefined, so do not  rely  on  their  contents
       after an error.
      
 NOTE:
    nfds  is the highest-numbered file descriptor in any of the three sets,
       plus 1.

   struct timeval {
               long    tv_sec;         /* seconds */
               long    tv_usec;        /* microseconds */
           };
    

示例代碼:
       #include <stdio.h>
       #include <stdlib.h>
       #include <sys/time.h>
       #include <sys/types.h>
       #include <unistd.h>

       int main(void)
       {
           fd_set rfds;
           struct timeval tv;
           int retval;

           /* Watch stdin (fd 0) to see when it has input. */
           FD_ZERO(&rfds);
           FD_SET(0, &rfds);
     /* Wait up to five seconds. */
           tv.tv_sec = 5;
           tv.tv_usec = 0;

           retval = select(1, &rfds, NULL, NULL, &tv);
           /* Don’t rely on the value of tv now! */

           if (retval == -1)
               perror("select()");
           else if (retval)
               printf("Data is available now.\n");
               /* FD_ISSET(0, &rfds) will be true. */
           else
               printf("No data within five seconds.\n");

           exit(EXIT_SUCCESS);
       }
    
 
 
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章