diff --git a/README.md b/README.md index eacb257..5ccaca1 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,16 @@ Compile version `X` : ``` -gcc -Wall -Wpedantic t_sockvX.c -o t_sockvX +gcc -Wall -Wpedantic tsock_vX.c -o t_sockvX +``` + +Or compile all versions: + +``` +gcc -Wall -Wpedantic tsock_v1.c -o t_sockv1 +gcc -Wall -Wpedantic tsock_v2.c -o t_sockv2 +gcc -Wall -Wpedantic tsock_v3.c -o t_sockv3 +gcc -Wall -Wpedantic tsock_v4.c -o t_sockv4 ``` Generate zip archive (replace `TP1` with relevant indication) : @@ -22,11 +31,51 @@ zip LACAU-ALNET-TP1.zip tsock_v*.c README.md ## Running -TODO help output +``` +usage: ./t_sockv1 <-u> [-ps] [host] +parameters: host With -s, address of the host to connect to. Required with -s. + port Port to connect or bind to. Required. +options: -p Runs a TCP/UDP sink. Incompatible with -s. + -s Runs a TCP/UDP faucet. Incompatible with -p. + -u Use UDP instead of TCP. Required. + +usage: ./t_sockv2 [-psu] [host] +parameters: host With -s, address of the host to connect to. Required with -s. + port Port to connect or bind to. Required. +options: -p Runs a TCP/UDP sink. Incompatible with -s. + -s Runs a TCP/UDP faucet. Incompatible with -p. + -u Use UDP instead of TCP. + +usage: ./t_sockv3 [-psu] [-n nb_messages] [-l mess_length] [host] +parameters: host With -s, address of the host to connect to. Required with -s. + port Port to connect or bind to. Required. +options: -l mess_length Size of the messages to send. Min 5. Max 1400. Default 30. + -n nb_messages Number of messages to send. Min 1. Default 10. Ignored with -p. + -p Runs a TCP/UDP sink. Incompatible with -s. + -s Runs a TCP/UDP faucet. Incompatible with -p. + -u Use UDP instead of TCP. +``` + +Example usage of v3 : + +``` +./t_sockv3 -p -l 15 4000 # receiver +./t_sockv3 -s -l 15 localhost 4000 # sender +``` + +Example usage of v4 : + +``` +./t_sockv3 -C -e -n 20 -l 15 localhost 4000 # client sender +./t_sockv3 -S -r -n 20 -l 15 4000 # server receiver +``` ## Roadmap - [X] tsock-v1 - [X] tsock-v2 -- [WIP] tsock-v3 -- [ ] tsock-v4 +- [X] tsock-v3 +- [X] tsock-v4 + - [X] server can handle multiple requests simultaneously + - [X] server doesn't stop after the connection ends + - [X] both client and server can assume sender/receiver roles diff --git a/tsock_v0.c b/tsock_v0.c index 168d258..66a62ce 100644 --- a/tsock_v0.c +++ b/tsock_v0.c @@ -11,70 +11,70 @@ /* constantes et structures propres au domaine INTERNET */ #include /* structures retournées par les fonctions de gestion de la base de -données du réseau */ + données du réseau */ #include /* pour les entrées/sorties */ #include /* pour la gestion des erreurs */ #include -void main (int argc, char **argv) +int main (int argc, char **argv) { - int c; - extern char *optarg; - extern int optind; - int nb_message = -1; /* Nb de messages à envoyer ou à recevoir, par défaut : 10 en émission, infini en réception */ - int source = -1 ; /* 0=puits, 1=source */ - while ((c = getopt(argc, argv, "pn:s")) != -1) { - switch (c) { - case 'p': - if (source == 1) { - printf("usage: cmd [-p|-s][-n ##]\n"); - exit(1); - } - source = 0; - break; + int c; + extern char *optarg; + extern int optind; + int nb_message = -1; /* Nb de messages à envoyer ou à recevoir, par défaut : 10 en émission, infini en réception */ + int source = -1 ; /* 0=puits, 1=source */ + while ((c = getopt(argc, argv, "pn:s")) != -1) { + switch (c) { + case 'p': + if (source == 1) { + printf("usage: cmd [-p|-s][-n ##]\n"); + exit(1); + } + source = 0; + break; - case 's': - if (source == 0) { - printf("usage: cmd [-p|-s][-n ##]\n"); - exit(1) ; - } - source = 1; - break; + case 's': + if (source == 0) { + printf("usage: cmd [-p|-s][-n ##]\n"); + exit(1) ; + } + source = 1; + break; - case 'n': - nb_message = atoi(optarg); - break; + case 'n': + nb_message = atoi(optarg); + break; - default: - printf("usage: cmd [-p|-s][-n ##]\n"); - break; - } - } + default: + printf("usage: cmd [-p|-s][-n ##]\n"); + break; + } + } - if (source == -1) { - printf("usage: cmd [-p|-s][-n ##]\n"); - exit(1) ; - } + if (source == -1) { + printf("usage: cmd [-p|-s][-n ##]\n"); + exit(1) ; + } - if (source == 1) - printf("on est dans le source\n"); - else - printf("on est dans le puits\n"); + if (source == 1) + printf("on est dans le source\n"); + else + printf("on est dans le puits\n"); - if (nb_message != -1) { - if (source == 1) - printf("nb de tampons à envoyer : %d\n", nb_message); - else - printf("nb de tampons à recevoir : %d\n", nb_message); - } else { - if (source == 1) { - nb_message = 10 ; - printf("nb de tampons à envoyer = 10 par défaut\n"); - } else - printf("nb de tampons à envoyer = infini\n"); + if (nb_message != -1) { + if (source == 1) + printf("nb de tampons à envoyer : %d\n", nb_message); + else + printf("nb de tampons à recevoir : %d\n", nb_message); + } else { + if (source == 1) { + nb_message = 10 ; + printf("nb de tampons à envoyer = 10 par défaut\n"); + } else + printf("nb de tampons à envoyer = infini\n"); - } + } } diff --git a/tsock_v1.c b/tsock_v1.c index 3cde554..f164b41 100644 --- a/tsock_v1.c +++ b/tsock_v1.c @@ -11,7 +11,7 @@ /* constantes et structures propres au domaine INTERNET */ #include /* structures retournées par les fonctions de gestion de la base de -données du réseau */ + données du réseau */ #include /* pour les entrées/sorties */ #include @@ -19,6 +19,152 @@ données du réseau */ #include #define BASE_SIZE 10 + +void construire_message(char *message, char motif, int lg); +void afficher_message(char *message, int lg); +void print_usage(char* arg0); + +int main (int argc, char **argv) { + int c; + extern char *optarg; + extern int optind; + int nb_message = -1; /* Nb de messages à envoyer ou à recevoir, par défaut : 10 en émission, infini en réception */ + int source = -1 ; /* 0=puits, 1=source */ + int udp=0; /* 0=TCP, 1=UDP */ + + while ((c = getopt(argc, argv, "pn:su")) != -1) { + switch (c) { + case 'p': + if (source == 1) { + print_usage(argv[0]); + exit(1); + } + source = 0; + break; + + case 's': + if (source == 0) { + print_usage(argv[0]); + exit(1) ; + } + source = 1; + break; + + case 'n': + nb_message = atoi(optarg); + break; + + case 'u': + udp=1; + break; + + default: + print_usage(argv[0]); + exit(1); + } + } + + char* nom_machine_distante; + + // Recuperation du port + int port=atoi(argv[argc-1]); + port = htons(port); + + char* message = malloc(BASE_SIZE * sizeof(char)); + + if (source == -1) { + print_usage(argv[0]); + exit(1) ; + } + + if (source == 1) { + printf("on est dans le source\n"); + + //Recuperation du nom logique + nom_machine_distante=argv[argc-2]; + } else + printf("on est dans le puits\n"); + + if (nb_message != -1) { + if (source == 1) + printf("nb de tampons à envoyer : %d\n", nb_message); + else + printf("nb de tampons à recevoir : %d\n", nb_message); + } else { + if (source == 1) { + nb_message = 10 ; + printf("nb de tampons à envoyer = 10 par défaut\n"); + } else + printf("nb de tampons à envoyer = infini\n"); + } + + if (udp==1){ + // Creation du socket local + int sock= socket(AF_INET,SOCK_DGRAM,0); + + if (source==1) { + // Creation de l'adresse du socket distant + struct hostent *hp ; + struct sockaddr_in adr_dest; + int longueur_adr_dest = sizeof(adr_dest); + + int longueur_message = BASE_SIZE; + + memset((char *)& adr_dest, 0, sizeof(adr_dest)) ; + + adr_dest.sin_family=AF_INET; + adr_dest.sin_port=port; + + + if ((hp = gethostbyname(nom_machine_distante)) == NULL) { + printf("erreur gethostbyname\n") ; + exit(1) ; + } + + memcpy( (char*)&(adr_dest.sin_addr.s_addr), + hp->h_addr, + hp->h_length ) ; + + for (int i = 0; i < nb_message; i++) { + // Construction du message + construire_message(message, 'a' + (i % 26), BASE_SIZE); + + // Envoi du message + + sendto(sock,message,longueur_message,0,(struct sockaddr*)&adr_dest,longueur_adr_dest); + } + exit(0); + } else { // UDP & Puit + // Creation de l'adresse du socket distant + struct sockaddr_in adr_locale; + int longueur_adr_locale = sizeof(adr_locale); + + int longueur_message = BASE_SIZE; + + memset((char *)& adr_locale, 0, sizeof(adr_locale)) ; + + adr_locale.sin_family=AF_INET; + adr_locale.sin_port=port; + adr_locale.sin_addr.s_addr = INADDR_ANY; + + // Bind the local socket to any local address (ie any available interface) + if (bind(sock, (struct sockaddr *) &adr_locale, longueur_adr_locale) == -1) { + printf("failed to bind\n"); + exit(1); + } + + while (1) { + // Receive a single message because we are lazy + recvfrom(sock, message, longueur_message, 0, NULL, NULL); + + // Afficher notre seule et unique triste message + afficher_message(message, longueur_message); + } + exit(0); + } + } +} + void construire_message(char *message, char motif, int lg) { int i; for (i=0;ih_addr, - hp->h_length ) ; - - for (int i = 0; i < nb_message; i++) { - // Construction du message - construire_message(message, 'a' + (i % 26), BASE_SIZE); - - // Envoi du message - - sendto(sock,message,longueur_message,0,(struct sockaddr*)&adr_dest,longueur_adr_dest); - } - - exit(0); - - } - - else { - - - // Creation de l'adresse du socket distant - struct sockaddr_in adr_locale; - int longueur_adr_locale = sizeof(adr_locale); - - int longueur_message = BASE_SIZE; - - memset((char *)& adr_locale, 0, sizeof(adr_locale)) ; - - adr_locale.sin_family=AF_INET; - adr_locale.sin_port=port; - adr_locale.sin_addr.s_addr = INADDR_ANY; - - // Bind the local socket to any local address (ie any available interface) - if (bind(sock, (struct sockaddr *) &adr_locale, longueur_adr_locale) == -1) { - printf("failed to bind\n"); - exit(1); - } - - while (1) { - // Receive a single message because we are lazy - recvfrom(sock, message, longueur_message, 0, NULL, NULL); - - // Afficher notre seule et unique triste message - afficher_message(message, longueur_message); - } - - exit(0); - - - - } - } +void print_usage(char* arg0) { + printf("usage: %s <-u> [-ps] [host] \n", arg0); + printf("parameters: host With -s, address of the host to connect to. Required with -s.\n"); + printf(" port Port to connect or bind to. Required.\n"); + printf("options: -p Runs a TCP/UDP sink. Incompatible with -s.\n"); + printf(" -s Runs a TCP/UDP faucet. Incompatible with -p.\n"); + printf(" -u Use UDP instead of TCP. Required.\n"); } diff --git a/tsock_v2.c b/tsock_v2.c index 8588426..bb381d8 100644 --- a/tsock_v2.c +++ b/tsock_v2.c @@ -11,7 +11,7 @@ /* constantes et structures propres au domaine INTERNET */ #include /* structures retournées par les fonctions de gestion de la base de -données du réseau */ + données du réseau */ #include /* pour les entrées/sorties */ #include @@ -19,6 +19,234 @@ données du réseau */ #include #define BASE_SIZE 10 +void construire_message(char *message, char motif, int lg); +void afficher_message(char *message, int lg); +void print_usage(char* arg0); + +int main (int argc, char **argv) { + int c; + extern char *optarg; + extern int optind; + int nb_message = -1; /* Nb de messages à envoyer ou à recevoir, par défaut : 10 en émission, infini en réception */ + int source = -1 ; /* 0=puits, 1=source */ + int udp=0; /* 0=TCP, 1=UDP */ + + while ((c = getopt(argc, argv, "pn:su")) != -1) { + switch (c) { + case 'p': + if (source == 1) { + print_usage(argv[0]); + exit(1); + } + source = 0; + break; + + case 's': + if (source == 0) { + print_usage(argv[0]); + exit(1) ; + } + source = 1; + break; + + case 'n': + nb_message = atoi(optarg); + break; + + case 'u': + udp=1; + break; + + default: + print_usage(argv[0]); + exit(1); + } + } + + char* nom_machine_distante; + + // Recuperation du port + int port=atoi(argv[argc-1]); + port = htons(port); + + char* message = malloc(BASE_SIZE * sizeof(char)); + + if (source == -1) { + print_usage(argv[0]); + exit(1) ; + } + + if (source == 1) { + //Recuperation du nom logique + nom_machine_distante=argv[argc-2]; + } else printf("PUITS:"); + + + if (nb_message != -1) { + if (source == 1) + printf("nb de tampons à envoyer : %d\n", nb_message); + else + printf("nb de tampons à recevoir : %d\n", nb_message); + } else { + if (source == 1) { + nb_message = 10 ; + printf("nb de tampons à envoyer = 10 par défaut\n"); + } else + printf("nb de tampons à envoyer = infini\n"); + } + + if (udp==1){ + // Creation du socket local + int sock= socket(AF_INET,SOCK_DGRAM,0); + + if (source==1) { + + + + // Creation de l'adresse du socket distant + struct hostent *hp ; + struct sockaddr_in adr_dest; + int longueur_adr_dest = sizeof(adr_dest); + + int longueur_message = BASE_SIZE; + + memset((char *)& adr_dest, 0, sizeof(adr_dest)) ; + + adr_dest.sin_family=AF_INET; + adr_dest.sin_port=port; + + + if ((hp = gethostbyname(nom_machine_distante)) == NULL) { + printf("erreur gethostbyname\n") ; + exit(1) ; + } + + memcpy( (char*)&(adr_dest.sin_addr.s_addr), + hp->h_addr, + hp->h_length ) ; + + for (int i = 0; i < nb_message; i++) { + // Construction du message + construire_message(message, 'a' + (i % 26), BASE_SIZE); + + // Envoi du message + + sendto(sock,message,longueur_message,0,(struct sockaddr*)&adr_dest,longueur_adr_dest); + } + } else { // UDP & puit + // Creation de l'adresse du socket distant + struct sockaddr_in adr_locale; + int longueur_adr_locale = sizeof(adr_locale); + + int longueur_message = BASE_SIZE; + + memset((char *)& adr_locale, 0, sizeof(adr_locale)) ; + + adr_locale.sin_family=AF_INET; + adr_locale.sin_port=port; + adr_locale.sin_addr.s_addr = INADDR_ANY; + + // Bind the local socket to any local address (ie any available interface) + if (bind(sock, (struct sockaddr *) &adr_locale, longueur_adr_locale) == -1) { + printf("failed to bind\n"); + exit(1); + } + + while (1) { + // Receive a single message because we are lazy + recvfrom(sock, message, longueur_message, 0, NULL, NULL); + + // Afficher notre seule et unique triste message + afficher_message(message, longueur_message); + } + } + } else { // TCP + // Creation du socket local + int sock= socket(AF_INET,SOCK_STREAM,0); + + if (source==1) { + // Creation de l'adresse du socket distant + struct hostent *hp ; + struct sockaddr_in adr_dest; + int longueur_adr_dest = sizeof(adr_dest); + + int longueur_message = BASE_SIZE; + + memset((char *)& adr_dest, 0, sizeof(adr_dest)) ; + + adr_dest.sin_family=AF_INET; + adr_dest.sin_port=port; + + + if ((hp = gethostbyname(nom_machine_distante)) == NULL) { + printf("erreur gethostbyname\n") ; + exit(1) ; + } + + memcpy( (char*)&(adr_dest.sin_addr.s_addr), + hp->h_addr, + hp->h_length ) ; + + // Demande de connexion + int succ; + if ((succ=connect(sock,(struct sockaddr*) &adr_dest,longueur_adr_dest))!=0){ + printf("Echec connect"); + exit(1); + } + + // Envoie des messages + for (int i = 0; i < nb_message; i++) { + // Construction du message + construire_message(message, 'a' + (i % 26), BASE_SIZE); + + // Envoi du message + write(sock,message,longueur_message); + } + + // Close socket to avoid dangling connections + close(sock); + } else { // TCP & puit + // Creation de l'adresse du socket local + struct sockaddr_in adr_locale; + socklen_t longueur_adr_locale = sizeof(adr_locale); + + int longueur_message = BASE_SIZE; + + memset((char *)& adr_locale, 0, sizeof(adr_locale)) ; + + adr_locale.sin_family=AF_INET; + adr_locale.sin_port=port; + adr_locale.sin_addr.s_addr = INADDR_ANY; + + // Bind the local socket to any local address (ie any available interface) + if (bind(sock, (struct sockaddr *) &adr_locale, longueur_adr_locale) == -1) { + printf("failed to bind\n"); + exit(1); + } + + // set linstening queue size + if (listen(sock, 5) == -1) { + printf("échec et mat listen\n"); + exit(1); + } + + int sock_bis; + // Accept a single connection on the main thread + if ((sock_bis = accept( sock, (struct sockaddr *)&adr_locale, &longueur_adr_locale)) == -1){ + printf("échec du accept\n") ; + exit(1) ; + } + + while (read(sock_bis, message, longueur_message) > 0) { + afficher_message(message, longueur_message); + } + close(sock_bis); + close(sock); + } + } + exit(0); +} + void construire_message(char *message, char motif, int lg) { int i; for (i=0;ih_addr, - hp->h_length ) ; - - for (int i = 0; i < nb_message; i++) { - // Construction du message - construire_message(message, 'a' + (i % 26), BASE_SIZE); - - // Envoi du message - - sendto(sock,message,longueur_message,0,(struct sockaddr*)&adr_dest,longueur_adr_dest); - } - - - } - - else { - - - // Creation de l'adresse du socket distant - struct sockaddr_in adr_locale; - int longueur_adr_locale = sizeof(adr_locale); - - int longueur_message = BASE_SIZE; - - memset((char *)& adr_locale, 0, sizeof(adr_locale)) ; - - adr_locale.sin_family=AF_INET; - adr_locale.sin_port=port; - adr_locale.sin_addr.s_addr = INADDR_ANY; - - // Bind the local socket to any local address (ie any available interface) - if (bind(sock, (struct sockaddr *) &adr_locale, longueur_adr_locale) == -1) { - printf("failed to bind\n"); - exit(1); - } - - while (1) { - // Receive a single message because we are lazy - recvfrom(sock, message, longueur_message, 0, NULL, NULL); - - // Afficher notre seule et unique triste message - afficher_message(message, longueur_message); - } - - - - - } - } - - else{ - - // Creation du socket local - int sock= socket(AF_INET,SOCK_STREAM,0); - - if (source==1) { - - - - // Creation de l'adresse du socket distant - struct hostent *hp ; - struct sockaddr_in adr_dest; - int longueur_adr_dest = sizeof(adr_dest); - - int longueur_message = BASE_SIZE; - - memset((char *)& adr_dest, 0, sizeof(adr_dest)) ; - - adr_dest.sin_family=AF_INET; - adr_dest.sin_port=port; - - - if ((hp = gethostbyname(nom_machine_distante)) == NULL) { - printf("erreur gethostbyname\n") ; - exit(1) ; - } - - memcpy( (char*)&(adr_dest.sin_addr.s_addr), - hp->h_addr, - hp->h_length ) ; - - // Demande de connexion - int succ; - if ((succ=connect(sock,(struct sockaddr*) &adr_dest,longueur_adr_dest))!=0){ - printf("Echec connect"); - exit(1); - } - - // Envoie des messages - for (int i = 0; i < nb_message; i++) { - // Construction du message - construire_message(message, 'a' + (i % 26), BASE_SIZE); - - // Envoi du message - write(sock,message,longueur_message); - } - - // Close socket to avoid dangling connections - close(sock); - - - } - - else { - - - // Creation de l'adresse du socket local - struct sockaddr_in adr_locale; - socklen_t longueur_adr_locale = sizeof(adr_locale); - - int longueur_message = BASE_SIZE; - - memset((char *)& adr_locale, 0, sizeof(adr_locale)) ; - - adr_locale.sin_family=AF_INET; - adr_locale.sin_port=port; - adr_locale.sin_addr.s_addr = INADDR_ANY; - - // Bind the local socket to any local address (ie any available interface) - if (bind(sock, (struct sockaddr *) &adr_locale, longueur_adr_locale) == -1) { - printf("failed to bind\n"); - exit(1); - } - - // set linstening queue size - if (listen(sock, 5) == -1) { - printf("échec et mat listen\n"); - exit(1); - } - - int sock_bis; - // Accept a single connection on the main thread - if ((sock_bis = accept( sock, (struct sockaddr *)&adr_locale, &longueur_adr_locale)) == -1){ - printf("échec du accept\n") ; - exit(1) ; - } - - while (read(sock_bis, message, longueur_message) > 0) { - afficher_message(message, longueur_message); - } - close(sock_bis); - close(sock); - - - - - } - } - - exit(0); +void print_usage(char* arg0) { + printf("usage: %s [-psu] [host] \n", arg0); + printf("parameters: host With -s, address of the host to connect to. Required with -s.\n"); + printf(" port Port to connect or bind to. Required.\n"); + printf("options: -p Runs a TCP/UDP sink. Incompatible with -s.\n"); + printf(" -s Runs a TCP/UDP faucet. Incompatible with -p.\n"); + printf(" -u Use UDP instead of TCP.\n"); } - diff --git a/tsock_v3.c b/tsock_v3.c index 2ee4e8c..5112285 100644 --- a/tsock_v3.c +++ b/tsock_v3.c @@ -11,366 +11,344 @@ /* constantes et structures propres au domaine INTERNET */ #include /* structures retournées par les fonctions de gestion de la base de -données du réseau */ + données du réseau */ #include /* pour les entrées/sorties */ #include /* pour la gestion des erreurs */ #include -#define BASE_SIZE 10 - -void construire_message(char* message, char motif, int lg); +// Remplit le message de lg caractères motif +void construire_message(char *message, char motif, int lg, int numero_envoi); // Affichage distinct entre envoi et reception pour une facilité d'utilisation void afficher_message_envoi(char *message, int lg, int numero_envoi); void afficher_message_reception(char *message, int lg, int numero_envoi); // Permet de compter le nombre de digits d'un nombre, utile pour l'affichage [--143 ...] +// (base 10) int count_digits(int lg); +// Affiche l'usage de l'outil +void print_usage(char* arg0); + int main (int argc, char **argv) { - int c; - extern char *optarg; - extern int optind; - int nb_message = -1; /* Nb de messages à envoyer ou à recevoir, par défaut : 10 en émission, infini en réception */ - int source = -1 ; /* 0=puits, 1=source */ - int udp=0; /* 0=TCP, 1=UDP */ - int lg=-1; /* Longueur des messages à envoyer ou recevoir: par défaut 30 octets */ + int c; + extern char *optarg; + extern int optind; + int nb_message = -1; /* Nb de messages à envoyer ou à recevoir, par défaut : 10 en émission, infini en réception */ + int source = -1 ; /* 0=puits, 1=source */ + int udp=0; /* 0=TCP, 1=UDP */ + int lg=-1; /* Longueur des messages à envoyer ou recevoir: par défaut 30 octets */ - while ((c = getopt(argc, argv, "pn:sul:")) != -1) { - switch (c) { - case 'p': - if (source == 1) { - printf("usage: cmd [-p|-s][-n ##]\n"); - exit(1); - } - source = 0; - break; + while ((c = getopt(argc, argv, "pn:sul:")) != -1) { + switch (c) { + case 'p': + if (source == 1) { + print_usage(argv[0]); + exit(1); + } + source = 0; + break; - case 's': - if (source == 0) { - printf("usage: cmd [-p|-s][-n ##]\n"); - exit(1) ; - } - source = 1; - break; + case 's': + if (source == 0) { + print_usage(argv[0]); + exit(1) ; + } + source = 1; + break; - case 'n': - nb_message = atoi(optarg); - // Packets are numerotated with 5 figures, which means the number of - // packets send can't be bigger than (or equal) 10 ** 6 - if(nb_message >= 100000) { - printf("Too many packets"); - exit(1); - } + case 'n': + nb_message = atoi(optarg); + // Packets are numerotated with 5 figures, which means the number of + // packets send can't be bigger than (or equal) 10 ** 6 + if (nb_message >= 100000) { + printf("Too many packets. (Max 99999)\n"); + exit(1); + } else if (nb_message <= 0) { + printf("Lets try to send all at least one message (:\n"); + exit(1); + } + break; - break; + case 'u': + udp=1; + break; - case 'u': - udp=1; - break; - - case 'l': - lg=atoi(optarg); - // A TCP packet is roughly 1500 bytes. We allow for some overhead. - // We provide an MTU of 1400 bytes. - if(lg >= 1400) { - printf("Messages too long"); - exit(1); - } - break; - - default: - printf("usage: cmd [-p|-s][-n ##]\n"); - break; - } - } - - char* nom_machine_distante; - - // Recuperation du port - int port=atoi(argv[argc-1]); - //port = htons(port); - - // Default set of packet length : 30 bytes - if (lg == -1) { - lg=30; - } - - //Allocation du message, il est de la taille donnée en paramètre - char* message = malloc(lg * sizeof(char)); - - - if (source == -1) { - printf("usage: cmd [-p|-s][-n ##]\n"); - exit(1) ; - } - - // If number of messages is not fixed for the source, it is set to 10 messages - if (nb_message == -1 && source ) { - nb_message = 10 ; - } - - - //Affichage des informations de communication initiée - if (source == 1) { - //Recuperation du nom logique - nom_machine_distante=argv[argc-2]; - printf("SOURCE:lg_mesg_emis=%d,port=%d,nb_envois=%d,TP=%s,dest=%s\n", - lg,port,nb_message,(udp)?"UDP":"TCP",nom_machine_distante); - } else { - printf("PUITS:lg_mesg-lu=%d,port=%d,nb_receptions=",lg,port); - if (nb_message!=-1 && !source) { - printf("infini"); - } - else { - printf("%d",nb_message); - } - printf(", TP=%s\n",(udp)?"UDP":"TCP"); - } - - - // Communnication through UDP messages - if (udp==1){ - // Creation du socket local - int sock= socket(AF_INET,SOCK_DGRAM,0); - - if (source==1) { - - - - // Creation de l'adresse du socket distant - struct hostent *hp ; - struct sockaddr_in adr_dest; - int longueur_adr_dest = sizeof(adr_dest); - - int longueur_message = lg; - - memset((char *)& adr_dest, 0, sizeof(adr_dest)) ; - - adr_dest.sin_family=AF_INET; - adr_dest.sin_port=port; - - - if ((hp = gethostbyname(nom_machine_distante)) == NULL) { - printf("erreur gethostbyname\n") ; - exit(1) ; - } - - memcpy( (char*)&(adr_dest.sin_addr.s_addr), - hp->h_addr, - hp->h_length ) ; - - for (int i = 0; i < nb_message; i++) { - // Construction du message - construire_message(message, 'a' + (i % 26), lg); - - // Envoi du message - afficher_message_envoi(message,lg,i+1); - sendto(sock,message,longueur_message,0,(struct sockaddr*)&adr_dest,longueur_adr_dest); - } - - - } - - else { - - - // Creation de l'adresse du socket distant - struct sockaddr_in adr_locale; - int longueur_adr_locale = sizeof(adr_locale); - - memset((char *)& adr_locale, 0, sizeof(adr_locale)) ; - - adr_locale.sin_family=AF_INET; - adr_locale.sin_port=port; - adr_locale.sin_addr.s_addr = INADDR_ANY; - - // Bind the local socket to any local address (ie any available interface) - if (bind(sock, (struct sockaddr *) &adr_locale, longueur_adr_locale) == -1) { - printf("failed to bind\n"); - exit(1); - } - - // Suivi du numéro de message reçu - int k=0; - - while (1) { - // Receive a single message because we are lazy - recvfrom(sock, message, lg, 0, NULL, NULL); - k++; - // Afficher notre seule et unique triste message - afficher_message_reception(message, lg, k); - } - - - - - } + case 'l': + lg=atoi(optarg); + // A TCP packet is roughly 1500 bytes. We allow for some overhead. + // We provide an MTU of 1400 bytes. + if(lg >= 1400) { + printf("Messages too long (max 1400)\n"); + exit(1); + } else if (lg < 5) { + // The message size includes the message number, whos size is 5. + printf("Messages too short (min 5)\n"); + exit(1); } - else{ - - // Creation du socket local - int sock= socket(AF_INET,SOCK_STREAM,0); + break; - if (source==1) { + default: + print_usage(argv[0]); + exit(1); + } + } + + char* nom_machine_distante; + + // Recuperation du port + int port=atoi(argv[argc-1]); + //port = htons(port); + + // Default set of packet length : 30 bytes + if (lg == -1) { + lg=30; + } + + // Allocation du message, il est de la taille donnée en paramètre + char* message = malloc(lg * sizeof(char)); + if (source == -1) { + print_usage(argv[0]); + exit(1) ; + } - // Creation de l'adresse du socket distant - struct hostent *hp ; - struct sockaddr_in adr_dest; - int longueur_adr_dest = sizeof(adr_dest); + // If number of messages is not fixed for the source, it is set to 10 messages + if (nb_message == -1 && source ) { + nb_message = 10 ; + } - int longueur_message = lg; - - memset((char *)& adr_dest, 0, sizeof(adr_dest)) ; - - adr_dest.sin_family=AF_INET; - adr_dest.sin_port=port; + //Affichage des informations de communication initiée + if (source == 1) { + //Recuperation du nom logique + nom_machine_distante=argv[argc-2]; + printf("SOURCE:lg_mesg_emis=%d,port=%d,nb_envois=%d,TP=%s,dest=%s\n", + lg,port,nb_message,(udp)?"UDP":"TCP",nom_machine_distante); + } else { + printf("PUITS:lg_mesg_lu=%d,port=%d,nb_receptions=",lg,port); + if (nb_message!=-1 && !source) { + printf("infini"); + } + else { + printf("%d",nb_message); + } + printf(", TP=%s\n",(udp)?"UDP":"TCP"); + } - if ((hp = gethostbyname(nom_machine_distante)) == NULL) { - printf("erreur gethostbyname\n") ; - exit(1) ; - } + // Communnication through UDP datagrams + if (udp==1){ + // Creation du socket local + int sock= socket(AF_INET,SOCK_DGRAM,0); - memcpy( (char*)&(adr_dest.sin_addr.s_addr), - hp->h_addr, - hp->h_length ) ; - - // Demande de connexion - int succ; - if ((succ=connect(sock,(struct sockaddr*) &adr_dest,longueur_adr_dest))!=0){ - printf("Echec connect"); - exit(1); - } + if (source==1) { + // Creation de l'adresse du socket distant + struct hostent *hp ; + struct sockaddr_in adr_dest; + int longueur_adr_dest = sizeof(adr_dest); - // Envoi des messages - for (int i = 0; i < nb_message; i++) { - // Construction du message - construire_message(message, 'a' + (i % 26), lg); - afficher_message_envoi(message,lg,i+1); - // Envoi du message - write(sock,message,longueur_message); - } + int longueur_message = lg; - // Close socket to avoid dangling connections - close(sock); + memset((char *)& adr_dest, 0, sizeof(adr_dest)) ; - - } - - else { + adr_dest.sin_family=AF_INET; + adr_dest.sin_port=port; - // Creation de l'adresse du socket local - struct sockaddr_in adr_locale; - socklen_t longueur_adr_locale = sizeof(adr_locale); + if ((hp = gethostbyname(nom_machine_distante)) == NULL) { + printf("erreur gethostbyname\n") ; + exit(1) ; + } - int longueur_message = lg; - - memset((char *)& adr_locale, 0, sizeof(adr_locale)) ; - - adr_locale.sin_family=AF_INET; - adr_locale.sin_port=port; - adr_locale.sin_addr.s_addr = INADDR_ANY; + memcpy( (char*)&(adr_dest.sin_addr.s_addr), + hp->h_addr, + hp->h_length ) ; - // Bind the local socket to any local address (ie any available interface) - if (bind(sock, (struct sockaddr *) &adr_locale, longueur_adr_locale) == -1) { - printf("failed to bind\n"); - exit(1); - } + for (int i = 0; i < nb_message; i++) { + // Construction du message + construire_message(message, 'a' + (i % 26), lg, i+1); - // set linstening queue size - if (listen(sock, 5) == -1) { - printf("échec et mat listen\n"); - exit(1); - } + // Envoi du message + afficher_message_envoi(message,lg,i+1); + sendto(sock,message,longueur_message,0,(struct sockaddr*)&adr_dest,longueur_adr_dest); + } + } else { // UDP & puit + // Creation de l'adresse du socket local + struct sockaddr_in adr_locale; + int longueur_adr_locale = sizeof(adr_locale); - int sock_bis; - // Accept a single connection on the main thread - if ((sock_bis = accept( sock, (struct sockaddr *)&adr_locale, &longueur_adr_locale)) == -1){ - printf("échec du accept\n") ; - exit(1) ; - } + memset((char *)& adr_locale, 0, sizeof(adr_locale)) ; - // Suivi du numéro de message reçu - int k=0; + adr_locale.sin_family=AF_INET; + adr_locale.sin_port=port; + adr_locale.sin_addr.s_addr = INADDR_ANY; - while (read(sock_bis, message, longueur_message) > 0) { - afficher_message_reception(message, longueur_message,k); - k++; - } - close(sock_bis); - close(sock); - } - } + // Bind the local socket to any local address (ie any available interface) + if (bind(sock, (struct sockaddr *) &adr_locale, longueur_adr_locale) == -1) { + printf("failed to bind\n"); + exit(1); + } - exit(0); + // Suivi du numéro de message reçu + int k=1; + + while (1) { + // Receive a single message because we are lazy + recvfrom(sock, message, lg, 0, NULL, NULL); + // Afficher notre seule et unique triste message + afficher_message_reception(message, lg, k); + k++; + } + } + } else { // TCP + // Creation du socket local + int sock= socket(AF_INET,SOCK_STREAM,0); + + if (source==1) { + // Creation de l'adresse du socket distant + struct hostent *hp ; + struct sockaddr_in adr_dest; + int longueur_adr_dest = sizeof(adr_dest); + + int longueur_message = lg; + + memset((char *)& adr_dest, 0, sizeof(adr_dest)) ; + + adr_dest.sin_family=AF_INET; + adr_dest.sin_port=port; + + + if ((hp = gethostbyname(nom_machine_distante)) == NULL) { + printf("erreur gethostbyname\n") ; + exit(1) ; + } + + memcpy( (char*)&(adr_dest.sin_addr.s_addr), + hp->h_addr, + hp->h_length ) ; + + // Demande de connexion + int succ; + if ((succ=connect(sock,(struct sockaddr*) &adr_dest,longueur_adr_dest))!=0){ + printf("Echec connect\n"); + exit(1); + } + + // Envoi des messages + for (int i = 0; i < nb_message; i++) { + // Construction du message + construire_message(message, 'a' + (i % 26), lg, i+1); + afficher_message_envoi(message,lg,i+1); + // Envoi du message + write(sock,message,longueur_message); + } + + // Close socket to avoid dangling connections + close(sock); + } else { // TCP & puit + // Creation de l'adresse du socket local + struct sockaddr_in adr_locale; + socklen_t longueur_adr_locale = sizeof(adr_locale); + + int longueur_message = lg; + + memset((char *)& adr_locale, 0, sizeof(adr_locale)) ; + + adr_locale.sin_family=AF_INET; + adr_locale.sin_port=port; + adr_locale.sin_addr.s_addr = INADDR_ANY; + + // Bind the local socket to any local address (ie any available interface) + if (bind(sock, (struct sockaddr *) &adr_locale, longueur_adr_locale) == -1) { + printf("failed to bind\n"); + exit(1); + } + + // set linstening queue size + if (listen(sock, 5) == -1) { + printf("échec et mat listen\n"); + exit(1); + } + + int sock_bis; // Socket correspondant à la connexion TCP initiée par la source + // Accept a single connection on the main thread + if ((sock_bis = accept( sock, (struct sockaddr *)&adr_locale, &longueur_adr_locale)) == -1){ + printf("échec du accept\n") ; + exit(1) ; + } + + // Suivi du numéro de message reçu + int k=1; + + while (read(sock_bis, message, longueur_message) > 0) { + afficher_message_reception(message, longueur_message,k); + k++; + } + close(sock_bis); + close(sock); + } + } + + exit(0); } -void construire_message(char *message, char motif, int lg) { +void construire_message(char *message, char motif, int lg, int numero_envoi) { int i; - for (i=0;inb_digits; l--) { - printf("-"); + for (i=0;inb_digits; l--) { - printf("-"); + for (i=0;i 0) { + lg/=10; + retour++; + } + } - if (!lg){ - retour=1; - } - else { - retour=0; - while (lg > 0) { - lg/=10; - retour++; - } - } - - return retour; + return retour; +} + +void print_usage(char* arg0) { + printf("usage: %s [-psu] [-n nb_messages] [-l mess_length] [host] \n", arg0); + printf("parameters: host With -s, address of the host to connect to. Required with -s.\n"); + printf(" port Port to connect or bind to. Required.\n"); + printf("options: -l mess_length Size of the messages to send. Min 5. Max 1400. Default 30.\n"); + printf(" -n nb_messages Number of messages to send. Min 1. Default 10. Ignored with -p.\n"); + printf(" -p Runs a TCP/UDP sink. Incompatible with -s.\n"); + printf(" -s Runs a TCP/UDP faucet. Incompatible with -p.\n"); + printf(" -u Use UDP instead of TCP.\n"); }