int main(void) { int i; int ifd; int len; int client_sock; struct online_user *user; Client client; struct sockaddr_in client_name; int client_name_len = sizeof(client_name); #define MAX_BUFSIZE 0x100000 char buf[MAX_BUFSIZE]; struct format *package = (struct format *)buf; tcp_server_sock = tcp_startup(SERVER_TCP_PORT); init_mysql(); register_ctrl_c(); kdpfd = epoll_create(MAXEPOLLSIZE); /* 设置要监听的事件。EPOLLIN 表示可读,EPOLLET则指定电平触发 */ ev.events = EPOLLIN; ev.data.fd = tcp_server_sock; if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, tcp_server_sock, &ev) < 0) /* 把 tcp sock 加入监听集合,以便接收连接请求 */ error_die("tcp epoll_ctl\n"); /* 记录监听的文件数,同时他也是 epoll_wait 的第三个参数。 因为内核需要知道 events 数组的有效数据有多长 */ curfds = 1; for (;;) { memset(buf,0,sizeof(buf)); printf("waiting...\n"); /* 等待有事件发生。该函数的返回值存放在 nfds 和 events 内 */ nfds = epoll_wait(kdpfd, events, curfds, -1); if (nfds < 0) error_die("epoll_wait"); for (i = 0; i < nfds; i++) { ifd = events[i].data.fd; if (ifd == tcp_server_sock) { //新的 TCP 连接请求到来 if (!(events[i].events & EPOLLIN)) error_die("failed to event is not EPOLLIN\n"); client_sock = accept(tcp_server_sock,(struct sockaddr *)&client_name,&client_name_len); setnonblocking(client_sock); ev.events = EPOLLIN; ev.data.fd = client_sock; if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, client_sock, &ev) < 0) error_die("epoll_ctl"); curfds++; client = alloc_client(client_sock); add_client(client); } else if ((events[i].events & EPOLLIN)) { /* 客户端有数据发来(POLLIN)或者发生 POLLHUP/POLLERR(这两个事件系统会自动监听) */ client = find_client(ifd); if (client != NULL && client->handler != NULL) { //已经有了处理函数,直接调用这个函数来处理 client->handler(ifd,client->private); } else { //默认的处理方法 //读入数据包头部。 len = read(ifd,package,(sizeof(struct format)-sizeof(package->data))); if (len <= 0) { //对方断线。 close_connect(ifd); continue; } if (package->length >= MAX_BUFSIZE || package->length <= 0) { while(read(ifd,package->data,4) > 0); continue; } if ((len = read(ifd,package->data,package->length) <= 0)) { //读入数据包内容 close_connect(ifd); continue; } // 处理数据 if (handle(ifd,package) == NEED_WRITE) { ev.events = EPOLLOUT; ev.data.fd = ifd; epoll_ctl(kdpfd,EPOLL_CTL_MOD,ifd,&ev); } } } else if(events[i].events & EPOLLOUT) {
int main (int argc, char *argv[]) { ASLogger *logger; int stdin_handle; input_id stdinput; #ifdef WIN32 HANDLE hThread; int fds[2]; #endif /* winsock init */ tcp_startup (); /* setup logging */ logger = as_logger_create (); as_logger_add_output (logger, "stderr"); as_logger_add_output (logger, "ares.log"); AS_DBG ("Logging subsystem started"); /* setup event system */ as_event_init (); /* init lib */ if (!as_init ()) { printf ("FATA: as_init() failed\n"); exit (1); } #ifdef WIN32 /* create console reading thread on windows */ if (socketpair (0, 0, 0, fds) < 0) { printf ("FATAL: socketpair() failed\n"); exit (1); } stdin_handle = fds[1]; hThread = (HANDLE) _beginthreadex (NULL, 0, console_input_func, (void *)fds[0], 0, NULL); if (hThread == (HANDLE) -1 || hThread == (HANDLE) 0) { printf ("FATAL: couldn't start input thread\n"); exit (1); } #else stdin_handle = 0; #endif /* add callback for command handling */ stdinput = input_add (stdin_handle, NULL, INPUT_READ, stdin_cb, 0); #if 0 /* print prompt */ printf ("> "); #endif /* run event loop */ AS_DBG ("Entering event loop"); as_event_loop (); AS_DBG ("Left event loop"); input_remove (stdinput); #if WIN32 /* terminate thread if it is still running and close thread handle */ TerminateThread (hThread, 0); CloseHandle (hThread); #endif /* cleanup lib */ as_cleanup (); /* shutdown */ as_event_shutdown (); as_logger_free (logger); /* winsock shutdown */ tcp_cleanup (); return 0; }