From fb71cdafab9847a15ac67cd56b13d5ada1d7f20e Mon Sep 17 00:00:00 2001 From: iceyrazor Date: Tue, 13 Oct 2026 22:00:39 -0500 Subject: rwlocking removed Server and merged it into launch_socket launch_socket is now socket_server fixed a bit of error handling for acceptIncoming --- Server.c | 46 ----------- Server.h | 46 ----------- launch-socket.c | 209 ---------------------------------------------- launch-socket.h | 19 ----- socket_server.c | 251 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ socket_server.h | 57 +++++++++++++ 6 files changed, 308 insertions(+), 320 deletions(-) delete mode 100755 Server.c delete mode 100755 Server.h delete mode 100755 launch-socket.c delete mode 100755 launch-socket.h create mode 100755 socket_server.c create mode 100755 socket_server.h diff --git a/Server.c b/Server.c deleted file mode 100755 index 8c3c8c4..0000000 --- a/Server.c +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include -#include -#include -#include - -struct Server server_constructor(int domain, int service, int protocol, ulong interface, int port, int backlog){ - struct Server server; - - server.domain=domain; - server.service=service; - server.protocol=protocol; - server.interface=interface; - server.port=port; - server.backlog=backlog; - - server.address.sin_family=domain; - server.address.sin_port=htons(port); - server.address.sin_addr.s_addr=htonl(interface); - - server.socket = socket(domain,service,protocol); - - if(server.socket == 0){ - perror("failed to connect to socket...\n"); - exit(1); - } - - if (bind(server.socket, (struct sockaddr *)&server.address, sizeof(server.address)) < 0){ - perror("failed to bind socket...\n"); - exit(1); - } - - if(listen(server.socket, server.backlog) < 0){ - perror("failed to start listening...\n"); - exit(1); - } - - server.accepted_socket=NULL; - - server.on_message=NULL; - server.on_disconnect=NULL; - - server.running=true; - - return server; -}; diff --git a/Server.h b/Server.h deleted file mode 100755 index 241351a..0000000 --- a/Server.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef Server_h -#define Server_h - -#include -#include -#include -#include -#include - -struct AcceptedSocket{ - int socketFD; - struct sockaddr_in address; - int error; - bool succ; - pthread_t thread_id; - atomic_bool shutdown; - - struct AcceptedSocket *next; -}; - -struct Server{ - int domain; - int service; - int protocol; - u_long interface; - int port; - int backlog; - atomic_bool running; - - pthread_t server_thread_id; - pthread_t cleanup_thread_id; - - struct sockaddr_in address; - - int socket; - - pthread_mutex_t list_lock; - struct AcceptedSocket *accepted_socket; - - void (*on_message)(struct Server *server, char message[], ssize_t amountRecv, int socketFD); - void (*on_disconnect)(struct Server *server, int socketFD); -}; - -struct Server server_constructor(int domain, int service, int protocol, u_long interface, int port, int backlog); - -#endif /* Server_h */ diff --git a/launch-socket.c b/launch-socket.c deleted file mode 100755 index 38cd4eb..0000000 --- a/launch-socket.c +++ /dev/null @@ -1,209 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct recv_data_arg { - int socketFD; - struct Server* server; - struct AcceptedSocket* curr_socket; -}; - -void* recv_data(void* threadarg) -{ - struct recv_data_arg* recv_d_arg; - recv_d_arg = (struct recv_data_arg*)threadarg; - - while (recv_d_arg->server->running) { - char buffer[30000] = { 0 }; - ssize_t amountRecv = recv(recv_d_arg->socketFD, buffer, 30000, 0); - - if (recv_d_arg->server->running && recv_d_arg->curr_socket->shutdown == false) { - if (amountRecv == 0) - break; - - if (recv_d_arg->server->on_message) - recv_d_arg->server->on_message(recv_d_arg->server, buffer, amountRecv, recv_d_arg->socketFD); - } - } - - recv_d_arg->curr_socket->shutdown = true; - close(recv_d_arg->socketFD); - - if (recv_d_arg->server->on_disconnect) - recv_d_arg->server->on_disconnect(recv_d_arg->server, recv_d_arg->socketFD); - free(recv_d_arg); - - pthread_exit(NULL); -} - - -void cleanup_conns(struct Server* server) -{ - pthread_mutex_lock(&server->list_lock); - if (server->accepted_socket) { - struct AcceptedSocket* sel_socket = server->accepted_socket; - struct AcceptedSocket* prev_socket = server->accepted_socket; - struct AcceptedSocket* prev2_socket = server->accepted_socket; - - while (sel_socket != NULL) { - sel_socket = sel_socket->next; - if (prev_socket->shutdown == true) { - if (prev_socket == server->accepted_socket) { - pthread_join(server->accepted_socket->thread_id,NULL); - free(server->accepted_socket); - server->accepted_socket = sel_socket; - } else { - pthread_join(prev2_socket->next->thread_id,NULL); - free(prev2_socket->next); - prev2_socket->next = sel_socket; - } - } else { - prev2_socket = prev_socket; - } - prev_socket = sel_socket; - } - } - pthread_mutex_unlock(&server->list_lock); -} - -void* cleanup_loop(void* threadarg) -{ - struct Server* server; - server = (struct Server*)threadarg; - while (server->running) { - cleanup_conns(server); - for (int i = 0; i < 60 && server->running; i++) { - sleep(1); - } - } - - pthread_exit(NULL); -} - -struct AcceptedSocket* acceptIncoming(struct Server* server) -{ - int serverSocketFd = server->socket; - - struct sockaddr_in clientAddress; - socklen_t ClientAddressSize = sizeof(struct sockaddr); - int clientSocketFD = accept(serverSocketFd, (struct sockaddr*)&clientAddress, &ClientAddressSize); - - if (server->running) { - struct AcceptedSocket* acceptedSocket = malloc(sizeof(struct AcceptedSocket)); - acceptedSocket->address = clientAddress; - acceptedSocket->socketFD = clientSocketFD; - acceptedSocket->succ = clientSocketFD > 0; - acceptedSocket->next = NULL; - acceptedSocket->shutdown = false; - - if (!acceptedSocket) { - acceptedSocket->error = clientSocketFD; - } else { - if (server->running) { - struct AcceptedSocket* sel_socket = server->accepted_socket; - - if (sel_socket == NULL) { - server->accepted_socket = acceptedSocket; - } else { - while (1) { - if (sel_socket->next == NULL) { - sel_socket->next = acceptedSocket; - break; - } else { - sel_socket = sel_socket->next; - } - } - } - } - } - return acceptedSocket; - } else { - return NULL; - } -} - -void* await_client(void* threadarg) -{ - struct Server* server; - server = (struct Server*)threadarg; - while (server->running) { - struct AcceptedSocket* new_socket = acceptIncoming(server); - if (server->running) { - if (new_socket->succ == 0) { - free(new_socket); - } else { - - struct recv_data_arg* recv_d_arg = malloc(sizeof(*recv_d_arg)); - recv_d_arg->socketFD = new_socket->socketFD; - recv_d_arg->server = server; - recv_d_arg->curr_socket = new_socket; - - int thread_err = pthread_create(&new_socket->thread_id, NULL, recv_data, recv_d_arg); - if (thread_err != 0) { - fprintf(stderr, "ERROR CREATING THREAD FOR CLIENT: %d\n", thread_err); - perror("await client error"); - exit(-1); - } - } - } - } - - pthread_exit(NULL); -} - -int server_close_socket(struct Server* server) -{ - server->running = false; - pthread_join(server->cleanup_thread_id, NULL); - - int shuterr = shutdown(server->socket, SHUT_RDWR); - pthread_join(server->server_thread_id, NULL); - int closeerr = close(server->socket); - - cleanup_conns(server); - pthread_mutex_destroy(&server->list_lock); - return shuterr+closeerr; -} - -int launch_socket(struct Server* server) -{ - pthread_mutex_init(&server->list_lock, NULL); - - int thread_err2 = pthread_create(&server->cleanup_thread_id, NULL, cleanup_loop, (void*)server); - if (thread_err2 != 0) { - fprintf(stderr, "ERROR WITH CLEANUP LOOP: %d\n", thread_err2); - perror("cleanup loop err"); - exit(-1); - } - - int thread_err = pthread_create(&server->server_thread_id, NULL, await_client, (void*)server); - if (thread_err != 0) { - fprintf(stderr, "ERROR WITH AWAIT CLIENT: %d\n", thread_err); - perror("await client error"); - exit(-1); - } - - return 0; -} - -void broadcast(struct Server* server, int socketFD, char* message){ - pthread_mutex_lock(&server->list_lock); - struct AcceptedSocket* sel_socket = server->accepted_socket; - while (sel_socket != NULL) { - if (sel_socket->shutdown == false && sel_socket->socketFD != socketFD) { - send(sel_socket->socketFD, message, 30000, 0); - } - sel_socket = sel_socket->next; - } - pthread_mutex_unlock(&server->list_lock); -} \ No newline at end of file diff --git a/launch-socket.h b/launch-socket.h deleted file mode 100755 index 2e10b04..0000000 --- a/launch-socket.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef launch_socket_h -#define launch_socket_h -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int server_close_socket(struct Server *server); - -int launch_socket(struct Server *server); - -void broadcast(struct Server *server, int socketFD, char* message); -#endif diff --git a/socket_server.c b/socket_server.c new file mode 100755 index 0000000..9281595 --- /dev/null +++ b/socket_server.c @@ -0,0 +1,251 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct Server server_constructor(int domain, int service, int protocol, ulong interface, int port, int backlog) +{ + struct Server server; + + server.domain = domain; + server.service = service; + server.protocol = protocol; + server.interface = interface; + server.port = port; + server.backlog = backlog; + + server.address.sin_family = domain; + server.address.sin_port = htons(port); + server.address.sin_addr.s_addr = htonl(interface); + + server.socket = socket(domain, service, protocol); + + if (server.socket == 0) { + perror("failed to connect to socket...\n"); + exit(1); + } + + if (bind(server.socket, (struct sockaddr*)&server.address, sizeof(server.address)) < 0) { + perror("failed to bind socket...\n"); + exit(1); + } + + if (listen(server.socket, server.backlog) < 0) { + perror("failed to start listening...\n"); + exit(1); + } + + server.accepted_socket = NULL; + + server.on_message = NULL; + server.on_disconnect = NULL; + + server.running = true; + + return server; +}; + +struct recv_data_arg { + struct Server* server; + struct AcceptedSocket* curr_socket; +}; + +void* recv_data(void* threadarg) +{ + struct recv_data_arg* recv_d_arg; + recv_d_arg = (struct recv_data_arg*)threadarg; + + while (recv_d_arg->server->running) { + char buffer[30000] = { 0 }; + ssize_t amountRecv = recv(recv_d_arg->curr_socket->socketFD, buffer, 30000, 0); + + if (recv_d_arg->server->running && recv_d_arg->curr_socket->shutdown == false) { + if (amountRecv == 0) + break; + + if (recv_d_arg->server->on_message) + recv_d_arg->server->on_message(recv_d_arg->server, recv_d_arg->curr_socket, buffer, amountRecv); + } + } + + pthread_rwlock_wrlock(&recv_d_arg->server->list_lock); + close(recv_d_arg->curr_socket->socketFD); + recv_d_arg->curr_socket->shutdown = true; + pthread_rwlock_unlock(&recv_d_arg->server->list_lock); + + if (recv_d_arg->server->on_disconnect) + recv_d_arg->server->on_disconnect(recv_d_arg->server, recv_d_arg->curr_socket); + + free(recv_d_arg); + pthread_exit(NULL); +} + +void cleanup_conns(struct Server* server) +{ + pthread_rwlock_wrlock(&server->list_lock); + if (server->accepted_socket) { + struct AcceptedSocket* sel_socket = server->accepted_socket; + struct AcceptedSocket* prev_socket = server->accepted_socket; + struct AcceptedSocket* prev2_socket = server->accepted_socket; + + while (sel_socket != NULL) { + sel_socket = sel_socket->next; + if (prev_socket->shutdown == true) { + if (prev_socket == server->accepted_socket) { + pthread_join(server->accepted_socket->thread_id, NULL); + free(server->accepted_socket); + server->accepted_socket = sel_socket; + } else { + pthread_join(prev2_socket->next->thread_id, NULL); + free(prev2_socket->next); + prev2_socket->next = sel_socket; + } + } else { + prev2_socket = prev_socket; + } + prev_socket = sel_socket; + } + } + pthread_rwlock_unlock(&server->list_lock); +} + +void* cleanup_loop(void* threadarg) +{ + struct Server* server; + server = (struct Server*)threadarg; + while (server->running) { + cleanup_conns(server); + for (int i = 0; i < 60 && server->running; i++) { + sleep(1); + } + } + + pthread_exit(NULL); +} + +struct AcceptedSocket* acceptIncoming(struct Server* server) +{ + int serverSocketFd = server->socket; + + struct sockaddr_in clientAddress; + socklen_t ClientAddressSize = sizeof(struct sockaddr); + int clientSocketFD = accept(serverSocketFd, (struct sockaddr*)&clientAddress, &ClientAddressSize); + + if (server->running && clientSocketFD > 0) { + struct AcceptedSocket* acceptedSocket = malloc(sizeof(struct AcceptedSocket)); + if (!acceptedSocket) + return NULL; + acceptedSocket->address = clientAddress; + acceptedSocket->socketFD = clientSocketFD; + acceptedSocket->next = NULL; + acceptedSocket->shutdown = false; + + if (server->running) { + pthread_rwlock_wrlock(&server->list_lock); + struct AcceptedSocket* sel_socket = server->accepted_socket; + + if (sel_socket == NULL) { + server->accepted_socket = acceptedSocket; + } else { + while (1) { + if (sel_socket->next == NULL) { + sel_socket->next = acceptedSocket; + break; + } else { + sel_socket = sel_socket->next; + } + } + } + pthread_rwlock_unlock(&server->list_lock); + } + return acceptedSocket; + } else { + return NULL; + } +} + +void* await_client(void* threadarg) +{ + struct Server* server; + server = (struct Server*)threadarg; + while (server->running) { + struct AcceptedSocket* new_socket = acceptIncoming(server); + if (server->running && new_socket) { + struct recv_data_arg* recv_d_arg = malloc(sizeof(*recv_d_arg)); + recv_d_arg->server = server; + recv_d_arg->curr_socket = new_socket; + + int thread_err = pthread_create(&new_socket->thread_id, NULL, recv_data, recv_d_arg); + if (thread_err != 0) { + fprintf(stderr, "ERROR CREATING THREAD FOR CLIENT: %d\n", thread_err); + perror("await client error"); + exit(-1); + } + } + } + + pthread_exit(NULL); +} + +int server_close_socket(struct Server* server) +{ + server->running = false; + pthread_join(server->cleanup_thread_id, NULL); + + int shuterr = shutdown(server->socket, SHUT_RDWR); + pthread_join(server->server_thread_id, NULL); + int closeerr = close(server->socket); + + cleanup_conns(server); + pthread_rwlock_destroy(&server->list_lock); + return shuterr + closeerr; +} + +int init_socket_server(struct Server* server) +{ + pthread_rwlock_init(&server->list_lock, NULL); + + int thread_err2 = pthread_create(&server->cleanup_thread_id, NULL, cleanup_loop, (void*)server); + if (thread_err2 != 0) { + fprintf(stderr, "ERROR WITH CLEANUP LOOP: %d\n", thread_err2); + perror("cleanup loop err"); + exit(-1); + } + + int thread_err = pthread_create(&server->server_thread_id, NULL, await_client, (void*)server); + if (thread_err != 0) { + fprintf(stderr, "ERROR WITH AWAIT CLIENT: %d\n", thread_err); + perror("await client error"); + exit(-1); + } + + return 0; +} + +void soc_send(struct Server* server, struct AcceptedSocket* cur_socket, char* message) +{ + pthread_rwlock_rdlock(&server->list_lock); + if(cur_socket->shutdown==false) + send(cur_socket->socketFD, message, 30000, MSG_NOSIGNAL); + pthread_rwlock_unlock(&server->list_lock); +} + +void soc_broadcast(struct Server* server, struct AcceptedSocket* cur_socket, char* message) +{ + pthread_rwlock_rdlock(&server->list_lock); + struct AcceptedSocket* sel_socket = server->accepted_socket; + while (sel_socket != NULL) { + if (sel_socket->shutdown == false && sel_socket->socketFD != cur_socket->socketFD) { + soc_send(server, sel_socket, message); + } + sel_socket = sel_socket->next; + } + pthread_rwlock_unlock(&server->list_lock); +} \ No newline at end of file diff --git a/socket_server.h b/socket_server.h new file mode 100755 index 0000000..222de11 --- /dev/null +++ b/socket_server.h @@ -0,0 +1,57 @@ +#ifndef socket_server_h +#define socket_server_h +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct AcceptedSocket{ + int socketFD; + struct sockaddr_in address; + int error; + bool succ; + pthread_t thread_id; + atomic_bool shutdown; + + struct AcceptedSocket *next; +}; + +struct Server{ + int domain; + int service; + int protocol; + u_long interface; + int port; + int backlog; + atomic_bool running; + + pthread_t server_thread_id; + pthread_t cleanup_thread_id; + + struct sockaddr_in address; + + int socket; + + pthread_rwlock_t list_lock; + struct AcceptedSocket *accepted_socket; + + void (*on_message)(struct Server *server, struct AcceptedSocket* cur_socket, char message[], ssize_t amountRecv); + void (*on_disconnect)(struct Server *server, struct AcceptedSocket* cur_socket); +}; + +struct Server server_constructor(int domain, int service, int protocol, u_long interface, int port, int backlog); + +int server_close_socket(struct Server *server); + +int init_socket_server(struct Server *server); + +void soc_send(struct Server* server, struct AcceptedSocket* cur_socket, char* message); + +void soc_broadcast(struct Server *server, struct AcceptedSocket* cur_socket, char* message); +#endif -- cgit v1.3