代码转载自:https://www.cnblogs.com/wanghao-boke/p/11443231.html
1 #include <cstdio>
2 #include <cstdlib>
3 #include <sys/epoll.h>
4 #include <sys/socket.h>
5 #include <arpa/inet.h>
6 #include <fcntl.h>
7 #include <cstring>
8 #include <ctime>
9 #include <unistd.h>
10 #include <errno.h>
11
12 #define MAX_EVENTS 2014
13 #define BUFLEN 4096
14 #define SERV_PORT 8080
15 #define SERV_ADDR "127.0.0.1"
16
17 void recvdata(int fd, int events, void *arg);
18 void senddata(int fd, int events, void *arg)
19
20 struct myevent_s
21 {
22 int fd;
23 int events;
24 void *arg;
25 void(*call_back)(int fd, int events, void *arg);
26 int status;
27 char buf[BUFLEN];
28 int len;
29 long last_active;
30 };
31
32 int g_efd;
33 struct myevent_s g_events[MAX_EVENTS+1];
34
35 void eventset(struct myevent_s *ev, int fd, void(*call_back)(int, int, void*), void *arg)
36 {
37 ev->fd = fd;
38 ev->call_back = call_back;
39 ev->events = 0;
40 ev->arg = arg;
41 ev->status = 0;
42 ev->last_active = time(NULL);
43 return;
44 }
45
46 void eventadd(int efd, int events, struct myevent_s *ev)
47 {
48 struct epoll_event epv = {0, {0}};
49 int op;
50 epv.data.ptr = ev;
51 epv.events = ev->events = events;
52
53 if(ev->status == 1) {
54 op = EPOLL_CTL_MOD;
55 } else {
56 op = EPOLL_CTL_ADD;
57 ev->status = 1;
58 }
59
60 if(epoll_ctl(efd, op, ev->fd, &epv) < 0) {
61 printf("event add failed [fd=%d],event[%d]\n", ev->fd, events);
62 } else {
63 printf("event add OK [fd = %d], event[%0X]\n", ev->fd, op, events);
64 }
65 return ;
66 }
67
68 void eventdel(int efd, struct myevent_s *ev)
69 {
70 struct epoll_event epv = {0, {0}};
71
72 if(ev->status != 1) {
73 return ;
74 }
75
76 epv.data.ptr = ev;
77 ev->status = 0;
78 epoll_ctl(efd, EPOLL_CTL_DEL, ev->fd, &epv);
79
80 return ;
81 }
82
83 void acceptconn(int lfd, int events, void *arg)
84 {
85 struct sockaddr_in cin;
86 socklen_t len = sizeof(cin);
87 int cfd, i;
88
89 if((cfd = accept(lfd, (struct sockaddr*)&cin, &len)) == -1) {
90 if(errno != EAGAIN && errno != EINTR) {
91 }
92 printf("%s : accept, %s \n", _func_, strerror(errno));
93 return ;
94 }
95
96 do {
97 for(i = 0; i < MAX_EVENTS; i++) {
98 if(g_events[i].status == 0) {
99 break;
100 }
101 }
102
103 if(i == MAX_EVENTS) {
104 printf("%s: max connect limit[%d]\n", _func_, MAX_EVENTS);
105 return ;
106 }
107
108 int flag = 0;
109 if((flag = fcntl(cfd, F_SETFL, O_NONBLOCK)) < 0) {
110 printf("%s: accept, %s \n", _func_, strerror(errno));
111 break;
112 }
113
114 eventset(&g_events[i], cfd, recvdata, &g_events[i];
115 eventadd(g_efd, EPOLLIN, &g_events[i]);
116 } while(0);
117
118 printf("new connect [%s:%d] [time:%ld], pos[%d]\n",
119 inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), g_events[i].last_active, i);
120 return;
121 }
122
123 void recvdata(int fd, int events, void *arg)
124 {
125 struct myevent_s *ev = (struct myevent_s *)arg;
126 int len;
127
128 len = recv(fd, ev->buf, sizeof(ev->buf), 0);
129
130 eventdel(g_efd, ev);
131
132 if(len > 0) {
133 ev->len = len;
134 ev->buf[len] = 0;
135 printf("C[%d]:%s\n", fd, ev->buf);
136
137 eventset(ev, fd, senddata, ev);
138 eventadd(g_efd, EPOLLOUT, ev);
139 } else if(len == 0) {
140 close(ev->fd);
141 printf("[fd = %d] pos[%ld], close\n", fd, ev-g_events);
142 } else {
143 close(ev->fd);
144 printf("recv[fd=%d] error[%d]:%s\n", fd, errno, strerror(errno));
145 }
146 return;
147 }
148
149 void senddata(int fd, int events, void *arg)
150 {
151 struct myevent_s *ev = (struct myevent_s *)arg;
152 itn len;
153
154 len = send(fd, ev->buf, ev->len, 0);
155
156 if(len > 0) {
157 printf("send[fd=%d], [%d]%s\n", fd, len, ev->bfu);
158 eventdel(g_efd, ev);
159 eventset(ev, fd, recvdata, ev);
160 eventadd(g_efd, EPOLLIN, ev);
161 } else {
162 close(ev->fd);
163 eventdel(g_efd, ev);
164 printf("send[fd=%d] error %s\n", fd, strerror(errno));
165 }
166 return;
167 }
168
169 void initlistensocket(int efd, short port)
170 {
171 int lfd = socket(AF_INET, SOCK_STREAM, 0);
172 fcntl(lfd, F_SETFL, O_NONBLOCK);
173
174 eventset(&g_events[MAX_EVENTS], lfd, acceptconn, &g_events[MAX_EVENTS]);
175 eventadd(efd, EPOLLIN, &g_events[MAX_EVENTS]);
176
177 struct sockaddr_in sin;
178 memset(&sin, 0, sizeof(sin));
179 sin.sin_addr.s_addr = INADDR_ANY;
180 sin.sin_family = AF_INET;
181 sin.sin_port = htons(port);
182
183 bind(lfd, (struct sockaddr*)&sin, sizeof(sin));
184 listen(lfd, 20);
185 return;
186 }
187
188 int main(int argc, char *argv[])
189 {
190 unsigned short port = SERV_PORT;
191
192 if(argc == 2)
193 port = atoi(argv[1]);
194
195 g_efd = epoll_create(MAX_EVENTS+1);
196 if(g_efd <= 0) {
197 printf("Create efd in %s error %s\n", _func_, strerror(errno));
198 }
199 initlistensocket(g_efd, port);
200
201 struct epoll_event events[MAX_EVENTS+1];
202 printf("server runnig:port[%d]\n", port);
203
204 int checkpos = 0, i;
205 while(1) {
206 long now = time(NULL);
207 for(i = 0; i < 100; i++, checkpos++) {
208 if(checkpos == MAX_EVENTS)
209 checkpos = 0;
210 if(g_events[checkpos].status != 1)
211 continue;
212
213 long duration = now - g_events[checkpos].last_active;
214
215 if(duration >= 60) {
216 close(g_events[checkpos].fd);
217 printf("[fd=%d] timeout\n", g_events[checkpos].fd);
218 eventdel(g_efd, &g_event[checkpos]);
219 }
220 }
221
222 int nfd = epoll_wait(g_efd, events, MAX_EVENTS+1, 1000);
223 if(nfd < 0) {
224 printf("epoll_wait error, exit\n");
225 break;
226 }
227
228 for(i = 0; i < nfd; i++) {
229 struct myevent_s *ev = (struct myevent_s*)events[i].data.ptr;
230 if((events[i].events & EPOLLIN) && (ev->events & EPOLLIN))
231 ev->call_back(ev->fd, events[i].events, ev->arg);
232 if((events[i].events & EPOLLOUT) && (ev->events & EPOLLOUT))
233 ev->call_back(ev->fd, events[i].events, ev->arg);
234 }
235 }
236 return 0;
237 }