From 94e667b05dfed5912a4bda9c629247bb72723e27 Mon Sep 17 00:00:00 2001 From: Johnny Richard Date: Sat, 9 Apr 2022 03:23:08 +0200 Subject: server.c: Polish socket io data management --- server.c | 156 ++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 85 insertions(+), 71 deletions(-) (limited to 'server.c') diff --git a/server.c b/server.c index f2d66cc..72699ef 100644 --- a/server.c +++ b/server.c @@ -30,6 +30,9 @@ #define BUFFER_SIZE 1024 #define EXIT_COMMAND "exit" +static void server_handle_client_data(server_t *server, struct epoll_event *event); +static void server_handle_server_data(server_t *server, struct epoll_event *event); + server_t server_create(uint32_t port) { @@ -87,9 +90,6 @@ server_create(uint32_t port) void server_start(server_t *server) { - struct sockaddr_in client; - socklen_t client_len = sizeof(client); - server->running = true; while (server->running) { @@ -105,75 +105,10 @@ server_start(server_t *server) } for (int i = 0; i < event_count; ++i) { - int sockfd = server->events[i].data.fd; - if (sockfd == server->fd) { - int client_fd = accept(server->fd, (struct sockaddr *) &client, &client_len); - if (client_fd == -1) { - log_error("could not accept connection: %s", strerror(errno)); - close(server->fd); - exit(EXIT_FAILURE); - } - - struct epoll_event event; - event.events = EPOLLIN; - event.data.fd = client_fd; - - if (epoll_ctl(server->epoll_fd, EPOLL_CTL_ADD, client_fd, &event) == -1) { - log_error("could not add server to epoll: %s", strerror(errno)); - exit(EXIT_FAILURE); - } - - int j = 0; - while (server->connected_clients[j] != -1 && j < MAXEVENTS) { - j++; - } - log_trace("j = %d, MAXEVENTS = %d", j, MAXEVENTS); - - if (j < MAXEVENTS) { - server->connected_clients[j] = client_fd; - } else { - log_warn("max number of connection has been reached"); - } + if (server->events[i].data.fd == server->fd) { + server_handle_server_data(server, &server->events[i]); } else { - int client_fd = sockfd; - if (server->events[i].events & EPOLLHUP) { - for (int j = 0; j < MAXEVENTS; ++j) { - if (server->connected_clients[j] == client_fd) { - server->connected_clients[j] = -1; - break; - } - } - continue; - } - char client_buf[BUFFER_SIZE]; - memset(client_buf, 0, BUFFER_SIZE); - - if (recv(client_fd, client_buf, BUFFER_SIZE, 0) == -1) { - log_error("could not read data from client: %s", strerror(errno)); - continue; - } - - if (!strncasecmp(client_buf, EXIT_COMMAND, strlen(EXIT_COMMAND) - 1)) { - log_info("exiting program. bye bye!"); - close(client_fd); - close(server->fd); - exit(EXIT_SUCCESS); - } - - for (int j = 0; j < MAXEVENTS; ++j) { - if (server->connected_clients[j] == -1) { - continue; - } - - char message[BUFFER_SIZE]; - memset(message, 0, sizeof(char) * BUFFER_SIZE); - - sprintf(message, "client_%d :%s", client_fd, client_buf); - if (send(server->connected_clients[j], message, BUFFER_SIZE, 0) == -1) { - log_error("could not send data to client: %s", strerror(errno)); - continue; - } - } + server_handle_client_data(server, &server->events[i]); } } } @@ -181,3 +116,82 @@ server_start(server_t *server) close(server->fd); exit(EXIT_SUCCESS); } + +static void +server_handle_server_data(server_t *server, struct epoll_event *event) +{ + struct sockaddr_in client; + socklen_t client_len = sizeof(client); + + int client_fd = accept(server->fd, (struct sockaddr *) &client, &client_len); + if (client_fd == -1) { + log_error("could not accept connection: %s", strerror(errno)); + close(server->fd); + exit(EXIT_FAILURE); + } + + struct epoll_event client_event; + client_event.events = EPOLLIN; + client_event.data.fd = client_fd; + + if (epoll_ctl(server->epoll_fd, EPOLL_CTL_ADD, client_fd, &client_event) == -1) { + log_error("could not add server to epoll: %s", strerror(errno)); + exit(EXIT_FAILURE); + } + + int j = 0; + while (server->connected_clients[j] != -1 && j < MAXEVENTS) { + j++; + } + + if (j < MAXEVENTS) { + server->connected_clients[j] = client_fd; + } else { + log_warn("max number of connection has been reached"); + } + +} + +static void +server_handle_client_data(server_t *server, struct epoll_event *event) +{ + int client_fd = event->data.fd; + if (event->events & EPOLLHUP) { + for (int j = 0; j < MAXEVENTS; ++j) { + if (server->connected_clients[j] == client_fd) { + server->connected_clients[j] = -1; + break; + } + } + return; + } + char client_buf[BUFFER_SIZE]; + memset(client_buf, 0, BUFFER_SIZE); + + if (recv(client_fd, client_buf, BUFFER_SIZE, 0) == -1) { + log_error("could not read data from client: %s", strerror(errno)); + return; + } + + if (!strncasecmp(client_buf, EXIT_COMMAND, strlen(EXIT_COMMAND) - 1)) { + log_info("exiting program. bye bye!"); + close(client_fd); + close(server->fd); + exit(EXIT_SUCCESS); + } + + for (int j = 0; j < MAXEVENTS; ++j) { + if (server->connected_clients[j] == -1) { + continue; + } + + char message[BUFFER_SIZE]; + memset(message, 0, sizeof(char) * BUFFER_SIZE); + + sprintf(message, "client_%d :%s", client_fd, client_buf); + if (send(server->connected_clients[j], message, BUFFER_SIZE, 0) == -1) { + log_error("could not send data to client: %s", strerror(errno)); + continue; + } + } +} -- cgit v1.2.3