├── README └── epoll.c /README: -------------------------------------------------------------------------------- 1 | 2 | a simple TCP server using EPOLL. 3 | 4 | if you want to test it, please create a TCP client. with it, you can send message to this TCP server. 5 | -------------------------------------------------------------------------------- /epoll.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define MAXLINE 10 14 | #define OPEN_MAX 100 15 | #define LISTENQ 20 16 | #define SERV_PORT 5555 17 | #define INFTIM 1000 18 | 19 | void setnonblocking(int sock) 20 | { 21 | int opts; 22 | opts = fcntl(sock, F_GETFL); 23 | 24 | if(opts < 0) { 25 | perror("fcntl(sock, GETFL)"); 26 | exit(1); 27 | } 28 | 29 | opts = opts | O_NONBLOCK; 30 | 31 | if(fcntl(sock, F_SETFL, opts) < 0) { 32 | perror("fcntl(sock, SETFL, opts)"); 33 | exit(1); 34 | } 35 | } 36 | 37 | int main(int argc, char *argv[]) 38 | { 39 | printf("epoll socket begins.\n"); 40 | int i, maxi, listenfd, connfd, sockfd, epfd, nfds; 41 | ssize_t n; 42 | char line[MAXLINE]; 43 | socklen_t clilen; 44 | 45 | struct epoll_event ev, events[20]; 46 | 47 | epfd = epoll_create(256); 48 | 49 | struct sockaddr_in clientaddr; 50 | struct sockaddr_in serveraddr; 51 | 52 | listenfd = socket(AF_INET, SOCK_STREAM, 0); 53 | 54 | setnonblocking(listenfd); 55 | 56 | ev.data.fd = listenfd; 57 | ev.events = EPOLLIN | EPOLLET; 58 | 59 | epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev); 60 | 61 | bzero(&serveraddr, sizeof(serveraddr)); 62 | serveraddr.sin_family = AF_INET; 63 | char *local_addr = "192.168.199.8"; 64 | inet_aton(local_addr, &(serveraddr.sin_addr)); 65 | serveraddr.sin_port = htons(SERV_PORT); 66 | 67 | bind(listenfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)); 68 | 69 | listen(listenfd, LISTENQ); 70 | 71 | maxi = 0; 72 | 73 | for(; ;) { 74 | nfds = epoll_wait(epfd, events, 20, 500); 75 | 76 | for(i = 0; i < nfds; ++i) { 77 | if(events[i].data.fd == listenfd) { 78 | printf("accept connection, fd is %d\n", listenfd); 79 | connfd = accept(listenfd, (struct sockaddr *)&clientaddr, &clilen); 80 | if(connfd < 0) { 81 | perror("connfd < 0"); 82 | exit(1); 83 | } 84 | 85 | setnonblocking(connfd); 86 | 87 | char *str = inet_ntoa(clientaddr.sin_addr); 88 | printf("connect from %s\n", str); 89 | 90 | ev.data.fd = connfd; 91 | ev.events = EPOLLIN | EPOLLET; 92 | epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev); 93 | } 94 | else if(events[i].events & EPOLLIN) { 95 | if((sockfd = events[i].data.fd) < 0) continue; 96 | if((n = read(sockfd, line, MAXLINE)) < 0) { 97 | if(errno == ECONNRESET) { 98 | close(sockfd); 99 | events[i].data.fd = -1; 100 | } else { 101 | printf("readline error"); 102 | } 103 | } else if(n == 0) { 104 | close(sockfd); 105 | events[i].data.fd = -1; 106 | } 107 | 108 | printf("received data: %s\n", line); 109 | 110 | ev.data.fd = sockfd; 111 | ev.events = EPOLLOUT | EPOLLET; 112 | epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev); 113 | } 114 | else if(events[i].events & EPOLLOUT) { 115 | sockfd = events[i].data.fd; 116 | write(sockfd, line, n); 117 | 118 | printf("written data: %s\n", line); 119 | 120 | ev.data.fd = sockfd; 121 | ev.events = EPOLLIN | EPOLLET; 122 | epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev); 123 | } 124 | } 125 | } 126 | } 127 | --------------------------------------------------------------------------------