epoll

来源:互联网 发布:淘宝刷单好评 编辑:程序博客网 时间:2024/05/01 23:45
  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #include <stdlib.h>  
  4. #include <sys/types.h>  
  5. #include <sys/socket.h>  
  6. #include <netinet/in.h>  
  7. #include <arpa/inet.h>  
  8. #include <sys/epoll.h>  
  9. #include <unistd.h>  
  10. #include <fcntl.h>  
  11.   
  12. int start_up(char* ip, short port)  
  13. {  
  14.     int listen_sock = socket(AF_INET, SOCK_STREAM, 0);  
  15.     if (listen_sock < 0)  
  16.     {  
  17.         perror("socket");  
  18.         exit(2);  
  19.     }  
  20.   
  21.     struct sockaddr_in local;  
  22.     local.sin_family = AF_INET;  
  23.     local.sin_port = htons(port);  
  24.     local.sin_addr.s_addr = inet_addr(ip);  
  25.     if (bind(listen_sock, (struct sockaddr*)&local, sizeof(local)))  
  26.     {  
  27.         perror("bind");  
  28.         exit(3);  
  29.     }  
  30.       
  31.     if (listen(listen_sock, 5) < 0)  
  32.     {  
  33.         perror("listen");  
  34.         exit(4);  
  35.     }  
  36.   
  37.     return listen_sock;  
  38. }  
  39.   
  40. void Usage(const char* proc)  
  41. {  
  42.     printf("Usage: %s [ip] [port]\n", proc);  
  43. }  
  44.   
  45. static int set_nonblock(int fd)  
  46. {  
  47.     int fl = fcntl(fd, F_GETFL);  
  48.     fcntl(fd, F_SETFL, fl|O_NONBLOCK);  
  49. }  
  50.   
  51. int main(int argc, char* argv[])  
  52. {  
  53.     if (argc != 3)  
  54.     {  
  55.         Usage(argv[0]);  
  56.         exit(1);  
  57.     }  
  58.   
  59.     int listen_sock = start_up(argv[1], atoi(argv[2]));  
  60.       
  61.     int epfd = epoll_create(256);  
  62.     if (epfd < 0)  
  63.     {  
  64.         perror("epoll_create");  
  65.         exit(5);  
  66.     }  
  67.   
  68.     struct epoll_event ev;  
  69.     ev.events = EPOLLIN;  
  70.     ev.data.fd = listen_sock;  
  71.     // 注册唯一文件描述符:关注读事件  
  72.     epoll_ctl(epfd, EPOLL_CTL_ADD, listen_sock, &ev);  
  73.   
  74.     struct epoll_event ready_events[64];  
  75.     int timeout = -1;  
  76.     while (1)  
  77.     {  
  78.         int num = epoll_wait(epfd, ready_events, 64, timeout);    
  79.         if (num < 0)  
  80.         {  
  81.             perror("epoll_wait");  
  82.         }  
  83.         else if (num == 0)  
  84.         {  
  85.             printf("timeout...\n");  
  86.         }  
  87.         else  
  88.         {  
  89.             int i = 0;  
  90.             for (; i < num; i++)  
  91.             {  
  92.                 // listen_sock 就绪  
  93.                 int new_fd = ready_events[i].data.fd;  
  94.                 if (new_fd == listen_sock && (ready_events[i].events & EPOLLIN))  
  95.                 {  
  96.                     struct sockaddr_in client;  
  97.                     socklen_t len = sizeof(client);  
  98.                     int new_fd = accept(listen_sock, (struct sockaddr*)&client, &len);  
  99.                     if (new_fd < 0)  
  100.                     {  
  101.                         perror("accept");  
  102.                     }  
  103.                     else  
  104.                     {  
  105.                         printf("get a new connect: %s:%d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));  
  106.   
  107.                         ev.events = EPOLLIN;  
  108.                         ev.data.fd = new_fd;  
  109.                         epoll_ctl(epfd, EPOLL_CTL_ADD, new_fd, &ev);  
  110.                     }  
  111.                 }  
  112.                 else if (ready_events[i].events & EPOLLIN)  // normal events  
  113.                 {  
  114.                     char buf[1024];  
  115.                     ssize_t s = read(new_fd, buf, sizeof(buf)-1);  
  116.                     if (s < 0)  
  117.                     {  
  118.                         perror("read");  
  119.                     }  
  120.                     else if (s == 0)  
  121.                     {  
  122.                         printf("client closed...\n");     
  123.                         epoll_ctl(epfd, EPOLL_CTL_DEL, new_fd, NULL);  
  124.                         close(new_fd);  
  125.                     }  
  126.                     else  
  127.                     {  
  128.                         buf[s] = 0;  
  129.                         printf("clinet# %s\n", buf);  
  130.   
  131.                         ev.events = EPOLLOUT | EPOLLET;  
  132.                         ev.data.fd = new_fd;  
  133.                         epoll_ctl(epfd, EPOLL_CTL_MOD, new_fd, &ev);                  
  134.                     }  
  135.                 }  
  136.                 else if (ready_events[i].events & EPOLLOUT)  
  137.                 {  
  138.                     char buf[1024];  
  139.                     strcpy(buf, "HTTP/1.0 200 OK\r\n\r\n<html><h1>hello world ! =_=||</h1></html>");  
  140.                     write(new_fd, buf, strlen(buf));  
  141.                     epoll_ctl(epfd, EPOLL_CTL_DEL, new_fd, NULL);  
  142.                     close(new_fd);  
  143.                 }  
  144.             }  
  145.         }  
  146.     } // while  
  147.   
  148.   
  149.     return 0;  
  150. }  
原创粉丝点击