From 428ac5ff4f9b88ec0df3f8fa7dc0c2e7e993a632 Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Fri, 9 Jul 2021 02:53:54 +0200 Subject: [PATCH] Multiple clients ! --- include/base.h | 2 ++ src/cmds.c | 2 ++ src/server.c | 73 +++++++++++++++++++++++++++++++++++--------------- 3 files changed, 55 insertions(+), 22 deletions(-) diff --git a/include/base.h b/include/base.h index 9e9947e..3831fb1 100644 --- a/include/base.h +++ b/include/base.h @@ -122,11 +122,13 @@ struct { struct { pthread_t id; bool pleaseStop; + int sockfd; } typedef Server_t; struct { pthread_t id; bool pleaseStop; + Server_t *parent; int sockfd; } typedef ServerCommunication_t; diff --git a/src/cmds.c b/src/cmds.c index dafd60c..c7c2557 100644 --- a/src/cmds.c +++ b/src/cmds.c @@ -23,6 +23,8 @@ #include "../include/scheduler.h" #include "../include/model.h" +#include + #define LINE_LENGTH 80 #define LINE_NUMBER 24 diff --git a/src/server.c b/src/server.c index 8830455..673b55e 100644 --- a/src/server.c +++ b/src/server.c @@ -25,6 +25,8 @@ #include #include #include +#include +#include static void *serverMain(void *server); @@ -40,13 +42,16 @@ void ServerInit(Server_t *server) #define SEND_BUFFER_SIZE 80 * 24 #define RECEIVE_BUFFER_SIZE 80 -static void serverCommunicationInstance(Server_t *args, int sockfd) +void *serverCommunicationInstance(void *server) { + ServerCommunication_t *args; char **argv = NULL; char receiveBuff[RECEIVE_BUFFER_SIZE]; char sendBuff[SEND_BUFFER_SIZE]; int tokenIndex; + args = (ServerCommunication_t*) server; + //Accept and incoming connection while(!args->pleaseStop) { @@ -55,7 +60,7 @@ static void serverCommunicationInstance(Server_t *args, int sockfd) printLog("Waiting for commands...\n"); // Read the message from client and copy it in buffer - read(sockfd, receiveBuff, sizeof(receiveBuff)); + read(args->sockfd, receiveBuff, sizeof(receiveBuff)); // Ignore null-sized request if (receiveBuff[0] == 0) @@ -80,16 +85,18 @@ static void serverCommunicationInstance(Server_t *args, int sockfd) // Execute command by first arg in cmdList for (int i = 0; i < LEN(cmdList); i++) { if (strcmp(cmdList[i].name, argv[0]) == 0) { - cmdList[i].execute(sendBuff, argv, args); + cmdList[i].execute(sendBuff, argv, args->parent); } } // and send that buffer to client - write(sockfd, sendBuff, sizeof(sendBuff)); + write(args->sockfd, sendBuff, sizeof(sendBuff)); } + close(args->sockfd); printLog("End of communications \n"); free(argv); + return NULL; } // -------------------------------------------------------------------------- // @@ -100,7 +107,8 @@ static void serverCommunicationInstance(Server_t *args, int sockfd) static void *serverMain(void *server) { Server_t *args; - int sockfd, connfd; + ServerCommunication_t serverSlots[50] = {0}; + int connfd, flags, serverSlotIndex = 0; uint len; struct sockaddr_in servaddr, cli; @@ -109,12 +117,23 @@ static void *serverMain(void *server) printLog("Server #%lu online\n", args->id); // Create socket - sockfd = socket(AF_INET, SOCK_STREAM, 0); - if (sockfd == -1) { + args->sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (args->sockfd == -1) { printLog("Socket creation failed!\n"); goto serverExiting; } + flags = fcntl(args->sockfd, F_GETFL); + if (flags == -1) { + printLog("Socket parameters getting failed!\n"); + goto serverExiting; + } + + if (fcntl(args->sockfd, F_SETFL, flags | O_NONBLOCK) < 0) { + printLog("Socket non-blocking setting failed!\n"); + goto serverExiting; + } + // Prepare binding structure bzero(&servaddr, sizeof(servaddr)); @@ -124,38 +143,48 @@ static void *serverMain(void *server) servaddr.sin_port = htons(PORT); // Binding newly created socket - if ((bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr))) != 0) { + if ((bind(args->sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr))) != 0) { printLog("Socket bind failed!\n"); - goto serverEarlyExiting; + close(args->sockfd); + goto serverExiting; } // Now server is ready to listen and verification - if ((listen(sockfd, 5)) != 0) { + if ((listen(args->sockfd, 5)) != 0) { printLog("Socket listening failed!\n"); + close(args->sockfd); goto serverExiting; } len = sizeof(cli); + printLog("Server listening...\n"); + while (!args->pleaseStop) { - printLog("Server listening...\n"); // Accept the data packet from client - connfd = accept(sockfd, (struct sockaddr*)&cli, &len); + connfd = accept(args->sockfd, (struct sockaddr*)&cli, &len); if (connfd < 0) { - printLog("Server acccept failed!\n"); - goto serverExiting; + if (errno != EWOULDBLOCK) { + printLog("Server acccept failed!\n"); + goto serverExiting; + } + } else { + printLog("Client accepted\n"); + + serverSlots[serverSlotIndex].sockfd = connfd; + serverSlots[serverSlotIndex].parent = args; + + pthread_create(&serverSlots[serverSlotIndex].id, + NULL, + serverCommunicationInstance, + (void*)&serverSlots[serverSlotIndex]); + + printLog("Server listening...\n"); } - printLog("Client accepted\n"); - - // Function for chatting between client and server - serverCommunicationInstance(args, connfd); } -serverExiting: - // After communication ended close the socket - close(sockfd); -serverEarlyExiting: +serverExiting: printLog("Server #%lu offline\n", args->id); return NULL; }