Advertisement
Guest User

epoll_example.c

a guest
Nov 13th, 2014
312
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.29 KB | None | 0 0
  1. #include <unistd.h>
  2. #include <fcntl.h>
  3. #include <stdio.h>
  4. #include <memory.h>
  5. #include <netdb.h>
  6. #include <errno.h>
  7. #include <sys/types.h>
  8. #include <sys/epoll.h>
  9. #include <sys/types.h>
  10. #include <sys/socket.h>
  11.  
  12. int const MAX_EVENTS = 1024;
  13.  
  14. static int create_and_bind(char const* port)
  15. {
  16.     struct addrinfo hints;
  17.     struct addrinfo* result,* rp;
  18.     int s, sfd;
  19.  
  20.     memset(&hints, 0, sizeof hints);
  21.     hints.ai_family = AF_UNSPEC;     /* Return IPv4 and IPv6 choices */
  22.     hints.ai_socktype = SOCK_STREAM; /* We want a TCP socket */
  23.     hints.ai_flags = AI_PASSIVE;     /* All interfaces */
  24.  
  25.     s = getaddrinfo(NULL, port, &hints, &result);
  26.     if (s != 0) {
  27.         fprintf(stderr, "getaddrinfo: %s\n", gai_strerror (s));
  28.         return -1;
  29.     }
  30.  
  31.     for (rp = result; rp != NULL; rp = rp->ai_next) {
  32.         sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
  33.         if (sfd == -1)
  34.             continue;
  35.  
  36.         s = bind(sfd, rp->ai_addr, rp->ai_addrlen);
  37.         if (s == 0) {
  38.             break;
  39.         }
  40.         close (sfd);
  41.     }
  42.  
  43.     if (rp == NULL) {
  44.         fprintf (stderr, "Could not bind\n");
  45.         return -1;
  46.     }
  47.  
  48.     freeaddrinfo(result);
  49.     return sfd;
  50. }
  51.  
  52. static int make_socket_non_blocking(int fd)
  53. {
  54.     int flags, s;
  55.  
  56.     flags = fcntl(fd, F_GETFL, 0);
  57.     if (flags == -1) {
  58.         perror ("fcntl");
  59.         return -1;
  60.     }
  61.  
  62.     flags |= O_NONBLOCK;
  63.     s = fcntl(fd, F_SETFL, flags);
  64.     if (s == -1) {
  65.         perror ("fcntl");
  66.         return -1;
  67.     }
  68.  
  69.     return 0;
  70. }
  71.  
  72. int main() {
  73.     int epfd, i, n;
  74.     struct epoll_event events[MAX_EVENTS];
  75.     struct epoll_event event;
  76.     int sockfd = create_and_bind("4999");
  77.     if (sockfd == -1) {
  78.         perror("create and bind");
  79.         return 1;
  80.     }
  81.     if (make_socket_non_blocking(sockfd)) {
  82.         perror("mask non blocking");
  83.         return 1;
  84.     }
  85.     if (listen(sockfd, 1024)) {
  86.         perror("listen");
  87.         return 1;
  88.     }
  89.     epfd = epoll_create(1024);
  90.     if (epfd == -1) {
  91.         perror("epoll create");
  92.         return 1;
  93.     }
  94.     event.data.fd = sockfd;
  95.     event.events = EPOLLIN | EPOLLET;
  96.     if (epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &event)) {
  97.         perror("epoll ctl");
  98.         return 1;
  99.     }
  100.  
  101.     while (1) {
  102.         n = epoll_wait(epfd, events, MAX_EVENTS, -1);
  103.         for (i = 0; i < n; ++i) {
  104. //      for (i = 0; i < epoll_wait(epfd, events, MAX_EVENTS, -1); ++i) {
  105.             if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))) {
  106.                 fprintf(stderr, "epoll error\n");
  107.                 close(events[i].data.fd);
  108.                 continue;
  109.             }
  110.             if (events[i].data.fd == sockfd) {
  111.                 while (1) {
  112.                     struct sockaddr in_addr;
  113.                     socklen_t in_len;
  114.                     int infd;
  115.                     char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
  116.                
  117.                     in_len = sizeof in_addr;
  118.                     infd = accept (sockfd, &in_addr, &in_len);
  119.                     if (infd == -1) {
  120.                         if ((errno == EAGAIN) ||
  121.                             (errno == EWOULDBLOCK)) {
  122.                             break;
  123.                         } else {
  124.                             perror ("accept");
  125.                             break;
  126.                         }
  127.                     }
  128.                
  129.                     if (getnameinfo (&in_addr, in_len,
  130.                                      hbuf, sizeof hbuf,
  131.                                      sbuf, sizeof sbuf,
  132.                                      NI_NUMERICHOST | NI_NUMERICSERV) == 0)
  133.                     {
  134.                         printf("Accepted connection on descriptor %d "
  135.                                "(host=%s, port=%s)\n", infd, hbuf, sbuf);
  136.                     }
  137.                
  138.                     if (make_socket_non_blocking (infd))
  139.                       return 1;
  140.                     event.data.fd = infd;
  141.                     event.events = EPOLLIN | EPOLLET;
  142.                     if (epoll_ctl (epfd, EPOLL_CTL_ADD, infd, &event) == -1) {
  143.                         perror ("epoll_ctl");
  144.                         return 1;
  145.                     }
  146.                 }
  147.                 continue;
  148.             }
  149.             int done = 0;
  150.  
  151.             while (1) {
  152.                 ssize_t count;
  153.                 char buf[512];
  154.  
  155.                 printf("Reading...\n");
  156.                 fflush(stdout);
  157.                 count = read(events[i].data.fd, buf, sizeof buf - 1);
  158.                 if (count == -1) {
  159.                     if (errno != EAGAIN) {
  160.                         perror("read");
  161.                         done = 1;
  162.                     }
  163.                     break;
  164.                 }
  165.                 printf("%d bytes read\n", count);
  166.                 buf[count] = 0;
  167.                 printf("Message: %s\n", buf);
  168.                 if (count < sizeof buf) {
  169.                     done = 1;
  170.                     break;
  171.                 }
  172.                 fflush(stdout);
  173.             }
  174.  
  175.             if (done) {
  176.                 printf ("Closed connection on descriptor %d\n",
  177.                         events[i].data.fd);
  178.                 close (events[i].data.fd);
  179.             }
  180.         }
  181.     }
  182. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement