diff --git a/tsock_v4.c b/tsock_v4.c index 8198905..084ef40 100644 --- a/tsock_v4.c +++ b/tsock_v4.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 @@ -28,354 +28,354 @@ void afficher_message_reception(char *message, int lg, int numero_envoi); 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 client = 0; /* 0 not client, 1 client */ - int serveur = 0; /* 0 not server, 1 server */ - int emetteur = 0; /* 0 not sender, 1 sender */ - int recepteur = 0; /* 0 not receiver, 1 receiver */ + 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 client = 0; /* 0 not client, 1 client */ + int serveur = 0; /* 0 not server, 1 server */ + int emetteur = 0; /* 0 not sender, 1 sender */ + int recepteur = 0; /* 0 not receiver, 1 receiver */ - while ((c = getopt(argc, argv, "pn:sul:CSer")) != -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:CSer")) != -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); - // 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); - } - - 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. - // We also to send at least a message of 5 characters length for indice packet - if(lg >= 1400 || lg < 5) { - printf("Messages too long"); - exit(1); - } - break; - /* -c and -e options stand only for TCP exchange */ - case 'C': - client=1; - if (udp == 1){ - printf("No option -C for UDP"); - exit(0); - } - break; - case 'S': - serveur = 1; - if (udp == 1){ - printf("No option -S for UDP"); - exit(0); - } - break; - case 'e': - emetteur=1; - if (udp == 1 || recepteur == 1){ - printf("Missuse of -e option"); - exit(0); - } - break; - case 'r': - recepteur=1; - if (udp == 1 || emetteur == 1){ - printf("Missuse of -r option"); - exit(0); - } - break; - default: - printf("usage: cmd [-p|-s][-n ##]\n"); - break; - } - } - - if (!recepteur && !emetteur && !udp) { - printf("Need to specify sender or receiver for TCP connexion"); - exit(0); - } - - 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 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 || client) { - //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"); - } - - - /*******************************UDP COMMUNICATION*************************************/ - 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, i+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 { - - - // 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 (recvfrom(sock, message, lg, 0, NULL, NULL)) { - - k++; - // Afficher notre seule et unique triste message - afficher_message_reception(message, lg, k); - } - - } + 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); } + break; - /*******************************TCP COMMUNICATION*************************************/ + case 'u': + udp=1; + break; - else{ - - // Creation du socket local - int sock= socket(AF_INET,SOCK_STREAM,0); + case 'l': + lg=atoi(optarg); + // A TCP packet is roughly 1500 bytes. We allow for some overhead. + // We provide an MTU of 1400 bytes. + // We also to send at least a message of 5 characters length for indice packet + if(lg >= 1400 || lg < 5) { + printf("Messages too long"); + exit(1); + } + break; + /* -c and -e options stand only for TCP exchange */ + case 'C': + client=1; + if (udp == 1){ + printf("No option -C for UDP"); + exit(0); + } + break; + case 'S': + serveur = 1; + if (udp == 1){ + printf("No option -S for UDP"); + exit(0); + } + break; + case 'e': + emetteur=1; + if (udp == 1 || recepteur == 1){ + printf("Missuse of -e option"); + exit(0); + } + break; + case 'r': + recepteur=1; + if (udp == 1 || emetteur == 1){ + printf("Missuse of -r option"); + exit(0); + } + break; + default: + printf("usage: cmd [-p|-s][-n ##]\n"); + break; + } + } - //The server shall establish the connexion - if (client) { - - // 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"); - exit(1); - } - - - // Envoi des messages - for (int i = 0; i < nb_message; i++) { - - if (emetteur){ - // 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); - } - if (recepteur) { - if ((read(sock, message, longueur_message)) < 0){ - printf("échec du read\n") ; exit(1) ;} - afficher_message_reception(message, longueur_message,i+1) ; - - } - } - - - - - // Close socket to avoid dangling connections - close(sock); - - - } - - // The server shall accept the connexion - if (serveur) { - - - // 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 listening queue size - if (listen(sock, QUEUE_SIZE) == -1) { - printf("échec et mat listen\n"); - exit(1); - } - - int sock_bis; - - while(1) { - // 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) ; - } - printf("socket accepte:%d\n",sock_bis); - - - switch (fork() ) { - case - 1 : /* il y a une erreur */ - printf("erreur fork\n") ; exit(1) ; - case 0 : /* on est dans le proc. fils */ - close(sock) ; /* fermeture socket du proc. père */ - for (int i=0 ; i < nb_message ; i ++) { - - // Server send packets - if (emetteur){ - // Construction du message - construire_message(message, 'a' + (i % 26), lg, i+1); - afficher_message_envoi(message,lg,i+1); - // Envoi du message - write(sock_bis,message,longueur_message); - } - // Server receives packets - if (recepteur) { - if ((read(sock_bis, message, longueur_message)) < 0){ - printf("échec du read\n") ; exit(1) ;} - afficher_message_reception(message, longueur_message,i+1) ; - } - } - close(sock_bis); - exit(0) ; - default : /* on est dans le proc. père */ - close(sock_bis) ; /* fermeture socket du proc. fils - Connexion stay opened for further exchanges */ - } - } - } - } + if (!recepteur && !emetteur && !udp) { + printf("Need to specify sender or receiver for TCP connexion"); exit(0); + } + + 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 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 || client) { + //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"); + } + + + /*******************************UDP COMMUNICATION*************************************/ + 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, i+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 { + + + // 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 (recvfrom(sock, message, lg, 0, NULL, NULL)) { + + k++; + // Afficher notre seule et unique triste message + afficher_message_reception(message, lg, k); + } + + } + } + + + /*******************************TCP COMMUNICATION*************************************/ + + else{ + + // Creation du socket local + int sock= socket(AF_INET,SOCK_STREAM,0); + + //The server shall establish the connexion + if (client) { + + // 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"); + exit(1); + } + + + // Envoi des messages + for (int i = 0; i < nb_message; i++) { + + if (emetteur){ + // 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); + } + if (recepteur) { + if ((read(sock, message, longueur_message)) < 0){ + printf("échec du read\n") ; exit(1) ;} + afficher_message_reception(message, longueur_message,i+1) ; + + } + } + + + + + // Close socket to avoid dangling connections + close(sock); + + + } + + // The server shall accept the connexion + if (serveur) { + + + // 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 listening queue size + if (listen(sock, QUEUE_SIZE) == -1) { + printf("échec et mat listen\n"); + exit(1); + } + + int sock_bis; + + while(1) { + // 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) ; + } + printf("socket accepte:%d\n",sock_bis); + + + switch (fork() ) { + case - 1 : /* il y a une erreur */ + printf("erreur fork\n") ; exit(1) ; + case 0 : /* on est dans le proc. fils */ + close(sock) ; /* fermeture socket du proc. père */ + for (int i=0 ; i < nb_message ; i ++) { + + // Server send packets + if (emetteur){ + // Construction du message + construire_message(message, 'a' + (i % 26), lg, i+1); + afficher_message_envoi(message,lg,i+1); + // Envoi du message + write(sock_bis,message,longueur_message); + } + // Server receives packets + if (recepteur) { + if ((read(sock_bis, message, longueur_message)) < 0){ + printf("échec du read\n") ; exit(1) ;} + afficher_message_reception(message, longueur_message,i+1) ; + } + } + close(sock_bis); + exit(0) ; + default : /* on est dans le proc. père */ + close(sock_bis) ; /* fermeture socket du proc. fils + Connexion stay opened for further exchanges */ + } + } + } + } + exit(0); } @@ -388,11 +388,11 @@ void construire_message(char *message, char motif, int lg, int numero_envoi) { void afficher_message_envoi(char *message, int lg, int numero_envoi) { int i; printf("SOURCE: Envoi n°%d (%d) [",numero_envoi,lg); - + for (i=0;i