int main(int argc, char* argv[]) { int lsocket = -1; //侦听套接字 int dsocket = -1; //连接套接字 ushort mix_socket[2]; memset(mix_socket, 0, sizeof(mix_socket)); P_EPOLL_STRUCT p_epoll = NULL; char buf[4096]; int cnt = 0; int ready = 0; // STAGE1, build local listen EXIT_IF_TRUE ( (lsocket = st_buildsocket(10, SERV_PORT)) == -1); st_make_nonblock(lsocket); EXIT_IF_TRUE( (p_epoll = st_make_events(lsocket, 64)) == NULL); st_print("SERVER prepared OK!\n"); int e_i = 0; while (TRUE) { ready = epoll_wait(p_epoll->event_fd, p_epoll->p_events, 64, 5000 /*5s*/); if (ready == -1) { SYS_ABORT("EPOLL_WAIT ERROR!\n"); } if( ready == 0) { st_print("PROCESS ALIVE!\n"); continue; } for (e_i = 0; e_i < ready; ++e_i) { if( (p_epoll->p_events[e_i].events & EPOLLERR) ) { st_d_error("Epoll Error!\n"); close(p_epoll->p_events[e_i].data.fd); continue; } if ( ( p_epoll->p_events[e_i].events & EPOLLHUP ) || ( p_epoll->p_events[e_i].events & EPOLLRDHUP) ) { st_d_error("Remote Disconnected!\n"); close(p_epoll->p_events[e_i].data.fd); continue; } if (p_epoll->p_events[e_i].data.fd == lsocket) { struct sockaddr in_addr; socklen_t in_len; dsocket = accept(lsocket, (struct sockaddr *) &in_addr, &in_len); if (dsocket == -1) { st_d_error("accept lsocket error!\n"); continue; } st_make_nonblock(dsocket); if (st_add_new_event(dsocket, p_epoll)) { st_d_error("Add socket:%d to event error!\n", dsocket); close(dsocket); dsocket = -1; //INVALID break; } st_print("Server accept new socket:%d\n", dsocket); if(mix_socket[0] == 0) mix_socket[0] = dsocket; else mix_socket[1] = dsocket; } else //数据转发部分 { if(p_epoll->p_events[e_i].data.fd == mix_socket[0]) { memset(buf, 0, sizeof(buf)); cnt = recv(mix_socket[0], buf, sizeof(buf), 0); if (cnt > 0) { //write(1, buf, cnt); send(mix_socket[1], buf, cnt, 0); } continue; } else if(p_epoll->p_events[e_i].data.fd == mix_socket[1]) { memset(buf, 0, sizeof(buf)); cnt = recv(mix_socket[1], buf, sizeof(buf), 0); if (cnt > 0) { //write(1, buf, cnt); send(mix_socket[0], buf, cnt, 0); } continue; } } } } st_print("PROCESS TERMINATED!\n"); return 0; }
void st_event_loop(P_EPOLL_STRUCT p_epoll, P_ST_THREAD_MANAGE p_manage, void* handler(void* data)) { if (!p_epoll) return; struct epoll_event* p_events = p_epoll->p_events; int listen_socket = p_epoll->event.data.fd; int e_i = 0; int ready = 0; for ( ; ; ) { ready = epoll_wait(p_epoll->event_fd, p_events, p_epoll->max_events, -1); for (e_i = 0; e_i < ready; e_i++) { if( (p_epoll->p_events[e_i].events & EPOLLERR) ) { st_d_print("Epoll Error!\n"); close(p_epoll->p_events[e_i].data.fd); continue; } if ( ( p_epoll->p_events[e_i].events & EPOLLHUP ) || ( p_epoll->p_events[e_i].events & EPOLLRDHUP) ) { st_d_print("Remote Disconnected!\n"); close(p_epoll->p_events[e_i].data.fd); continue; } if (listen_socket == p_events[e_i].data.fd) { /* 新链接到了(可能会有多个连接同时到来) */ while (1) { struct sockaddr in_addr; socklen_t in_len; int infd; char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; in_len = sizeof(struct sockaddr); infd = accept (listen_socket, &in_addr, &in_len); //非阻塞的Socket if (infd == -1) break; int sk = getnameinfo (&in_addr, in_len, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV); if (sk == 0) { st_print("Accept NEW Connect:[%d} " "(host=%s, port=%s)\n", infd, hbuf, sbuf); } if (st_add_new_event(infd, p_epoll)) { st_print("Add socket:%d to event error!\n", infd); break; } continue; //可能有多个连接 } } else { //有侦听的套接字发送数据的请求,添加你的处理 if (p_manage && handler) { st_threadpool_push_task(p_manage, handler, (void *)p_events[e_i].data.fd); //传值调用简单些! } #if 0 while (1) { ssize_t count; char buf[512]; count = read (p_events[e_i].data.fd, buf, sizeof(buf)); if (count == -1) { /* If errno == EAGAIN, that means we have read all data. So go back to the main loop. */ if (errno != EAGAIN) { perror ("read"); done = 1; } break; } else if (count == 0) { /* End of file. The remote has closed the connection. */ done = 1; break; } /* Write the buffer to standard output */ int s = write (1, buf, count); if (s == -1) { perror ("write"); abort (); } } if (done) { printf ("Closed connection on descriptor %d\n", p_events[e_i].data.fd); /* Closing the descriptor will make epoll remove it from the set of descriptors which are monitored. */ close (p_events[e_i].data.fd); } #endif } } } }