diff --git a/.server.c.swp b/.server.c.swp new file mode 100644 index 0000000..84be80d Binary files /dev/null and b/.server.c.swp differ diff --git a/.server.h.swp b/.server.h.swp new file mode 100644 index 0000000..27f88d6 Binary files /dev/null and b/.server.h.swp differ diff --git a/lib.c b/lib.c index b31696b..7a99d7a 100644 --- a/lib.c +++ b/lib.c @@ -74,7 +74,7 @@ int xbind(const int port){ =========================================================*/ DEBUG&& debug("xbind", "listen for client"); - if( listen(xsocket, 1) < 0 ){ + if( listen(xsocket, maxClients) < 0 ){ DEBUG&& printf("error\n"); return -1; } diff --git a/lib.h b/lib.h index ff7423c..18719c6 100644 --- a/lib.h +++ b/lib.h @@ -10,6 +10,9 @@ #define DEBUG 0x1 #define DEBUG_LEN 40 + // constants + #define maxClients 0x4 + #include #include diff --git a/lib.o b/lib.o index 7cdc95f..d631430 100644 Binary files a/lib.o and b/lib.o differ diff --git a/makefile b/makefile index 7ca2720..25aff58 100644 --- a/makefile +++ b/makefile @@ -1,4 +1,4 @@ -CC=-Werror -g +CC=-Werror -g -pthread client.o: client.h client.c diff --git a/server.c b/server.c index e90e20a..b5e9ba4 100644 --- a/server.c +++ b/server.c @@ -6,19 +6,17 @@ int main(int argc, char* argv[]){ /* [1] Initialisation =========================================================*/ - /* (1) Socket info */ - // Client + /* (1) Client address + port */ struct sockaddr_in addr_client; - char client_ip[20]; - int port; // chosen port - // Socket + int port; + + /* (2) Sockets */ int listensock, datasock; + /* (3) Struct to send arguments to threadable process */ + pthread_arg_wrapper built_args = {0, 0}; + - /* (2) Misc. information */ - char* to_send = (char*) malloc( BUFSIZE * sizeof(char) ); - char* to_recv = (char*) malloc( BUFSIZE * sizeof(char) ); - int bytes; // transfer count /* [2] Manage arguments @@ -37,18 +35,6 @@ int main(int argc, char* argv[]){ return 1; } - /* (3) Manage optional @message argument */ - if( argc >= 3 ){ - - if( strlen(argv[2]) > BUFSIZE || sscanf(argv[2], "%s", to_send) <= 0 ){ - printf("argument error: message must be a string (max: %d characters long)\n", BUFSIZE); - return 1; - } - - }else - strcpy(to_send, "server default message"); - - /* [3] Create socket @@ -63,20 +49,103 @@ int main(int argc, char* argv[]){ } - /* [4] Wait for client + /* [4] Wait for clients indefinately =========================================================*/ - /* (1) Listen to incoming connection */ - datasock = xlisten(listensock, &addr_client); + int i, index = -1; // thread index + while( 1 ){ + + /* (1) Listen for incoming connection */ + index = -1; + DEBUG&& debug("server", "wait for client"); + datasock = xlisten(listensock, &addr_client); + + /* (2) Manage error */ + if( datasock == -1 ){ + DEBUG&& printf("error\n"); + continue; + } + + DEBUG&& printf("done\n"); + + + /* (3) Search for a free manager */ + DEBUG&& debug("server", "finding free thread"); + for( i = 0 ; i < maxClients ; i++ ) + + if( a_managers[i] == 0 ){ + index = i; + break; + } + + + /* (4) If we haven't found a free manager -> do nothing (john snow) */ + if( index == -1 ){ + DEBUG&& printf("not found\n"); + continue; + } + + DEBUG&& printf("found\n"); + + /* (5) Build thread arguments */ + built_args.socket = datasock; + built_args.index = index; + + /* (6) Processing client connection on a new thread */ + pthread_create(&managers[index], NULL, manageClient, (void*)(intptr_t) &built_args); + + /* (7) Mark the manager as active */ + a_managers[index] = 1; + - /* (2) Manage error */ - if( datasock == -1 ){ - perror("erreur connection client"); - exit(1); } + /* [5] Wait for all threads to end + =========================================================*/ + /* (1) Wait for all threads to end properly */ + for( i = 0 ; i < maxClients ; i++ ) + pthread_join(managers[i], NULL); + + /* (2) Close listening socket */ + close(listensock); + + return 0; +} - /* [5] Wait for data + + + + + + + + +void* manageClient(void* pthread_args){ + + + /* [1] Initialization + =========================================================*/ + /* (1) Initialize socket data */ + struct sockaddr_in addr_client; + char* to_send = (char*) malloc( BUFSIZE * sizeof(char) ); + char* to_recv = (char*) malloc( BUFSIZE * sizeof(char) ); + int bytes; // transfer count + char client_ip[20]; + + /* (2) Fetch arguments */ + pthread_arg_wrapper* arguments = (pthread_arg_wrapper*) (intptr_t) pthread_args; + + // get client_socket + int datasock = arguments->socket; + int thread_index = arguments->index; + + strcpy(to_send, "server default response"); + + + DEBUG&& debug("thread", "starting thread"); + DEBUG&& printf("success[%d]\n", thread_index); + + /* [2] Wait for data =========================================================*/ /* (1) wait/read data */ bytes = xread(datasock, to_recv, BUFSIZE); @@ -92,9 +161,10 @@ int main(int argc, char* argv[]){ inet_ntop(AF_INET, &(addr_client.sin_addr), client_ip, 20); printf("*** received '%s' (%d bytes) from %s:%d\n", to_recv, bytes, client_ip, ntohs(addr_client.sin_port)); - - /* [6] Send response + + + /* [3] Send response =========================================================*/ /* (1) Send response */ bytes = xwrite(datasock, to_send); @@ -106,10 +176,13 @@ int main(int argc, char* argv[]){ } - /* [6] Close socket - =========================================================*/ - close(datasock); - close(listensock); - return 0; + /* [4] End process + =========================================================*/ + /* (1) Close data socket */ + close(datasock); + + /* (2) Mark manager as inactive again */ + managers[thread_index] = 0; + } diff --git a/server.h b/server.h index 085b371..1dcad0f 100644 --- a/server.h +++ b/server.h @@ -14,9 +14,25 @@ #include #include #include + #include #include "lib.h" + // DEFINITIONS + typedef struct{ + int socket; + int index; + } pthread_arg_wrapper; + + + // VARIABLES + static pthread_t managers[maxClients]; // containa THREADS + static int a_managers[maxClients] = {0}; // contains THREADS actifs + + /************************************************ + **** Signatures **** + ************************************************/ + void* manageClient(void* pthread_args); #endif diff --git a/server.o b/server.o index 868c4a5..b91c657 100644 Binary files a/server.o and b/server.o differ