#include "server.h" int main(int argc, char* argv[]){ /* [1] Initialisation =========================================================*/ /* (1) Client address + port */ struct sockaddr_in addr_client; int port; /* (2) Sockets */ int listensock, datasock; /* (3) Struct to send arguments to threadable process */ pthread_arg_wrapper built_args = {0, 0}; /* [2] Manage arguments =========================================================*/ /* (1) Manage arguments count */ if( argc < 2 ){ printf("Missing arguments\nUsage: server port [message]\n"); printf("port = 0 : automatic port\n"); return 1; } /* (2) Manage port argument */ if( sscanf(argv[1], "%d", &port) <= 0 ){ printf("argument error: port must be a valid integer\n"); printf("port = 0 : automatic port\n"); return 1; } /* [3] Create socket =========================================================*/ /* (1) Create socket */ listensock = xbind(port); /* (1-) Manage error */ if( listensock == -1 ){ perror("erreur création socket"); exit(1); } /* [4] Wait for clients indefinately =========================================================*/ int i, index = -1; // thread index while( 1 ){ /* (1) Listen for incoming connection */ index = -1; datasock = xlisten(listensock, &addr_client); DEBUG&& debug("server", "wait for 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 ){ DEBUG&& printf("found[%d]\n", i); 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; } /* (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; } /* [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; } 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); /* (2) Manage error */ if( bytes == -1 ){ perror("erreur reception paquet"); exit(1); } // Get client ip 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)); /* [3] Send response =========================================================*/ /* (1) Send response */ bytes = xwrite(datasock, to_send); /* (2) Manage error */ if( bytes == -1 ){ perror("erreur envoi réponse"); exit(1); } /* [4] End process =========================================================*/ /* (1) Close data socket */ DEBUG&& debug("thread", "closing socket"); close(datasock); DEBUG&& printf("done\n"); /* (2) Mark manager as inactive again */ DEBUG&& debug("thread", "freeing thread"); a_managers[thread_index] = 0; DEBUG&& printf("done\n"); }