int tcp_server_run(tcp_server_t *server) { struct epoll_event *events = NULL; tcp_server_stream_t *stream = NULL; int nfds = 0; int i = 0; if (NULL == server) { log_error("server is NULL."); return 0; } events = (struct epoll_event *)malloc(sizeof(struct epoll_event) * server->stream_num); if (NULL == events) { log_error("malloc for events failed."); return 0; } while (!server->stop) { nfds = epoll_wait(server->epoll_fd, events, server->stream_num, TCP_EPOLL_TIMEOUT); if (nfds < 0) { log_error("epoll_wait error, %s.", strerror(errno)); return 0; } for (i = 0; i < nfds; i++) { stream = (tcp_server_stream_t *)events[i].data.ptr; if (NULL == stream) { log_error("events[%d].data.ptr is NULL", i); continue; } if (events[i].events & EPOLLIN && stream->rcv_cb) { stream->rcv_cb(stream); } else if (events[i].events & EPOLLOUT && stream->snd_cb) { stream->snd_cb(stream); } else if ((events[i].events & EPOLLERR)) { log_error("epoll event has error, remote ip: %s", inet_ntoa(stream->remote_addr.sin_addr)); stream->error = 1; } else if (events[i].events & EPOLLHUP) { log_warn("epoll event has EPOLLHUP, remote ip: %s", inet_ntoa(stream->remote_addr.sin_addr)); } else { log_error("epoll event unknown flags, %s.", inet_ntoa(stream->remote_addr.sin_addr)); } if (stream->error || stream->close) { tcp_stream_close(stream); server->active_stream_num--; } } } return 1; }
static int accept_cb(tcp_server_stream_t *listen_stream) { struct sockaddr_in remote_addr; struct epoll_event event; socklen_t addr_len; int sock_fd; tcp_server_t *server; tcp_server_stream_t *stream; bzero(&remote_addr, sizeof(remote_addr)); addr_len = sizeof(struct sockaddr_in); sock_fd = accept(listen_stream->sock_fd, (struct sockaddr *)&remote_addr, &addr_len); if (sock_fd < 0) { if (EAGAIN != errno) { log_error("accept error, %s.", strerror(errno)); return 0; } else { log_info("no connection for accept."); return 1; } } log_debug("new connection comes, fd: %d.", sock_fd); if (!set_non_blocking(sock_fd)) { log_error("set sock_fd: %d failed.", sock_fd); close(sock_fd); return 0; } stream = get_idle_tcp_stream(server); if (NULL == stream) { log_error("no idle stream."); return 0; } tcp_stream_init(server, stream, sock_fd, &remote_addr); add_stream_into_busy_list(server, stream); /* 将当前sock fd添加到epoll中 */ bzero(&event, sizeof(event)); event.data.fd = sock_fd; event.data.ptr = stream; event.events = EPOLLIN | EPOLLET; if (epoll_ctl(server->epoll_fd, EPOLL_CTL_ADD, sock_fd, &event) < 0) { log_error("accept_cb, EPOLL_CTL_ADD error, %s.", strerror(errno)); tcp_stream_close(stream); return 0; } server->active_stream_num++; return 1; }
int tcp_client_run(tcp_client_t *client) { struct epoll_event *events = NULL; tcp_client_stream_t *stream = NULL; int nfds = 0; int i = 0; if (NULL == client) { log_error("client is NULL."); return 0; } events = (struct epoll_event *)malloc(sizeof(struct epoll_event) * client->stream_num); if (NULL == events) { log_error("malloc for events failed."); return 0; } while (!client->stop) { nfds = epoll_wait(client->epoll_fd, events, client->stream_num, TCP_EPOLL_TIMEOUT); if (nfds < 0) { log_error("epoll_wait error, %s.", strerror(errno)); return 0; } for (i = 0; i < nfds; i++) { stream = (tcp_client_stream_t *)events[i].data.ptr; if (NULL == stream) { log_error("events[%d].data.ptr is NULL", i); continue; } if (events[i].events & EPOLLIN && stream->rcv_cb) { stream->rcv_cb(stream); } else if (events[i].events & EPOLLOUT && stream->snd_cb) { stream->snd_cb(stream); } else if ((events[i].events & EPOLLERR)) { stream->error = 1; } else if (events[i].events & EPOLLHUP) { } else { } if (stream->error || stream->close) { tcp_stream_close(stream); client->active_stream_num--; } } } return 1; }