2017-02-01 18:11:53 +00:00
|
|
|
#include "server.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char* argv[]){
|
|
|
|
|
|
|
|
/* [1] Initialisation
|
|
|
|
=========================================================*/
|
2017-02-14 08:33:48 +00:00
|
|
|
/* (1) Client address + port */
|
2017-02-05 14:31:44 +00:00
|
|
|
struct sockaddr_in addr_client;
|
2017-02-14 08:33:48 +00:00
|
|
|
int port;
|
|
|
|
|
|
|
|
/* (2) Sockets */
|
2017-02-08 10:44:10 +00:00
|
|
|
int listensock, datasock;
|
2017-02-01 18:11:53 +00:00
|
|
|
|
2017-02-14 08:33:48 +00:00
|
|
|
/* (3) Struct to send arguments to threadable process */
|
|
|
|
pthread_arg_wrapper built_args = {0, 0};
|
|
|
|
|
2017-02-01 18:11:53 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2017-02-05 21:17:48 +00:00
|
|
|
/* [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
|
2017-02-01 18:11:53 +00:00
|
|
|
=========================================================*/
|
|
|
|
/* (1) Create socket */
|
2017-02-08 10:44:10 +00:00
|
|
|
listensock = xbind(port);
|
2017-02-01 18:11:53 +00:00
|
|
|
|
|
|
|
/* (1-) Manage error */
|
2017-02-08 10:44:10 +00:00
|
|
|
if( listensock == -1 ){
|
2017-02-01 18:11:53 +00:00
|
|
|
perror("erreur création socket");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-02-14 08:33:48 +00:00
|
|
|
/* [4] Wait for clients indefinately
|
2017-02-01 18:11:53 +00:00
|
|
|
=========================================================*/
|
2017-02-14 08:33:48 +00:00
|
|
|
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;
|
|
|
|
|
2017-02-08 10:44:10 +00:00
|
|
|
|
|
|
|
}
|
2017-02-01 18:11:53 +00:00
|
|
|
|
2017-02-14 08:33:48 +00:00
|
|
|
/* [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);
|
2017-02-01 18:11:53 +00:00
|
|
|
|
2017-02-14 08:33:48 +00:00
|
|
|
/* (2) Close listening socket */
|
|
|
|
close(listensock);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2017-02-08 10:44:10 +00:00
|
|
|
|
2017-02-14 08:33:48 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
2017-02-08 10:44:10 +00:00
|
|
|
=========================================================*/
|
|
|
|
/* (1) wait/read data */
|
|
|
|
bytes = xread(datasock, to_recv, BUFSIZE);
|
|
|
|
|
2017-02-05 14:31:44 +00:00
|
|
|
/* (2) Manage error */
|
|
|
|
if( bytes == -1 ){
|
2017-02-08 10:44:10 +00:00
|
|
|
perror("erreur reception paquet");
|
2017-02-01 18:11:53 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2017-02-08 10:44:10 +00:00
|
|
|
|
2017-02-02 10:18:34 +00:00
|
|
|
// Get client ip
|
|
|
|
inet_ntop(AF_INET, &(addr_client.sin_addr), client_ip, 20);
|
|
|
|
|
2017-02-05 14:31:44 +00:00
|
|
|
printf("*** received '%s' (%d bytes) from %s:%d\n", to_recv, bytes, client_ip, ntohs(addr_client.sin_port));
|
2017-02-01 18:11:53 +00:00
|
|
|
|
2017-02-14 08:33:48 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* [3] Send response
|
2017-02-01 18:11:53 +00:00
|
|
|
=========================================================*/
|
2017-02-05 21:17:48 +00:00
|
|
|
/* (1) Send response */
|
2017-02-08 10:44:10 +00:00
|
|
|
bytes = xwrite(datasock, to_send);
|
2017-02-05 14:31:44 +00:00
|
|
|
|
2017-02-05 21:17:48 +00:00
|
|
|
/* (2) Manage error */
|
2017-02-05 14:31:44 +00:00
|
|
|
if( bytes == -1 ){
|
2017-02-01 18:11:53 +00:00
|
|
|
perror("erreur envoi réponse");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2017-02-05 21:17:48 +00:00
|
|
|
|
2017-02-14 08:33:48 +00:00
|
|
|
|
|
|
|
/* [4] End process
|
2017-02-01 18:11:53 +00:00
|
|
|
=========================================================*/
|
2017-02-14 08:33:48 +00:00
|
|
|
/* (1) Close data socket */
|
2017-02-08 10:44:10 +00:00
|
|
|
close(datasock);
|
2017-02-05 21:17:48 +00:00
|
|
|
|
2017-02-14 08:33:48 +00:00
|
|
|
/* (2) Mark manager as inactive again */
|
|
|
|
managers[thread_index] = 0;
|
|
|
|
|
2017-02-01 18:11:53 +00:00
|
|
|
}
|