aboutsummaryrefslogtreecommitdiff
path: root/launch-socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'launch-socket.c')
-rwxr-xr-xlaunch-socket.c279
1 files changed, 150 insertions, 129 deletions
diff --git a/launch-socket.c b/launch-socket.c
index 0c2881c..38cd4eb 100755
--- a/launch-socket.c
+++ b/launch-socket.c
@@ -1,188 +1,209 @@
-#include <stdlib.h>
-#include <unistd.h>
+#include <Server.h>
#include <bits/pthreadtypes.h>
-#include <pthread.h>
#include <netinet/in.h>
-#include <stdio.h>
-#include <Server.h>
-#include <sys/socket.h>
#include <poll.h>
+#include <pthread.h>
+#include <stdatomic.h>
#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <launch-socket.h>
-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;
- }
-}
-
-struct recv_data_arg{
+struct recv_data_arg {
int socketFD;
- struct Server *server;
- struct AcceptedSocket *curr_socket;
+ 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;
+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);
+ 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){
- if(amountRecv==0) break;
+ if (recv_d_arg->server->running && recv_d_arg->curr_socket->shutdown == false) {
+ if (amountRecv == 0)
+ break;
- recv_d_arg->server->on_message(recv_d_arg->server, buffer, amountRecv, recv_d_arg->socketFD);
+ 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;
+ 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);
+ 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){
- 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){
+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;
+ server->accepted_socket = sel_socket;
} else {
+ pthread_join(prev2_socket->next->thread_id,NULL);
free(prev2_socket->next);
- prev2_socket->next=sel_socket;
+ prev2_socket->next = sel_socket;
}
} else {
- prev2_socket=prev_socket;
+ prev2_socket = prev_socket;
}
- prev_socket=sel_socket;
+ prev_socket = sel_socket;
}
}
+ pthread_mutex_unlock(&server->list_lock);
}
-void *await_client(void *threadarg){
- struct Server *server;
- server=(struct Server *) threadarg;
- while (server->running){
- printf("\n=== WAITING FOR CONNECTION ===\n\n");
-
- struct AcceptedSocket* new_socket = acceptIncoming(server);
- if(server->running){
- if(new_socket->succ==0){ free(new_socket); } else {
+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);
- struct recv_data_arg *recv_d_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;
+ 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;
- int thread_err=pthread_create(&new_socket->thread_id, NULL, recv_data, recv_d_arg);
+ 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;
}
-
- pthread_exit(NULL);
}
-void *cleanup_loop(void *threadarg){
- struct Server *server;
- server=(struct Server *) threadarg;
- while(server->running){
- cleanup_conns(server);
- sleep(60);
+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);
}
-void server_close_socket(struct Server *server){
- server->running=false;
+int server_close_socket(struct Server* server)
+{
+ server->running = false;
+ pthread_join(server->cleanup_thread_id, NULL);
- struct AcceptedSocket *sel_socket_A=server->accepted_socket;
- while(sel_socket_A!=NULL){
- close(sel_socket_A->socketFD);
- sel_socket_A->shutdown=true;
- sel_socket_A=sel_socket_A->next;
- }
+ int shuterr = shutdown(server->socket, SHUT_RDWR);
+ pthread_join(server->server_thread_id, NULL);
+ int closeerr = close(server->socket);
- int shuterr=shutdown(server->socket,SHUT_RDWR);
- int closeerr=close(server->socket);
-
- sleep(2);
cleanup_conns(server);
-
- printf("\nshutdown with %d : %d\n",shuterr,closeerr);
+ pthread_mutex_destroy(&server->list_lock);
+ return shuterr+closeerr;
}
-pthread_t launch_socket(struct Server *server){
- int addrlen= sizeof(server->address);
+int launch_socket(struct Server* server)
+{
+ pthread_mutex_init(&server->list_lock, NULL);
- printf("running on port: %d\n",server->port);
-
- pthread_t id2;
- int thread_err2=pthread_create(&id2, NULL, cleanup_loop, (void *) server);
- if (thread_err2!=0){
- fprintf(stderr,"ERROR WITH CLEANUP LOOP: %d\n",thread_err2);
+ 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);
}
- pthread_t id;
- int thread_err=pthread_create(&id, NULL, await_client, (void *) server);
- if (thread_err!=0){
- fprintf(stderr,"ERROR WITH AWAIT CLIENT: %d\n",thread_err);
+ 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 id;
+ 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