• epoll的一个使用例子


    使用到主要函数有:

    #include <sys/epoll.h>
    int epoll_create(int size);
    int epoll_create1(int flags);
    int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
    int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
    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 */
    };
     1 #define EPOLL_SIZE 1024
     2 int doServiceEpoll(int listenFd)
     3 {
     4     struct epoll_event events[EPOLL_SIZE];
     5 
     6     struct epoll_event event;
     7     int epollFd = epoll_create1(EPOLL_CLOEXEC);
     8     if(epollFd < 0) {
     9         ERR_EXIT("epoll_create1");
    10     }
    11 
    12     event.data.fd = listenFd;
    13     event.events = EPOLLIN|EPOLLET;
    14     if(epoll_ctl(epollFd, EPOLL_CTL_ADD, listenFd, &event) < 0) {
    15         ERR_EXIT("epoll_ctl");
    16     }
    17     
    18     int epollRet;
    19     int i;
    20     struct sockaddr_in cliAddr;
    21     socklen_t len;
    22     int acceptFd;
    23     int epollNum = 1;
    24     int readNum;
    25     while(1) {
    26         epollRet = epoll_wait(epollFd, events, epollNum, -1);
    27         if(epollRet < 0) {
    28             ERR_EXIT("epollRet");
    29         } else if(epollRet == 0) {
    30             continue;
    31         }
    32 
    33         for(i = 0; i < epollRet; i++) {
    34             if(events[i].data.fd == listenFd) {
    35                 memset(&cliAddr, 0, sizeof(cliAddr));
    36                 len = sizeof(cliAddr);
    37                 if((acceptFd = accept(listenFd, (struct sockaddr *)&cliAddr, &len)) < 0) {
    38                     ERR_EXIT("accept");
    39                 }
    40                 printf("recv a connect from %s, port %d, fd %d
    ", 
    41                     inet_ntoa(cliAddr.sin_addr), ntohs(cliAddr.sin_port), acceptFd);
    42                 epollNum++;  
    43                 event.data.fd = acceptFd;
    44                 event.events = EPOLLIN|EPOLLET;
    45                 if(epoll_ctl(epollFd, EPOLL_CTL_ADD, event.data.fd , &event) < 0) {
    46                     ERR_EXIT("epoll_ctl");
    47                 }
    48             } 
    49             else if(events[i].events & EPOLLIN) {
    50                 if(events[i].data.fd < 0) {
    51                     continue;
    52                 }
    53                 readNum = handleRead(events[i].data.fd);
    54                 if(readNum == READ_ERROR) {
    55                     ERR_EXIT("handleRead");
    56                 } else if(readNum == READ_CLOSE) {
    57                     event = events[i];
    58                     if(epoll_ctl(epollFd, EPOLL_CTL_DEL, event.data.fd, &event) < 0) { 
    59                         ERR_EXIT("epoll_ctl");
    60                     }
    61                     epollNum--;
    62                     printf("client closed, remove %d
    ", events[i].data.fd);
    63                     close(events[i].data.fd);
    64                 } 
    65             }
    66         }
    67     }    
    68 }

    1. struct epoll_event events[EPOLL_SIZE];用于返回发生了哪些事件。

    2. struct epoll_event event; 是一个临时变量,用于将我们想要监视的描述符通过 epoll_ctl 添加到集合中去。

    3. epollNum 表示当前监视的描述符的个数。

    4. epollRet 大于0时,表示有多少个文件描述符发生相关事件。 等于0时,表示超时。

    5. accept时,需要将连接套接字通过epoll_ctl 添加到集合中去。当read收到FIN时,需要将连接套接字通过epoll_ctl 从集合中删去,并close此套接字。

  • 相关阅读:
    单例模式的四种方式
    创建者模式
    抽象工厂模式
    工厂方法模式
    【位运算符与逻辑运算符知识点】【二进制枚举子集】【just for 状压】
    【数学基础】【欧拉定理模板】【费马小定理】
    【练习赛补题】poj 3026 Borg Maze 【bfs+最小生成树】【坑~】
    【数学基础】【欧拉函数解析模板】【欧拉筛法实现求1~n】【求某个数字n】
    【 数学基础】【素数线性筛法--欧拉筛法模板】【普通筛法的优化】
    【练习赛2补题】poj 2325 Persistent Numbers 【高精度除法+贪心】
  • 原文地址:https://www.cnblogs.com/superPerfect/p/3606554.html
Copyright © 2020-2023  润新知