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 "); 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 "); 47 return -1; 48 } 49 //正常listen 50 if(listen(sd, SOMAXCONN) < 0) 51 { 52 printf("listen error "); 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] ", 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 "); 86 return ; 87 } 88 89 if(EV_ERROR & revents) 90 { 91 printf("error event in accept "); 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 "); 100 return; 101 } 102 //如果连接数超出指定范围,则关闭连接 103 if( client_sd > MAX_ALLOWED_CLIENT) 104 { 105 printf("fd too large[%d] ", 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] ", client_sd); 113 return ; 114 } 115 116 printf("client connected "); 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 "); 133 return ; 134 } 135 //正常的recv 136 read = recv(watcher->fd, buffer, BUFFER_SIZE, 0); 137 if(read < 0) 138 { 139 printf("read error "); 140 return; 141 } 142 143 if(read == 0) 144 { 145 printf("client disconnected. "); 146 //ev_io_stop(loop, watcher); 147 //free(watcher); 148 //如果客户端断开连接,释放响应的资源,并且关闭监听 149 freelibev(loop, watcher->fd); 150 return; 151 } 152 else 153 { 154 //buffer[read] = ' '; 155 printf("receive message:%s ", 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] ", 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 }