diff --git a/LACAU-Clement-Pseudos_codes.pdf b/LACAU-Clement-Pseudos_codes.pdf new file mode 100644 index 0000000..6f81a67 Binary files /dev/null and b/LACAU-Clement-Pseudos_codes.pdf differ diff --git a/tsock_v4.c b/tsock_v4.c new file mode 100644 index 0000000..5164038 --- /dev/null +++ b/tsock_v4.c @@ -0,0 +1,353 @@ +/* librairie standard ... */ +#include +/* pour getopt */ +#include +/* déclaration des types de base */ +#include +/* constantes relatives aux domaines, types et protocoles */ +#include +/* constantes et structures propres au domaine UNIX */ +#include +/* 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 */ +#include +/* pour les entrées/sorties */ +#include +/* pour la gestion des erreurs */ +#include +#define QUEUE_SIZE 5 + +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); + + +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 */ + + 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; + + 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; + + 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, 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); + } + + + + + } + } + + 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 = 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++) { + // 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 { + + + // 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 ++) { + 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); +} + + +void construire_message(char *message, char motif, int lg, int numero_envoi) { + int i; + snprintf(message, lg,"% 5d",numero_envoi); + for (i=5;i