├── README.md ├── epoll_client.cpp ├── epoll_server.cpp └── utility.h /README.md: -------------------------------------------------------------------------------- 1 | # epoll 2 | 3 | 相比非阻塞忙轮询这类无差别轮训,linux内核提供了epoll这样更高级的形式 4 | 把需要处理的IO事件添加到epoll内核列表,epoll_wait来监控并提醒用户程序当IO事件发生时 5 | 6 | 7 | 此聊天室客户端代码fork两个进程,子进程把用户输入写入到pipe,父进程读pipe发给服务端同时监控服务端的消息并广播 8 | -------------------------------------------------------------------------------- /epoll_client.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwzh222/epoll/f139a3927a86c84d225c1ae0e9aed240d97d5185/epoll_client.cpp -------------------------------------------------------------------------------- /epoll_server.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jwzh222/epoll/f139a3927a86c84d225c1ae0e9aed240d97d5185/epoll_server.cpp -------------------------------------------------------------------------------- /utility.h: -------------------------------------------------------------------------------- 1 | #ifndef UTILITY_H_INCLUDED 2 | #define UTILITY_H_INCLUDED 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | using namespace std; 19 | 20 | // clients_list save all the clients's socket 21 | list clients_list; 22 | 23 | /********************** macro defintion **************************/ 24 | // server ip 25 | #define SERVER_IP "127.0.0.1" 26 | 27 | // server port 28 | #define SERVER_PORT 8888 29 | 30 | //epoll size 31 | #define EPOLL_SIZE 5000 32 | 33 | //message buffer size 34 | #define BUF_SIZE 0xFFFF 35 | 36 | #define SERVER_WELCOME "Welcome you join to the chat room! Your chat ID is: Client #%d" 37 | 38 | #define SERVER_MESSAGE "ClientID %d say >> %s" 39 | 40 | // exit 41 | #define EXIT "EXIT" 42 | 43 | #define CAUTION "There is only one int the char room!" 44 | 45 | /********************** some function **************************/ 46 | /** 47 | * @param sockfd: socket descriptor 48 | * @return 0 49 | **/ 50 | int setnonblocking(int sockfd) 51 | { 52 | fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0)| O_NONBLOCK); 53 | return 0; 54 | } 55 | 56 | /** 57 | * @param epollfd: epoll handle 58 | * @param fd: socket descriptor 59 | * @param enable_et : enable_et = true, epoll use ET; otherwise LT 60 | **/ 61 | void addfd( int epollfd, int fd, bool enable_et ) 62 | { 63 | struct epoll_event ev; 64 | ev.data.fd = fd; 65 | ev.events = EPOLLIN; 66 | if( enable_et ) 67 | ev.events = EPOLLIN | EPOLLET; 68 | epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev); 69 | setnonblocking(fd); 70 | printf("fd added to epoll!\n\n"); 71 | } 72 | 73 | /** 74 | * @param clientfd: socket descriptor 75 | * @return : len 76 | **/ 77 | int sendBroadcastmessage(int clientfd) 78 | { 79 | // buf[BUF_SIZE] receive new chat message 80 | // message[BUF_SIZE] save format message 81 | char buf[BUF_SIZE], message[BUF_SIZE]; 82 | bzero(buf, BUF_SIZE); 83 | bzero(message, BUF_SIZE); 84 | 85 | // receive message 86 | printf("read from client(clientID = %d)\n", clientfd); 87 | int len = recv(clientfd, buf, BUF_SIZE, 0); 88 | 89 | if(len <= 0) // len = 0 means the client closed connection 90 | { 91 | close(clientfd); 92 | clients_list.remove(clientfd); //server remove the client 93 | printf("ClientID = %d closed.\n now there are %d client in the char room\n", clientfd, (int)clients_list.size()); 94 | 95 | } 96 | else //broadcast message 97 | { 98 | if(clients_list.size() == 1) { // this means There is only one int the char room 99 | send(clientfd, CAUTION, strlen(CAUTION), 0); 100 | return len; 101 | } 102 | // format message to broadcast 103 | sprintf(message, SERVER_MESSAGE, clientfd, buf); 104 | 105 | list::iterator it; 106 | for(it = clients_list.begin(); it != clients_list.end(); ++it) { 107 | if(*it != clientfd){ 108 | if( send(*it, message, BUF_SIZE, 0) < 0 ) { perror("error"); exit(-1);} 109 | } 110 | } 111 | } 112 | return len; 113 | } 114 | #endif // UTILITY_H_INCLUDED 115 | --------------------------------------------------------------------------------