From 742b05de740be3e54d718a649099eac570705cb7 Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Fri, 9 Jul 2021 18:34:54 +0200 Subject: [PATCH] MULTIPLE CLIENTS WORKING! --- Makefile | 8 +++--- src/cli.c | 2 +- src/server.c | 70 ++++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 56 insertions(+), 24 deletions(-) diff --git a/Makefile b/Makefile index cf6026f..a83b960 100644 --- a/Makefile +++ b/Makefile @@ -43,21 +43,21 @@ $(BINDIR)/tests/centers: $(SRCDIR)/tests/centers.c # ---- General recipes ------------------------------------------------------- # -$(BINDIR)/%.o: $(SRCDIR)/%.c $(INCDIR)/%.h $(INCDIR)/base.h +$(BINDIR)/%.o: $(SRCDIR)/%.c $(INCDIR)/%.h | $(INCDIR)/base.h @echo "Compiling $<" @$(CC) $(CCINCLUDES) $(CCOPTS) $(CCFLAGS) -c -o $@ $< # ---- Main recipe ----------------------------------------------------------- # -$(BINDIR)/main.o: $(SRCDIR)/main.c $(INCDIR)/base.h +$(BINDIR)/main.o: $(SRCDIR)/main.c | $(INCDIR)/base.h @echo "Compiling $<" @$(CC) $(CCINCLUDES) $(CCOPTS) $(CCFLAGS) -c -o $@ $< -$(BINDIR)/gem-graph-server: $(SERVEROBJ) $(INCDIR)/base.h +$(BINDIR)/gem-graph-server: $(SERVEROBJ) @echo "Building program to $@" @$(CC) -o $@ $(SERVEROBJ) $(LDFLAGS) @echo "Success!" -$(BINDIR)/gem-graph-ctl: $(CLIOBJ) $(INCDIR)/base.h +$(BINDIR)/gem-graph-ctl: $(CLIOBJ) @echo "Building program to $@" @$(CC) -o $@ $(CLIOBJ) $(LDFLAGS) @echo "Success!" diff --git a/src/cli.c b/src/cli.c index b6d1398..83f37c2 100644 --- a/src/cli.c +++ b/src/cli.c @@ -222,7 +222,7 @@ int main() struct sockaddr_in servaddr; // Socket creation - sockfd = socket(PF_INET, SOCK_STREAM, 0); + sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd == -1) { printLog("Socket creation failed!\n"); return 1; diff --git a/src/server.c b/src/server.c index 2423d2c..8ed5f4e 100644 --- a/src/server.c +++ b/src/server.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -46,9 +47,12 @@ void *serverCommunicationInstance(void *server) { ServerCommunication_t *args; char **argv = NULL; + char clientIP[16]; char receiveBuff[RECEIVE_BUFFER_SIZE]; char sendBuff[SEND_BUFFER_SIZE]; - int tokenIndex; + int tokenIndex, bytesReceived; + struct sockaddr_in clientAddr; + socklen_t clientAddrSize = sizeof(clientAddr); args = (ServerCommunication_t*) server; @@ -60,14 +64,25 @@ void *serverCommunicationInstance(void *server) printLog("Waiting for commands...\n"); // Read the message from client and copy it in buffer - read(args->sockfd, receiveBuff, sizeof(receiveBuff)); + bytesReceived = recvfrom(args->sockfd, receiveBuff, sizeof(receiveBuff), + 0, (struct sockaddr *)&clientAddr, + &clientAddrSize); + if (bytesReceived == -1) { + printLog("Could not receive data!\n"); + break; + }; // Ignore null-sized request - if (receiveBuff[0] == 0) + if (bytesReceived == 0) break; + // get IP addr from client + inet_ntop(AF_INET, &(clientAddr.sin_addr), clientIP, clientAddrSize); + // Print buffer which contains the client request - printLog("Client request : '%s'\n", receiveBuff); + printLog("Client %s:%d request : '%s'\n", clientIP, + ntohs(clientAddr.sin_port), + receiveBuff); // get args in an array tokenIndex = 0; @@ -90,7 +105,8 @@ void *serverCommunicationInstance(void *server) } // and send that buffer to client - write(args->sockfd, sendBuff, sizeof(sendBuff)); + sendto(args->sockfd, sendBuff, sizeof(sendBuff), 0, + (struct sockaddr *)&clientAddr, clientAddrSize); } close(args->sockfd); @@ -103,14 +119,16 @@ void *serverCommunicationInstance(void *server) // Server main function // // -------------------------------------------------------------------------- // #define PORT 9000 +#define MAX_CONNECTION 100 static void *serverMain(void *server) { Server_t *args; - ServerCommunication_t serverSlots[50] = {0}; - int connfd, flags, serverSlotIndex = 0; - uint len; - struct sockaddr_in servaddr, cli; + ServerCommunication_t serverSlots[MAX_CONNECTION] = {0}; + int connfd, flags, threadStatus, serverSlotIndex = 0; + uint socklen; + struct sockaddr_in servaddr, clientAddr; + char clientIP[16]; // Get args args = (Server_t*) server; @@ -143,46 +161,60 @@ static void *serverMain(void *server) servaddr.sin_port = htons(PORT); // Binding newly created socket - if ((bind(args->sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr))) != 0) { + if ((bind(args->sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr))) == -1) { printLog("Socket bind failed!\n"); - close(args->sockfd); goto serverExiting; } // Now server is ready to listen and verification - if ((listen(args->sockfd, 5)) != 0) { + if (listen(args->sockfd, MAX_CONNECTION) == -1) { printLog("Socket listening failed!\n"); - close(args->sockfd); goto serverExiting; } - len = sizeof(cli); + socklen = sizeof(clientAddr); + + if (getsockname(args->sockfd, (struct sockaddr *) &servaddr, &socklen) + == -1) { + printLog("Could not get sock name!\n"); + goto serverExiting; + } printLog("Server listening...\n"); while (!args->pleaseStop) { // Accept the data packet from client - connfd = accept(args->sockfd, (struct sockaddr*)&cli, &len); + connfd = accept(args->sockfd, (struct sockaddr*)&clientAddr, &socklen); if (connfd < 0) { // If error is not due to lack of clients connecting, this is error if (errno != EWOULDBLOCK) { printLog("Server acccept failed!\n"); goto serverExiting; } + sleep(1); } else { - // Client connected, creating a thread - printLog("Client accepted\n"); + // Client connected + // get IP addr from client + inet_ntop(AF_INET, &(clientAddr.sin_addr), clientIP, socklen); + printLog("Client accepted from %s\n", clientIP); //TODO pass that thing to communicator ? + // Populate communicator slot serverSlots[serverSlotIndex].sockfd = connfd; serverSlots[serverSlotIndex].parent = args; - pthread_create(&serverSlots[serverSlotIndex].id, + // Create thread + threadStatus = pthread_create(&serverSlots[serverSlotIndex].id, NULL, serverCommunicationInstance, (void*)&serverSlots[serverSlotIndex]); + if(threadStatus != 0) { + printLog("Error from pthread: %d\n", threadStatus); + goto serverExiting; + } - printLog("Server listening...\n"); + serverSlotIndex++; + printLog("Accepted connection. Server will now listen...\n"); } }