server:
1 #include <sys/socket.h> 2 #include <sys/epoll.h> 3 #include <netinet/in.h> 4 #include <arpa/inet.h> 5 #include <fcntl.h> 6 #include <unistd.h> 7 #include <stdio.h> 8 #include <errno.h> 9 #include <iostream> 10 #include <string.h> 11 #include <stdlib.h> 12 using namespace std; 13 #define MAX_EVENTS 500 14 struct myevent_s 15 { 16 int fd; 17 void (*call_back)(int fd, int events, void *arg); 18 int events; 19 void *arg; 20 int status; // 1: in epoll wait list, 0 not in 21 char buff[128]; // recv data buffer 22 int len, s_offset; 23 long last_active; // last active time 24 }; 25 // set event 26 void EventSet(myevent_s *ev, int fd, void (*call_back)(int, int, void*), void *arg) 27 { 28 ev->fd = fd; 29 ev->call_back = call_back; 30 ev->events = 0; 31 ev->arg = arg; 32 ev->status = 0; 33 bzero(ev->buff, sizeof(ev->buff)); 34 ev->s_offset = 0; 35 ev->len = 0; 36 ev->last_active = time(NULL); 37 } 38 // add/mod an event to epoll 39 void EventAdd(int epollFd, int events, myevent_s *ev) 40 { 41 struct epoll_event epv = {0, {0}}; 42 int op; 43 epv.data.ptr = ev; 44 epv.events = ev->events = events; 45 if(ev->status == 1){ 46 op = EPOLL_CTL_MOD; 47 } 48 else{ 49 op = EPOLL_CTL_ADD; 50 ev->status = 1; 51 } 52 if(epoll_ctl(epollFd, op, ev->fd, &epv) < 0) 53 printf("Event Add failed[fd=%d], evnets[%d] ", ev->fd, events); 54 else 55 printf("Event Add OK[fd=%d], op=%d, evnets[%0X] ", ev->fd, op, events); 56 } 57 // delete an event from epoll 58 void EventDel(int epollFd, myevent_s *ev) 59 { 60 struct epoll_event epv = {0, {0}}; 61 if(ev->status != 1) return; 62 epv.data.ptr = ev; 63 ev->status = 0; 64 epoll_ctl(epollFd, EPOLL_CTL_DEL, ev->fd, &epv); 65 } 66 int g_epollFd; 67 myevent_s g_Events[MAX_EVENTS+1]; // g_Events[MAX_EVENTS] is used by listen fd 68 void RecvData(int fd, int events, void *arg); 69 void SendData(int fd, int events, void *arg); 70 // accept new connections from clients 71 void AcceptConn(int fd, int events, void *arg) 72 { 73 struct sockaddr_in sin; 74 socklen_t len = sizeof(struct sockaddr_in); 75 int nfd, i; 76 // accept 77 if((nfd = accept(fd, (struct sockaddr*)&sin, &len)) == -1) 78 { 79 if(errno != EAGAIN && errno != EINTR) 80 { 81 } 82 printf("%s: accept, %d", __func__, errno); 83 return; 84 } 85 do 86 { 87 for(i = 0; i < MAX_EVENTS; i++) 88 { 89 if(g_Events[i].status == 0) 90 { 91 break; 92 } 93 } 94 if(i == MAX_EVENTS) 95 { 96 printf("%s:max connection limit[%d].", __func__, MAX_EVENTS); 97 break; 98 } 99 // set nonblocking 100 int iret = 0; 101 if((iret = fcntl(nfd, F_SETFL, O_NONBLOCK)) < 0) 102 { 103 printf("%s: fcntl nonblocking failed:%d", __func__, iret); 104 break; 105 } 106 // add a read event for receive data 107 EventSet(&g_Events[i], nfd, RecvData, &g_Events[i]); 108 EventAdd(g_epollFd, EPOLLIN, &g_Events[i]); 109 }while(0); 110 printf("new conn[%s:%d][time:%d], pos[%d] ", inet_ntoa(sin.sin_addr), 111 ntohs(sin.sin_port), g_Events[i].last_active, i); 112 } 113 // receive data 114 void RecvData(int fd, int events, void *arg) 115 { 116 struct myevent_s *ev = (struct myevent_s*)arg; 117 int len; 118 // receive data 119 len = recv(fd, ev->buff+ev->len, sizeof(ev->buff)-1-ev->len, 0); 120 EventDel(g_epollFd, ev); 121 if(len > 0) 122 { 123 ev->len += len; 124 ev->buff[ev->len] = '