1 #include <ev.h>
2 #include <stdio.h>
3 #include <netinet/in.h>
4 #include <stdlib.h>
5 #include <string.h>
6
7 #define PORT 6666
8 #define BUFFER_SIZE 2048
9 #define MAX_ALLOWED_CLIENT 10240
10
11 struct ev_io *libevlist[MAX_ALLOWED_CLIENT] = {NULL};
12
13 void accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents);
14
15 void read_cb(struct ev_loop *loop, struct ev_io *watcher, int revents);
16
17 void timer_beat(struct ev_loop *loop, struct ev_timer *watcher, int revents);
18
19 int freelibev(struct ev_loop *loop, int fd);
20
21
22 int main()
23 {
24 struct ev_loop *loop=ev_default_loop(0);
25 int sd;
26 struct sockaddr_in addr;
27 int addr_len = sizeof(addr);
28
29 //创建一个io watcher和一个timer watcher
30 struct ev_io socket_accept;
31 struct ev_timer timeout_w;
32 //创建socket连接
33 sd = socket(PF_INET, SOCK_STREAM, 0);
34 if(sd < 0)
35 {
36 printf("socket error\n");
37 return -1;
38 }
39 bzero(&addr, sizeof(addr));
40 addr.sin_family = AF_INET;
41 addr.sin_port = htons(PORT);
42 addr.sin_addr.s_addr = INADDR_ANY;
43 //正常bind
44 if(bind(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0)
45 {
46 printf("bind error\n");
47 return -1;
48 }
49 //正常listen
50 if(listen(sd, SOMAXCONN) < 0)
51 {
52 printf("listen error\n");
53 return -1;
54 }
55 //设置fd可重用
56 int bReuseaddr=1;
57 if(setsockopt(sd,SOL_SOCKET ,SO_REUSEADDR,(const char*)&bReuseaddr,sizeof(bReuseaddr)) != 0)
58 {
59 printf("setsockopt error in reuseaddr[%d]\n", sd);
60 return ;
61 }
62
63 //初始化io watcher,用于监听fd
64 ev_io_init(&socket_accept, read_cb, sd, EV_READ);
65 ev_io_start(loop, &socket_accept);
66
67 ev_run(loop, 0);
68
69 return 1;
70 }
71
72 void accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
73 {
74
75 // 如果有链接,则继续监听fd;
76
77 struct sockaddr_in client_addr;
78 socklen_t client_len = sizeof(client_addr);
79 int client_sd;
80 //创建客户端的io watcher
81 struct ev_io *w_client = (struct ev_io*) malloc(sizeof(struct ev_io));
82
83 if(w_client == NULL)
84 {
85 printf("malloc error in accept_cb\n");
86 return ;
87 }
88
89 if(EV_ERROR & revents)
90 {
91 printf("error event in accept\n");
92 return ;
93 }
94
95 //获取与客户端相连的fd
96 client_sd = accept(watcher->fd, (struct sockaddr*)&client_addr, &client_len);
97 if(client_sd < 0)
98 {
99 printf("accept error\n");
100 return;
101 }
102 //如果连接数超出指定范围,则关闭连接
103 if( client_sd > MAX_ALLOWED_CLIENT)
104 {
105 printf("fd too large[%d]\n", client_sd);
106 close(client_sd);
107 return ;
108 }
109
110 if(libevlist[client_sd] != NULL)
111 {
112 printf("client_sd not NULL fd is [%d]\n", client_sd);
113 return ;
114 }
115
116 printf("client connected\n");
117 //监听新的fd
118 ev_io_init(w_client, read_cb, client_sd, EV_READ);
119 ev_io_start(loop, w_client);
120
121 libevlist[client_sd] = w_client;
122
123 }
124
125 void read_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
126 {
127 char buffer[BUFFER_SIZE];
128 ssize_t read;
129
130 if(EV_ERROR & revents)
131 {
132 printf("error event in read\n");
133 return ;
134 }
135 //正常的recv
136 read = recv(watcher->fd, buffer, BUFFER_SIZE, 0);
137 if(read < 0)
138 {
139 printf("read error\n");
140 return;
141 }
142
143 if(read == 0)
144 {
145 printf("client disconnected.\n");
146 //ev_io_stop(loop, watcher);
147 //free(watcher);
148 //如果客户端断开连接,释放响应的资源,并且关闭监听
149 freelibev(loop, watcher->fd);
150 return;
151 }
152 else
153 {
154 //buffer[read] = '\0';
155 printf("receive message:%s\n", buffer);
156 }
157 //返回给客户端
158 send(watcher->fd, buffer, read, 0);
159 bzero(buffer, read);
160 }
161
162 int freelibev(struct ev_loop *loop, int fd)
163 {
164 //清理相关资源
165
166 if(libevlist[fd] == NULL)
167 {
168 printf("the fd already freed[%d]\n", fd);
169 return -1;
170 }
171
172 close(fd);
173 ev_io_stop(loop, libevlist[fd]);
174 free(libevlist[fd]);
175 libevlist[fd] = NULL;
176 return 1;
177 }