epoll测试
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 <errno.h> 8 #include <iostream> 9 #include <cstring> 10 #include <cstdlib> 11 12 using namespace std; 13 14 #define MAX_EVENTS 1000 15 16 struct RP_EVENT_S 17 { 18 int fd; 19 void (*call_back)(int fd, int events, void* args); 20 int events; 21 void* args; 22 int status; // 1 in epoll wait list, 0 not in 23 char buff[128]; 24 int len, s_offset; 25 long last_active; 26 }; 27 28 void EventSet(RP_EVENT_S* ev, int fd, void (*call_back)(int, int, void*), void* arg) 29 { 30 ev->fd = fd; 31 ev->call_back = call_back; 32 ev->args = arg; 33 ev->status = 0; 34 bzero(ev->buff, sizeof(ev->buff)); 35 ev->s_offset = 0; 36 ev->len = 0; 37 ev->last_active = time(NULL); 38 } 39 40 void EventAdd(int epoll_fd, int events, RP_EVENT_S* ev) 41 { 42 struct epoll_event epv = {0, {0}}; 43 int op; 44 epv.data.ptr = ev; 45 epv.events = ev->events = events; 46 47 if (1 == ev->status) 48 { 49 op = EPOLL_CTL_MOD; 50 } 51 else { 52 op = EPOLL_CTL_ADD; 53 ev->status = 1; 54 } 55 56 if (epoll_ctl(epoll_fd, op, ev->fd, &epv) < 0) 57 { 58 std::cerr << "Event Add Failed [fd = " << ev->fd << "], events = " << events << std::endl; 59 } 60 else 61 { 62 // std::cout << "Event Add OK [fd = " << ev->fd << "], events = " << events << std::endl; 63 } 64 } 65 66 void EventDel(int epoll_fd, RP_EVENT_S* ev) 67 { 68 struct epoll_event epv = {0, {0}}; 69 if (1 != ev->status) 70 { 71 return; 72 } 73 epv.data.ptr = ev; 74 ev->status = 0; 75 epoll_ctl(epoll_fd, EPOLL_CTL_DEL, ev->fd, &epv); 76 } 77 78 int g_epoll_fd; 79 RP_EVENT_S g_Events[MAX_EVENTS + 1]; 80 81 void RecvData(int fd, int events, void* args); 82 void SendData(int fd, int events, void* args); 83 84 void AcceptConn(int fd, int events, void* args) 85 { 86 struct sockaddr_in sin; 87 socklen_t len = sizeof(sin); 88 89 int nfd, i; 90 if ((nfd = accept(fd, (struct sockaddr*)&sin, &len)) == -1) 91 { 92 if (EAGAIN != errno && EINTR != errno) 93 { 94 95 } 96 std::cerr << __func__ << ": accept error. " << errno << std::endl; 97 return; 98 } 99 100 do 101 { 102 103 for (i=0;i<MAX_EVENTS;++i) 104 { 105 if (g_Events[i].status == 0) 106 { 107 break ; 108 } 109 } 110 std::cout << "connection: " << i << std::endl; 111 112 if (MAX_EVENTS == i) 113 { 114 std::cerr << __func__ << ": Max connection limit. LIMIT = " << MAX_EVENTS << std::endl; 115 break ; 116 } 117 118 int iret = 0; 119 if ((iret = fcntl(nfd, F_SETFL, O_NONBLOCK)) < 0) 120 { 121 std::cerr << __func__ << ": fcntl nonblocking failed: " << iret << std::endl; 122 break ; 123 } 124 125 EventSet(&g_Events[i], nfd, RecvData, &g_Events[i]); 126 EventAdd(g_epoll_fd, EPOLLIN, &g_Events[i]); 127 } 128 while (0); 129 130 // std::cout << "new connection [" << inet_ntoa(sin.sin_addr) << ":" << ntohs(sin.sin_port) << 131 // "], pos = " << i << std::endl; 132 } 133 134 void RecvData(int fd, int events, void* args) 135 { 136 struct RP_EVENT_S* ev = (struct RP_EVENT_S*)args; 137 const char* str = "Hello world"; 138 int len = 0; 139 len = recv(fd, ev->buff+ev->len, sizeof(ev->buff) - 1 - ev->len, 0); 140 EventDel(g_epoll_fd, ev); 141 142 if (len > 0) 143 { 144 ev->len += len; 145 // ev->buff[ev->len] = '\0'; 146 // std::cout << "C[" << fd << "]:" << ev->buff << std::endl; 147 //EventSet(ev, fd, SendData, ev); 148 //memcpy((void*)str, ev->buff, strlen(str)); 149 //ev->len = strlen(str); 150 ev->call_back = SendData; 151 EventAdd(g_epoll_fd, EPOLLOUT, ev); 152 } 153 else if (0 == len) 154 { 155 close(ev->fd); 156 // std::cout << "[fd=" << fd << "] , closed gracefully." << std::endl; 157 } 158 else 159 { 160 close(ev->fd); 161 std::cerr << "recv[fd=" << fd << "] error[" << errno << "]: " << strerror(errno) << std::endl; 162 } 163 } 164 165 166 void SendData(int fd, int events, void* args) 167 { 168 struct RP_EVENT_S* ev = (struct RP_EVENT_S*)args; 169 170 int len; 171 len = send(fd, ev->buff + ev->s_offset, ev->len - ev->s_offset, 0); 172 173 if (len > 0) 174 { 175 // std::cout << "send[fd=" << fd << "], [" << len << "<->" << ev->len, ev->buff; 176 ev->s_offset += len; 177 if (ev->s_offset == ev->len) 178 { 179 EventDel(g_epoll_fd, ev); 180 EventSet(ev, fd, RecvData, ev); 181 EventAdd(g_epoll_fd, EPOLLIN, ev); 182 } 183 } 184 else 185 { 186 close(ev->fd); 187 EventDel(g_epoll_fd, ev); 188 std::cerr << "Send[fd=" << fd << "] errno[" << errno << "]" << std::endl; 189 } 190 } 191 192 void InitListenSocket(int epoll_fd, short port) 193 { 194 int listen_fd = socket(AF_INET, SOCK_STREAM, 0); 195 fcntl(listen_fd, F_SETFL, O_NONBLOCK); 196 std::cout << "server listen fd = " << listen_fd << std::endl; 197 EventSet(&g_Events[MAX_EVENTS], listen_fd, AcceptConn, &g_Events[MAX_EVENTS]); 198 199 EventAdd(epoll_fd, EPOLLIN, &g_Events[MAX_EVENTS]); 200 201 sockaddr_in sin; 202 bzero(&sin, sizeof(sin)); 203 204 sin.sin_family = AF_INET; 205 sin.sin_addr.s_addr = INADDR_ANY; 206 sin.sin_port = htons(port); 207 bind(listen_fd, (const sockaddr*)&sin, sizeof(sin)); 208 listen(listen_fd, 5); 209 } 210 211 int main(int argc, char *argv[]) 212 { 213 unsigned short port = 12345; 214 if (2 == argc) 215 { 216 port = atoi(argv[1]); 217 } 218 219 g_epoll_fd = epoll_create(MAX_EVENTS); 220 if (0 >= g_epoll_fd) 221 { 222 std::cerr << "create epoll failed." << std::endl; 223 return -1; 224 } 225 226 InitListenSocket(g_epoll_fd, port); 227 228 struct epoll_event events[MAX_EVENTS]; 229 230 int check_pos = 0; 231 while (1) 232 { 233 long now = time(NULL); 234 for (int i=0;i<100;++i, check_pos++) 235 { 236 if (check_pos == MAX_EVENTS) check_pos = 0; 237 238 if (g_Events[check_pos].status != 1) 239 { 240 continue ; 241 } 242 243 long duration = now - g_Events[check_pos].last_active; 244 245 if (duration >= 60) 246 { 247 close(g_Events[check_pos].fd); 248 std::cout << "[fd=" << g_Events[check_pos].fd << "] timeout" << std::endl; 249 EventDel(g_epoll_fd, &g_Events[check_pos]); 250 } 251 } 252 253 int fds = epoll_wait(g_epoll_fd, events, MAX_EVENTS, 1000); 254 if (fds < 0) 255 { 256 std::cerr << "epoll wait error. exit" << std::endl; 257 break; 258 } 259 260 for (int i=0;i<fds;++i) 261 { 262 RP_EVENT_S* ev = (struct RP_EVENT_S*)events[i].data.ptr; 263 if ((events[i].events & EPOLLIN) && (ev->events & EPOLLIN) ) 264 { 265 ev->call_back(ev->fd, events[i].events, ev->args); 266 } 267 if ((events[i].events & EPOLLOUT) && (ev->events & EPOLLOUT) ) 268 { 269 ev->call_back(ev->fd, events[i].events, ev->args); 270 } 271 } 272 } 273 return 0; 274 }
client
1 -module(client). 2 -export([start/0, start/1]). 3 4 start() -> 5 test("127.0.0.1", 12345, "Hello world"). 6 7 start(N) -> 8 tests_spawn("127.0.0.1", 12345, "Hello world", N). 9 10 11 loop_send_recv(Socket, Str) -> 12 ok = gen_tcp:send(Socket, term_to_binary(Str)), 13 receive 14 {tcp, Socket, Bin} -> 15 %io:format("client reveived binary = ~p~n", [Bin]), 16 Val = binary_to_term(Bin), 17 if 18 Val /= Str -> 19 io:format("recv error ~p~n", [Val]); 20 true -> 21 TEMP = 1 22 end 23 %io:format("client result=~p~n", [Val]) 24 %gen_tcp:close(Socket) 25 end, 26 loop_send_recv(Socket, Str). 27 28 test(Ip, Port, Str) -> 29 {ok, Socket} = gen_tcp:connect(Ip, Port, [binary, {packet, 4}]), 30 loop_send_recv(Socket, Str). 31 32 33 tests_spawn(Ip, Port, Str, 1) -> 34 spawn(fun() -> test(Ip, Port, Str) end); 35 tests_spawn(Ip, Port, Str, N) -> 36 spawn(fun() -> test(Ip, Port, Str) end), 37 tests_spawn(Ip, Port, Str, N-1).