(转载)epoll 反应堆模型代码

代码转载自: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 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值