diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b4bf426 --- /dev/null +++ b/Makefile @@ -0,0 +1,53 @@ +CC=gcc +CFLAGS=-Wall +SRC=src/ +EXEC=main +CLEAN=clean + +all: $(EXEC) + +main: bal.o iptable.o main.o puit.o source.o tsock.o + $(CC) $(CFLAGS) -o $@ $^ + +bal.o: src/bal.c + $(CC) $(CFLAGS) -c $^ + +iptable.o: src/iptable.c + $(CC) $(CFLAGS) -c $^ + +main.o: src/main.c + $(CC) $(CFLAGS) -c $^ + +puit.o: src/puit.c + $(CC) $(CFLAGS) -c $^ + +source.o: src/source.c + $(CC) $(CFLAGS) -c $^ + +tsock.o: src/tsock.c + $(CC) $(CFLAGS) -c $^ + +clean: + rm -rf *.o + rm $(EXEC) + +boite: + ./$(EXEC) -b 9000 + +emetteur: + ./$(EXEC) -e 1 9000 localhost + +recepteur: + ./$(EXEC) -r 1 9000 localhost + +udpsource: + ./$(EXEC) -s -u 9000 localhost + +udppuit: + ./$(EXEC) -p -u 9000 + +source: + ./$(EXEC) -s 9000 localhost + +puit: + ./$(EXEC) -p 9000 \ No newline at end of file diff --git a/header/bal.h b/header/bal.h index a173347..2cde70f 100644 --- a/header/bal.h +++ b/header/bal.h @@ -3,66 +3,229 @@ #include "tsock.h" +/** + * @brief Fonction de test pour les différentes primitive de bal.h + * Inutilisée sur le programme final. + * + * @return int -> 0 si réussite + */ int bal(void); +/** + * @struct messageBAL + * @brief definition de la structure d'un message BAL + * + * @var messageBAL::data + * Messgae sous forme d'un tableau de caractère + * @var messageBAL::tailleData + * Taille du message + * @var messageBAL::idEmetteur + * Numéro de l'émetteur qui a envoyé le message + */ typedef struct{ char *data; int tailleData; int idEmetteur; }messageBAL; +/** + * @struct elementMessage + * @brief Element dans une liste de Messages + * + * @var elementMessage::messageBALActuel + * Pointeur vers le message de l'élément + * @var elementMessage::suiv + * Pointeur vers le prochain élément + */ struct elementMessage{ messageBAL * messageBALActuel; struct elementMessage * suiv; }; +/** + * @struct listeMessage + * @brief Liste d'éléments messages + * + * @var listeMessage::debut + * Pointeur vers le premier élément + * @var listeMessage::courant + * Pointeur vers l'élément sélectionné + * @var listeMessage::fin + * Pointeur vers l'élément final + */ struct listeMessage{ struct elementMessage * debut; struct elementMessage * courant; struct elementMessage * fin; + int nbMessages; }; +/** + * @struct BAL + * @brief definition de la structure d'une Boite aux Lettres + * + * @var BAL::idRecepteur + * Numéro du recepteur ayant reçu les messages + * @var BAL::actualMessages + * Liste pointant sur les messages reçus + */ typedef struct{ int idRecepteur; struct listeMessage * actualMessages; }BAL; +/** + * @struct elementBAL + * @brief Element dans une liste de Messages + * + * @var elementBAL::BALActuel + * Pointeur vers la boite aux lettres de l'élément + * @var elementBAL::suiv + * Pointeur vers le prochain élément + */ struct elementBAL{ BAL * BALActuel; struct elementBAL * suiv; }; +/** + * @struct listeBAL + * @brief Liste d'éléments BAL + * + * @var listeBAL::debut + * Pointeur vers le premier élément + * @var listeBAL::courant + * Pointeur vers l'élément sélectionné + * @var listeBAL::fin + * Pointeur vers l'élément final + */ struct listeBAL{ struct elementBAL * debut; struct elementBAL * courant; struct elementBAL * fin; }; +/** + * @brief Permet l'initialisation d'une struture messageBAL avec un message et un idEmetteur donné. + * + * @param data char*, chaîne de caractère de la donnée. + * @param idEmetteur int, numéro de l'émetteur du message. + * @return messageBAL* message initialisé avec les paramètres donnés. + */ messageBAL * creeMessage(char *data,int idEmetteur); -struct elementMessage * initElementMessage(void); -struct listeMessage * initListeMessage(void); -void ajoutListeMessage(struct listeMessage * listeActuel,messageBAL * leMessage); -void afficheListeMessage(struct listeMessage listeActuel); -int bal(void); +/** + * @brief Initialise la structure elementMessage avec un malloc. + * L'élément crée renvoi vers une adresse NULL. + * + * @return struct elementMessage* element initialisé + */ +struct elementMessage * initElementMessage(void); + +/** + * @brief Initialise plusieurs éléments (debut,courant et fin) avec initElementMessage(). + * + * @return struct listeMessage* liste de message NULL mais alloué. + */ +struct listeMessage * initListeMessage(void); + +/** + * @brief Ajoute un message dans la liste de message : + * Mets à jour le pointeur courant ainsi que debut. + * + * @param listeActuel struct listeMessage *,la liste à modifier. + * @param leMessage messageBAL*, pointeur sur le message à ajouter à la liste. + */ +void ajoutListeMessage(struct listeMessage * listeActuel,messageBAL * leMessage); + +/** + * @brief Affiche l'intégralité des Messages pour tous les Emetteurs. + * + * @param listeActuel struct listeMessage, liste à afficher. + */ +void afficheListeMessage(struct listeMessage listeActuel); + +/** + * @brief Permet l'initialisation d'une struture BAL avec un idRecepteur et un messageRecepteur donné. + * + * @param idRecepteur int, numéro du recepteur. + * @param messageRecepteur struct listeMessage*, liste des messages du recepteur. + * @return BAL* boite aux lettres initialisée avec les paramètres donnés. + */ BAL * creerBAL(int idRecepteur, struct listeMessage * messageRecepteur); + +/** + * @brief Initialise la structure elementBAL avec un malloc. + * L'élément crée renvoi vers une adresse NULL. + * + * @return struct elementBAL* element initialisé + */ struct elementBAL * initElementBAL(void); + +/** + * @brief Initialise plusieurs éléments (debut,courant et fin) avec initElementBAL(). + * + * @return struct listeBAL liste de Boite aux lettres NULLes mais allouées. + */ struct listeBAL initListeBAL(void); + +/** + * @brief Ajoute une boite aux letres dans la liste de BAL : + * Mets à jour le pointeur courant ainsi que debut. + * + * @param listeActuel struct listeBAL *,la liste à modifier. + * @param leMessage BAL*, pointeur sur la boite aux lettres à ajouter à la liste. + */ void ajoutListeBAL(struct listeBAL * listeActuel,BAL * laBoiteAuxLettres); + +/** + * @brief Affiche l'intégralité de la Boite Aux Lettres pour tous les Récepteurs. + * Utilisation de la fonction afficheListeMessage + * + * @param listeActuel struct listeBAL, liste à afficher. + */ void afficheListeBAL(struct listeBAL listeActuel); +/** + * @brief Permet de vérifier si un idRecepteur existe dans une liste de Boite Aux Lettres donnée + * Ne modifie pas le pointeur courant mais parcours toute la liste. Modifie le boolRetour pour savoir si c'est vrai ou non. + * Renvoi l'élément correspondant si c'est le cas. Renvoi un élément vide sinon. + * + * @param listeActuel struct listeBAL, la liste à vérifier + * @param idRecepteur int, idRecepteur à vérifier. + * @param boolRetour bool*, 1->Element retourné trouvé dans la liste, 0->Element NULL, non trouvé dans la liste + * @return struct elementBAL*, element trouvé si dans la liste, NULL sinon. + */ struct elementBAL * existInListBAL(struct listeBAL listeActuel, int idRecepteur, bool * boolRetour); + +/** + * @brief Crée un nouveau message dans la liste de Boite Aux Lettres. + * Utilisation de la fonction existInListBAL() -> Créer une nouvelle BAL si le recepteur n'existe pas. + * + * @param b struct listeBAL*, la liste à modifier. + * @param idEmetteur int, le numéro de l'émetteur qui a envoyé le message. + * @param idRecepteur int, le numéro du recepteur qui va recevoir ce message. + * @param data char*, le message reçu. + */ void nouveauMessage(struct listeBAL * b,int idEmetteur,int idRecepteur,char *data); + /** * @brief Récupère la liste de message d'un recepteur précis * Attention de vérifier si la liste est vide -> si c'est le cas, * alors le recepteur n'existe pas. * - * @param b liste de BoîteAuxLettres - * @param idRecepteur + * @param b struct listeBAL, liste de BoîteAuxLettres + * @param idRecepteur int, id du recepteur * @return struct listeMessage* */ struct listeMessage * getMessages(struct listeBAL b, int idRecepteur); + +/** + * @brief [WIP] Permet de renvoyer les trames de chaque messages présentent dans la boîte aux lettres + * suivant le protocole de l'application. + * + * @param l struct listeMessage, la liste à envoye via TCP. + */ void formatListMessage(struct listeMessage l); #endif \ No newline at end of file diff --git a/header/iptable.h b/header/iptable.h new file mode 100644 index 0000000..4c4d080 --- /dev/null +++ b/header/iptable.h @@ -0,0 +1,112 @@ +#ifndef HEADER_IPTABLE +#define HEADER_IPTABLE + +#include "tsock.h" + +/** + * @brief Test la liste ipTable + * + * @return int 0-> si réussite. + */ +int iptableTest(); + +/** + * @struct ipTable + * @brief definition de la structure d'une table d'IP + * + * @var ipTable::ipAddress + * Adresse IP sous forme de char* + * @var ipTable::idEmetteur + * Numéro de l'émetteur associé à l'ip + */ +typedef struct{ + char *ipAddress; + int tailleipAddress; + int idEmetteur; +}ipTable; + +/** + * @struct elementipTable + * @brief Element dans une liste de table d'IP + * + * @var elementipTable::actualIpTable + * Pointeur vers la table d'IP de l'élément + * @var elementipTable::suiv + * Pointeur vers le prochain élément + */ +struct elementIpTable{ + ipTable * actualIpTable; + struct elementIpTable * suiv; +}; + +/** + * @struct listeIpTable + * @brief Liste d'éléments table d'IP + * + * @var listeIpTable::debut + * Pointeur vers le premier élément + * @var listeIpTable::courant + * Pointeur vers l'élément sélectionné + * @var listeIpTable::fin + * Pointeur vers l'élément final + */ +struct listeIpTable{ + struct elementIpTable * debut; + struct elementIpTable * courant; + struct elementIpTable * fin; + int taille; +}; + +/** + * @brief Permet l'initialisation d'une struture ipTable avec une IP et un idEmetteur donné. + * + * @param ipAddress char*, Adresse IP associée à l'émétteur. + * @param idEmetteur int, numéro de l'émetteur du message. + * @return ipTable* table d'IP initialisé avec les paramètres donnés. + */ +ipTable * creeIpTable(char *ipAddress,int idEmetteur); + +/** + * @brief Initialise la structure elementIpTable avec un malloc. + * L'élément crée renvoi vers une adresse NULL. + * + * @return struct elementIpTable* element initialisé + */ +struct elementIpTable * initElementIpTable(void); + +/** + * @brief Initialise plusieurs éléments (debut,courant et fin) avec initElementIpTable(). + * + * @return struct listeIpTable* liste de tables d'IP NULL mais alloué. + */ +struct listeIpTable * initListeIpTable(void); + +/** + * @brief Ajoute un tableau d'IP dans la liste de des tableaux d'IP : + * Mets à jour le pointeur courant ainsi que debut. + * + * @param listeActuel struct listeIpTable *,la liste à modifier. + * @param lipTable ipTable*, pointeur sur le tableau d'IP à ajouter à la liste. + */ +void ajoutListeIpTable(struct listeIpTable * listeActuel,ipTable * lipTable); + +/** + * @brief Affiche l'intégralité des IP/Id Emetteurs. + * + * @param listeActuel struct listeIpTable, liste à afficher. + */ +void afficheListeIpTable(struct listeIpTable listeActuel); + +/** + * @brief Permet de vérifier si une Adresse IP existe déjà dans une liste d'IP donnée + * Ne modifie pas le pointeur courant mais parcours toute la liste. Modifie le boolRetour pour savoir si c'est vrai ou non. + * Renvoi l'élément correspondant si c'est le cas. Renvoi un élément vide sinon. + * + * @param listeActuel struct listeBAL, la liste à vérifier + * @param idEmetteur char*, Adresse IP à vérifier. + * @param boolRetour bool*, 1->Element retourné trouvé dans la liste, 0->Element NULL, non trouvé dans la liste + * @return struct elementIpTable*, element trouvé si dans la liste, NULL sinon. + */ +struct elementIpTable * existInListIP(struct listeIpTable listeActuel, char* ipAdress, bool * boolRetour); + +#endif \ No newline at end of file diff --git a/header/puit.h b/header/puit.h index f6e1032..18bb710 100644 --- a/header/puit.h +++ b/header/puit.h @@ -2,10 +2,86 @@ #define HEADER_PUIT #include "tsock.h" +#include "bal.h" +#include "iptable.h" -int launchPuit(int nombreMessage,int tailleMessage,int isTCP,int port,char * ipAddress,int isBAL); -int initSocket(int socketType, struct sockaddr_in * socketStruct, int port, char * ipAddress); +/** + * @brief Fonction principale pour le puit. Peut lancer en mode TCP/UDP avec la fonction receiveMultipleData() + * Vérifie si la variable isBAL est à 1 -> active le mode boite aux lettres avec la fonction du même nom + * + * @param nombreMessage int, le nombre de message à envoyer. + * @param tailleMessage int, la taille de chacun de ces messages. + * @param isTCP int, 1 -> TCP, 0 -> UDP + * @param port int, numéro du port + * @param isBAL int, 1-> Mode Boite aux Lettres + * @return int 0-> si réussite, autre sinon + */ +int launchPuit(int nombreMessage,int tailleMessage,int isTCP,int port,int isBAL); + +/** + * @brief Pour un nombre de message donné (-1 -> infini) recevra des messages avec une taille précise. + * à l'aide de isTCP utilise différente primitive (listen, accept et read pour TCP, recvfrom pour UDP) + * Dans le cas d'UDP si nombreMessage = -1 (infini) écoutera à l'infini la source. Pour TCP fermera la connexion + * une fois la connexion finie [A améliorer]. + * + * @param nombreMessage int, le nombre de message à envoyer. + * @param tailleMessage int, la taille de chacun de ces messages. + * @param sock int, socket premettant d'utiliser la primitive readRecvFrom(). + * @param socketStruct struct sockaddr_in , la structure du socket. + * @param isTCP int, 1 -> TCP, 0 -> UDP. + * @return int 0 si réussi. + */ int receiveMultipleData(int nombreMessages, int tailleMessage, int sock, struct sockaddr_in socketStruct, int isTCP); -int modeBoiteAuxLettres(struct sockaddr_in socketStruct, int socketType, int port, char * ipAddress); + +/** + * @brief Créer une structure listeBAL pour stocker les différentes lettres des emetteurs. + * Uniquement en mode TCP lit la première couche protocolaire pour connaître le mode de la source. + * Si MODE_RECEPTEUR alors la primitive receptionRecepteur est lancée. + * Si MODE_EMIS alors la primitive receptionEmetteur est lancée. + * Ferme le socket TCP une fois les messages reçues et relance la connexion avec listen() et accept(). + * + * @param socketStruct struct sockaddr_in *, la structure du socket sous forme de pointeur + * @param socketType SOCK_STREAM pour TCP ou SOCK_DGRAM pour UDP + * @param port int, numéro du port + * @param ipAddress char *, adresse IP + */ +void modeBoiteAuxLettres(struct sockaddr_in socketStruct, int socketType, int port, char * ipAddress); + +/** + * @brief à partir d'un socket, lit le message reçu et l'ajoute dans la boite aux lettre donnée en paramètre. + * + * @param sock int, socket premettant d'utiliser la primitive read() + * @param tailleMessagePrevu int, taille du message prévu donné par la couche protocolaire de l'application + * @param tailleMessageRecu int*, taille réel donné par read() + * @param emetteur int, numéro de l'émetteur + * @param recepteur int, numéro du recepteur + * @param boiteAuxLettres struct listeBAL*, pointeur visant la boite aux lettres + */ +void receptionEmetteur(int sock, int tailleMessagePrevu, int * tailleMessageRecu, int emetteur, int recepteur, struct listeBAL *boiteAuxLettres); + +/** + * @brief à partir d'un socket, renvoi les messages dans la boite aux lettres pour un recepteur precis. + * + * @param sock int, socket premettant d'utiliser la primitive write(). + * @param recepteur int, id du recepteur. + * @param boiteAuxLettres struct listeBAL, la boite aux lettres à renvoyer. + */ +int receptionRecepteur(int sock, int socketType, struct sockaddr_in socketStruct, int port, int recepteur, struct listeBAL boiteAuxLettres); + +/** + * @brief Permet, à partir de isTCP de choisir la méthode d'envoi. + * + * @param sock int,socket premettant d'utiliser la primitive read()/recvfrom(). + * @param socketStruct struct sockaddr_in, la structure du socket avec l'ip et le port. + * @param longueurRecu int, sizeof(socketStruct) + * @param messageRecu char*, la chaîne de caractère qui recevra le message, doit être allouée + * @param tailleMessage int, la longueur donnée par l'utilisateur + * @param isTCP int, 1 -> TCP, 0 -> UDP + * @param i int, fonctionne comme un count pour le printf() + * @return int, renvoi la longueur n reçue par TCP/UDP. + */ +int readRecvFrom(int sock, struct sockaddr_in socketStruct, int longueurRecu, char * messageRecu, int tailleMessage, int isTCP, int i); + +int getEmetteurId(struct sockaddr_in socketStruct, struct listeIpTable * tabledIp); #endif \ No newline at end of file diff --git a/header/source.h b/header/source.h index d74f1a8..4fd0cef 100644 --- a/header/source.h +++ b/header/source.h @@ -2,10 +2,61 @@ #define HEADER_SOURCE #include "tsock.h" +/** + * @brief Lance le mode source. Gère UDP comme TCP et le mode Emetteur ainsi que Recepteur en TCP uniquement. + * Créer un socket(), un struct sockaddr_in et lance les diverses fonctions de connexion : + * connectTCP() puis sendMultipleData() pour le mode TCP + * sendMultipleData() uniquement pour le mode UDP + * + * @param nombreMessage int, le nombre de message à envoyer. + * @param tailleMessage int, la taille de chacun de ces messages. + * @param isTCP int, 1 -> TCP, 0 -> UDP + * @param port int, numéro du port + * @param ipAddress char *, adresse IP + * @param emetteur int, numéro Emetteur + * @param recepteur int, numéro Recepteur + * @return int 0-> si réussite, autre sinon + */ int launchSource(int nombreMessage,int tailleMessage,int isTCP,int port,char * ipAddress,int emetteur,int recepteur); + +/** + * @brief Envoi de trame(s) en mode UDP/TCP avec un format particulier : + * [msgID[5], caractères répétés] -> les caractères vont de a à z. + * + * @param nombreMessages int, le nombre de message à envoyer. + * @param tailleMessage int, la taille de chacun de ces messages. + * @param sock int, le socket créé par avance + * @param socketStruct struct sockaddr_in *, la structure du socket sous forme de pointeur + * @param sizeSocketStruct int, sizeof(*socketStruct). Important pour l'envoi en UDP + * @return int 0-> si réussite, autre sinon + */ int sendMultipleData(int nombreMessages, int tailleMessage, int sock, struct sockaddr_in * socketStruct, int sizeSocketStruct, int isTCP); -void connectTCP(int sock, struct sockaddr_in socketStruct, int tailleSocket); + +/** + * @brief Permet d'envoyer un/des message(s) avec une certaine taille spécifiquement + * pour la boîte au lettres. Le numéro du recepteur (nommé emetteur ici) est précisé. + * Une trame sera tout d'abord émise suivant le protocole de l'application avec la fonction formatTestParam() + * Ensuite une deuxième trame est émise avec formatTextMessage(). + * + * @param emetteur int, numéro de l'émetteur utilisateur donc du recepteur pour le message + * @param nombreMessage int, nombre de message à envoyer + * @param tailleMessage int, la taille de ces messages + * @param sock int, numéro du socket crée par avance + * @param socketStruct struct sockaddr_in *, pointeur sur la structure socket + * @param tailleSocketStruct int, sizeof(*socketStruct) + */ void modeEmetteur(int emetteur,int nombreMessage,int tailleMessage,int sock,struct sockaddr_in * socketStruct,int tailleSocketStruct); -void printAndVerif(char * sendingMessage,int tailleMessage,int longueurEmis, int count); + +/** + * @brief Permet de recevoir les messages de la boite aux lettres à l'émetteur spécifié. + * + * @param recepteur int, numéro du recepteur utilisateur donc de l'emetteur pour la boite aux lettres + * @param sock int, numéro du socket crée par avance + * @param socketStruct struct sockaddr_in *, pointeur sur la structure socket + * @param tailleSocketStruct int, sizeof(*socketStruct) + * @param port int, numéro du port + * @param ipAddress char *, adresse IP + */ +void modeRecepteur(int recepteur,int sock,struct sockaddr_in * socketStruct,int tailleSocketStruct,int port,char * ipAddress); #endif \ No newline at end of file diff --git a/header/tsock.h b/header/tsock.h index 041684f..46e955f 100644 --- a/header/tsock.h +++ b/header/tsock.h @@ -13,20 +13,213 @@ #include #include #include +#include "bal.h" +#define NBMESSAGE_DEFAULT 10 +#define MAX_MESSAGE 4 +#define MODE_PARAMETRE 0 +#define MODE_RECEPTEUR 1 +#define MODE_EMIS 2 + +/** + * @brief Permet de gérer le nombre de message envoyés s'ils ne sont pas précisés + * par l'utilisateur (uniquement en mode source). + * Ici le nombre par défaut est définie par NBMESSAGE_DEFAULT. + * A noter que pour le puit, ce nombre est laissé à -1 car le nombre de message recu + * est infini. + * @author Yohan Boujon + * + * @param nb int *, pointeur sur l'entier à modifier + * @param source source, vérifie si nous sommes bien en mode source + */ void setNbMessage(int * nb, int source); + +/** + * @brief Affiche les informations principales rentrées par l'utilisateur, notamment : le mode, le nombre de messages, + * la taille des messages, le port, l'adresse IP, le mode (TCP/UDP). + * @author Yohan Boujon + * + * @param source int, source ou puit + * @param isTCP int, TCP ou UDP + * @param nbMessage int, le nombre de message à envoyer/à recevoir (-1 en reception est lu comme infini) + * @param taille int, la taille de chaque message + * @param portNumber int, numéro du port + * @param ipAddress char*, l'adresse IP sous chaîne de caractère + */ void printInfo(int source, int isTCP, int nbMessage, int taille, int portNumber, char ipAddress[]); + +/** + * @brief Initialise la structure du socket pour avoir le port et l'ip. Si le mode choisi est reception : l'ip est ignorée. + * Utilise la fonction gethostbyname pour récupérer l'IPv4 à partir d'une chaîne de caractère quelconque. + * @author Yohan Boujon + * + * @param socketTempStruct struct sockaddr_in*, pointeur sur la structure (doit être initialisée au préalable). + * @param source int, source ou puit -> si à 0 alors ipAddress sera ignoré et défini par INADDR_ANY. + * @param port int, le port du socket. + * @param ipAddress char *, l'Adresse IP du socket. + */ void initStructSocket(struct sockaddr_in *socketTempStruct, int source, int port, char * ipAddress); -void getNonOtpArgs(char ** argv, int argc, int * portNumber, char * ipAddress[]); + +/** + * @brief Récupère toutes les informations qui n'utilisent pas getopt, + * notamment le port ainsi que l'ip. + * @author Yohan Boujon + * + * @param argv char **, liste de chaîne de caractère des arguments + * @param argc int, nombre d'arguments (IP -> argc-1 et Port -> argc-2) + * @param portNumber int *, numéro du port retourné + * @param ipAddress char **, pointeur faire une chaîne de caractère de l'adresse ip retournée + * @param portOnly bool, mode portOnly pour -s ou -b + */ +void getNonOtpArgs(char ** argv, int argc, int * portNumber, char * ipAddress[], bool portOnly); + +/** + * @brief [utile pour source.c] à partir d'un numéro, d'un message et d'une taille + * Créer une trame avec 5 caractères pour le numéro du message, et le reste pour le message + * @author Yohan Boujon + * + * @param actualMessage char *, Doit être initialisé. Message modifié. + * @param num int, numéro du message, ne doit pas dépasser 9999. + * @param tailleMessage int, taille du message final. + * @param messageChar char, caractère du message, sera répété pour 4-tailleMessage fois. + */ void formatText(char * actualMessage, int num, int tailleMessage, char messageChar); + +/** + * @brief Permet, pour une taille max donnée. De quitter le programme si cette valeur est dépassée. + * @author Simon Paris + * + * @param var int, variable à tester. + * @param tailleMax int, le test. + * @return int retourne 0 si cela s'est bien executé. + */ int exitMax(int var,int tailleMax); -char * formatTextParam(int numEmetteur, int numRecepteur, int tailleMessage, int nbMessage); +/** + * @brief Converti plusieurs paramètres en une chaîne de caractère. Couche protocolaire de l'application. + * Sous la forme suivante : [messageType[1],emetteur/recepteur[4],tailleMessage[4],nbMessage[4]] + * @author Simon Paris + * @author Yohan Boujon + * + * @param modeParam int, MODE_PARAMETRE pour un paramètre pure, MODE_RECEPTEUR -> -r ##, MODE_EMIS -> -e ##. + * @param emeteurRecepteur int, numéro de l'émetteur (-e ##, ou idEmetteur) ou du recepteur (-r ##, ou idRecepteur). + * @param tailleMessage int, taille du message à envoyer. + * @param nbMessage int, nombre de message à envoyer [inutilisé]. + * @return char* chaîne de caractère à envoyer via TCP. + */ +char * formatTextParam(int modeParam, int emeteurRecepteur, int tailleMessage, int nbMessage); + +/** + * @brief Ajoute un numéro au début du message à envoyer. + * @author Simon Paris + * + * @param message char *, chaîne de caractère du message originel. + * @param tailleMessage int, taille du message "message". + * @return char* renvoi la chaîne modifiée. + */ char * formatTextMessage(char * message, int tailleMessage); -int convertion(int nbr,char *numbuffer); + +/** + * @brief Converti un nombre en chaîne de caractre et le place dans la chaîne actualMessage. + * La taille de ce dernier doit être connu au préalable + * @author Simon Paris + * + * @param actualMessage char *, message à modifier. + * @param encadrementHaut int, offset du début du nombre. + * @param encadrementBas int, offset de la fin du nombre. + * @param nbr int, nombre à convertir en chaîne de caractère, ne doit pas dépasser 9999. + * @return int retourne encadrementHaut. + */ int gestionOffset(char *actualMessage,int encadrementHaut,int encadrementBas,int nbr); + +/** + * @brief Teste les différentes fonctions permettant de gérer le protocole, + * autant en lecture qu'écriture + * @author Simon Paris + * + * @return int 0 si réussi + */ int testProtocol(void); -int recuperationParam(char * msgParam); -int int2String(char *msgParam, int offset); +/** + * @brief Récupération de chaque paramètres grâce à la trame précédente. + * @author Simon Paris + * @author Yohan Boujon + * + * @param msgParam char *, chaîne reçue avant le message, couche protocolaire. + * @param messageOrPram int *, renvoi MODE_PARAM,MODE_SOURCE ou MODE_EMIS. + * @param numEmetteurRecepteur int *, renvoi le numéro de l'émetteur/recepteur. + * @param numTailleMessageParam int *, renvoi la taille du message émis. + * @param nbMessageParam int *, renvoi le nombre de message a recevoir [Inutilisé] + * @return int + */ +int recuperationParam(char * msgParam, int * messageOrPram, int * numEmetteurRecepteur, int * numTailleMessageParam, int * nbMessageParam); + +/** + * @brief converti une chaîne de caractère spécifique (protocolaire) en entiers avec une gestion d'offset. + * La taille lue entre chaque offset est définie par MAX_MESSAGE. + * @author Simon Paris + * @author Yohan Boujon + * + * @param data char *, la chaîne de caractère à lire. + * @param offset int, offset : décalage de n caractère sur la chaîne data. + * @return int nombre récupéré entre 0 et 9999. + */ +int protocol2int(char * data, int offset); + +/** + * @brief Fonction simplifiée pour le connect() du mode TCP. + * @author Yohan Boujon + * + * @param sock int, le socket créé par avance + * @param socketStruct struct sockaddr_in, structure du socket + * @param tailleSocket int, sizeof(socketStruct) + */ +int connectTCP(int sock, struct sockaddr_in socketStruct, int tailleSocket); + +/** + * @brief Récupère la longueur émise par la fonction write() (TCP) ou sendto() (UDP) + * Si elle est égale à -1 : ferme le programme car l'envoi n'a pas pu être effectué. + * Sinon affiche les divers paramètres avec un compteur de message (count). + * @author Yohan Boujon + * + * @param sendingMessage char *, le message à envoyer + * @param tailleMessage int, la taille du message théorique + * @param longueurEmis int, la taille du message à envoyer (-1 -> Erreur) + * @param count int, compteur + */ +void printAndVerif(char * sendingMessage,int tailleMessage,int longueurEmis, int count); + +/** + * @brief Permet l'initialisation avec la primitive socket() ainsi qu'initStructSocket() à l'aide d'un port et d'une adresse IP. + * Fonction bind() est ensuite réalisée pour se connecter au serveur. Qu'on soit en mode UDP/TCP. + * @author Yohan Boujon + * + * @param socketType SOCK_STREAM pour TCP ou SOCK_DGRAM pour UDP + * @param socketStruct struct sockaddr_in *, la structure du socket sous forme de pointeur + * @param port int, numéro du port + * @param ipAddress char *, adresse IP + * @return int, renvoi le socket crée + */ +int initSocket(int socketType, struct sockaddr_in * socketStruct, int port, char * ipAddress); + +/** + * @brief Ouvre un socket à l'aide d'un socketType + * + * @param socketType SOCK_STREAM pour TCP ou SOCK_DGRAM pour UDP + * @return int le socket créé + */ +int openSocket(int socketType); + +/** + * @brief utilise la fonction listen et accept de TCP pour créer un nouveau socket. + * + * @param sock int, le socket pour lancer la connexion. + * @param socketStruct struct sockaddr_in*, la structure du socket sous forme de pointeur. + * @param sizeSocketStruct int, sizeof(*socketStruct) + * @param closeSocket bool, 1-> ferme le socket sock. + * @return int, le socket crée par accept(). + */ +int listenAndAccept(int sock, struct sockaddr_in * socketStruct, int * sizeSocketStruct, bool closeSocket); + #endif \ No newline at end of file diff --git a/src/bal.c b/src/bal.c index b013abc..360ca14 100644 --- a/src/bal.c +++ b/src/bal.c @@ -20,7 +20,6 @@ int bal(void){ messageBAL * creeMessage(char *data,int idEmetteur) { messageBAL * message = malloc(sizeof(messageBAL)); - message->idEmetteur=idEmetteur; message->tailleData=strlen(data); message->data=(char*)malloc(sizeof(char)*message->tailleData); @@ -42,6 +41,7 @@ struct listeMessage * initListeMessage(void) l->debut=initElementMessage(); l->fin=initElementMessage(); l->courant=initElementMessage(); + l->nbMessages=0; return l; } @@ -51,7 +51,8 @@ void ajoutListeMessage(struct listeMessage * listeActuel,messageBAL * leMessage) elementActuel->messageBALActuel=leMessage; elementActuel->suiv=listeActuel->courant; listeActuel->debut=elementActuel; - listeActuel->courant=elementActuel; + listeActuel->courant=elementActuel; + listeActuel->nbMessages=listeActuel->nbMessages+1; } void afficheListeMessage(struct listeMessage listeActuel) @@ -60,7 +61,7 @@ void afficheListeMessage(struct listeMessage listeActuel) struct elementMessage * elementCourant = listeActuel.courant; while(elementCourant->suiv != elementFinal->suiv) { - printf("%s\n",elementCourant->messageBALActuel->data); + printf("Emetteur : %d\t Message : %s\n",elementCourant->messageBALActuel->idEmetteur,elementCourant->messageBALActuel->data); elementCourant=elementCourant->suiv; } } diff --git a/src/iptable.c b/src/iptable.c new file mode 100644 index 0000000..21b0632 --- /dev/null +++ b/src/iptable.c @@ -0,0 +1,76 @@ +#include "../header/iptable.h" + +int iptableTest() +{ + struct listeIpTable * l = initListeIpTable(); + ajoutListeIpTable(l,creeIpTable("localhost",1)); + ajoutListeIpTable(l,creeIpTable("192.168.1.21",2)); + afficheListeIpTable(*l); + return 0; +} + +ipTable * creeIpTable(char *ipAddress,int idEmetteur) +{ + ipTable * iptablevector = malloc(sizeof(ipTable)); + iptablevector->idEmetteur=idEmetteur; + iptablevector->tailleipAddress=strlen(ipAddress); + iptablevector->ipAddress=(char*)malloc(sizeof(char)*iptablevector->tailleipAddress); + strcpy(iptablevector->ipAddress,ipAddress); + return iptablevector; +} + +struct elementIpTable * initElementIpTable(void) +{ + struct elementIpTable * returnElement = malloc(sizeof(struct elementIpTable)); + returnElement->actualIpTable = creeIpTable("",0); + returnElement->suiv = NULL; + return returnElement; +} + +struct listeIpTable * initListeIpTable(void) +{ + struct listeIpTable * l=malloc(sizeof(struct listeIpTable)); + l->debut=initElementIpTable(); + l->fin=initElementIpTable(); + l->courant=initElementIpTable(); + l->taille=0; + return l; +} + +void ajoutListeIpTable(struct listeIpTable * listeActuel,ipTable * lipTable) +{ + struct elementIpTable * elementActuel = malloc(sizeof(struct elementIpTable)); + elementActuel->actualIpTable=lipTable; + elementActuel->suiv=listeActuel->courant; + listeActuel->debut=elementActuel; + listeActuel->courant=elementActuel; + listeActuel->taille=listeActuel->taille+1; +} + +void afficheListeIpTable(struct listeIpTable listeActuel) +{ + struct elementIpTable * elementFinal = listeActuel.fin; + struct elementIpTable * elementCourant = listeActuel.courant; + while(elementCourant->suiv != elementFinal->suiv) + { + printf("Adresse IP : %s\tEmetteur = %d\n",elementCourant->actualIpTable->ipAddress,elementCourant->actualIpTable->idEmetteur); + elementCourant=elementCourant->suiv; + } +} + +struct elementIpTable * existInListIP(struct listeIpTable listeActuel, char* ipAdress, bool * boolRetour) +{ + struct elementIpTable * elementFinal = listeActuel.fin; + struct elementIpTable * elementCourant = listeActuel.courant; + while(elementCourant->suiv != elementFinal->suiv) + { + if(strcmp(elementCourant->actualIpTable->ipAddress,ipAdress) == 0) + { + *boolRetour = true; + return elementCourant; + } + elementCourant=elementCourant->suiv; + }; + *boolRetour = false; + return elementFinal; +} \ No newline at end of file diff --git a/src/main.c b/src/main.c index 7d3586b..408e2d0 100644 --- a/src/main.c +++ b/src/main.c @@ -5,8 +5,8 @@ int main (int argc, char **argv) { - char usageChar[100]="usage: cmd [-p|-s]|[-u][-u|-r ##|-e ##|-b][-n ##][-l ##] port ipAdress\n"; - testProtocol(); + char usageChar[100]="usage: cmd [-p|-s][-u]|[-u|-r ##|-e ##|-b][-n ##][-l ##] port ipAdress\n"; + //testProtocol(); //bal(); char *ipAddress; extern char *optarg; @@ -71,35 +71,37 @@ int main (int argc, char **argv) break; } } - if (source == -1) { + bool serverMode = (isBAL || source==0); + if (source == -1){ printf("-p|-s non present !\n"); printf("%s",usageChar); exit(EXIT_FAILURE); } - if(argc != optind+2) - { + if((argc != optind+1) && serverMode){ + printf("ip non present !\n"); + printf("%s",usageChar); + exit(EXIT_FAILURE); + } + else if((argc != optind+2) && !serverMode){ printf("ip ou port non present !\n"); printf("%s",usageChar); exit(EXIT_FAILURE); } - if(tailleMessage == -1) - { + if(tailleMessage == -1){ tailleMessage = 30; } - getNonOtpArgs(argv, argc, &port, &ipAddress); + getNonOtpArgs(argv, argc, &port, &ipAddress, serverMode); setNbMessage(&nb_message,source); - printInfo(source,tcp,nb_message,tailleMessage,port,ipAddress); + serverMode ? printInfo(source,tcp,nb_message,tailleMessage,port,"non precise") : printInfo(source,tcp,nb_message,tailleMessage,port,ipAddress); if(source) { - //printf("Source : %d\n",nb_message); launchSource(nb_message,tailleMessage,tcp,port,ipAddress,emetteur,recepteur); } else { - //printf("Puit : %d\n",nb_message); - launchPuit(nb_message,tailleMessage,tcp,port,ipAddress,isBAL); + launchPuit(nb_message,tailleMessage,tcp,port,isBAL); } return(EXIT_SUCCESS); } \ No newline at end of file diff --git a/src/puit.c b/src/puit.c index 934498d..9d08f4d 100644 --- a/src/puit.c +++ b/src/puit.c @@ -1,105 +1,194 @@ #include "../header/puit.h" -int launchPuit(int nombreMessage,int tailleMessage,int isTCP,int port,char * ipAddress,int isBAL) +int launchPuit(int nombreMessage,int tailleMessage,int isTCP,int port,int isBAL) { int sock,socketType; struct sockaddr_in socketPuit; + /*socketType change de valeur en fonction de isTCP -> si isTCp alors SOCK_STREAM, sinon SOCK_DGRAM*/ socketType = (isTCP) ? SOCK_STREAM : SOCK_DGRAM; + /*Si le mode boîte aux lettres est activé alors on entre dans le mode BAL -> on return 0 car nous ne voulons pas + rentrer dans le mode TCP/UDP normal.*/ if(isBAL) { printf("Mode Boîte aux Lettres\n"); - modeBoiteAuxLettres(socketPuit,socketType,port,ipAddress); + modeBoiteAuxLettres(socketPuit,SOCK_STREAM,port,"localhost"); return 0; } - sock = initSocket(socketType,&socketPuit,port,ipAddress); + /*Sinon on initialise le socket de base et on rentre dans receiveMultipleData() -> on ferme le socket avant*/ + sock = initSocket(socketType,&socketPuit,port,"localhost"); receiveMultipleData(nombreMessage,tailleMessage,sock,socketPuit,isTCP); close(sock); return 0; } -int initSocket(int socketType, struct sockaddr_in * socketStruct, int port, char * ipAddress) +void modeBoiteAuxLettres(struct sockaddr_in socketStruct, int socketType, int port, char * ipAddress) { - int sockReturn; - if((sockReturn=socket(AF_INET,socketType,0)) == -1) - { - perror("[tsock] : fonction socket() : echec creation du socket\n"); - exit(EXIT_FAILURE); - } - initStructSocket(socketStruct,0,port,ipAddress); - if (bind(sockReturn, (struct sockaddr *)socketStruct, sizeof(*socketStruct)) < 0 ) - { - perror("[tsock] : fonction bind() : echec du lien avec socket serveur.\n"); - exit(EXIT_FAILURE); - } - return sockReturn; -} - -int modeBoiteAuxLettres(struct sockaddr_in socketStruct, int socketType, int port, char * ipAddress) -{ - char messageRecu[30+1]; - int n, i=1, longueurRecu = sizeof(socketStruct),sock,oldSock; + /*Init : Création de la boite aux lettres, de paramRecu pour la couche protocolaire. + Intiialisation de la taille de socketStruct pour les différentes fonctions. + Création des 4 variables à récupérer dans la couche protocolaire.*/ + struct listeBAL boiteAuxLettres = initListeBAL(); + struct listeIpTable * tabledIP = initListeIpTable(); + char paramRecu[13]; + int n, longueurRecu = sizeof(socketStruct),sock,oldSock; + int param,emetteurRecepteur,tailleMessage,nbMessage; while(1) { + /*Etat d'attente -> création d'un socket pour écouter le premier client et récupérer son IP. n=1 pour rentrer dans le while*/ n=1; oldSock = initSocket(socketType,&socketStruct,port,ipAddress); - listen(oldSock,5); - sock = accept(oldSock,(struct sockaddr *)&socketStruct,(socklen_t * restrict)&longueurRecu); + sock = listenAndAccept(oldSock,&socketStruct,&longueurRecu,true); + /*Tant qu'on reçoit des données, on vérifie si le client nous demande une reception ou une emission*/ while(n>0) { - n = read(sock,messageRecu,30); - messageRecu[n] = '\0'; - if(n>0) + n = read(sock,paramRecu,13); + recuperationParam(paramRecu,¶m,&emetteurRecepteur,&tailleMessage,&nbMessage); + switch(param) { - printf("Puit\tReception n°%d (%d) :\t[%s]\n",i,n,messageRecu); - i++; + case MODE_RECEPTEUR: + /*On récupère le socket créé par receptionRecepteur pour le fermer par la suite*/ + sock=receptionRecepteur(sock,socketType,socketStruct,port,emetteurRecepteur,boiteAuxLettres); + /*Pour fermer le while on met n=-1*/ + n=-1; + break; + case MODE_EMIS: + receptionEmetteur(sock,tailleMessage,&n,getEmetteurId(socketStruct,tabledIP),emetteurRecepteur,&boiteAuxLettres); + break; + default: + printf("Message non reconnu.\n"); + break; } } + /*Si on est en mode emis, le serveur affiche les données rentrées dans la boite aux lettres*/ + if(param == MODE_EMIS) + { + printf("---Boîte aux Lettres actuel :---\n"); + afficheListeBAL(boiteAuxLettres); + printf("---Liste d'IP actuel :---\n"); + afficheListeIpTable(*tabledIP); + } + /*On ferme le socket qu'il provienne du MODE_RECEPTEUR ou MODE_EMIS*/ close(sock); - close(oldSock); + } +} + +int receptionRecepteur(int sock, int socketType, struct sockaddr_in socketStruct, int port, int recepteur, struct listeBAL boiteAuxLettres) +{ + /*StripAddressStruct va convertir l'adresse de socketStruct en char* car initStructSocket demande ce type de variable. + On crée des pointeurs vers les éléments du recepteur concerné. + inet_ntop permet de convertir une adresse in_addr en char**/ + int longueurEmis,i=1; + char *paramMessage,StripAddressStruct[INET_ADDRSTRLEN]; + struct in_addr ipAddressStruct = ((struct sockaddr_in*)&socketStruct)->sin_addr; + struct elementMessage *elementFinal = getMessages(boiteAuxLettres,recepteur)->fin,*elementCourant = getMessages(boiteAuxLettres,recepteur)->courant; + inet_ntop( AF_INET, &ipAddressStruct, StripAddressStruct, INET_ADDRSTRLEN ); + + /*On ferme la connexion qui était en mode listen() + On crée un nouveau socket en initialisant la structure sockaddr_in avec l'adresse IP du client*/ + close(sock); + sock=openSocket(socketType); + initStructSocket(&socketStruct,1,port,StripAddressStruct); + /*On attend 1 seconde pour que la source lance un listen TCP + On lance une connexion TCP -> Si -1 alors on retourne le socket crée et on ferme la connexion (on retourne dans l'état d'attente)*/ + sleep(1); + if (connectTCP(sock,socketStruct,sizeof(socketStruct)) == -1) + { + return sock; + } + printf("\n--- Messages à renvoyer pour %d : ---\n",recepteur); + /*Tant qu'il reste des éléments dans la liste on envoi les différents paquets : + La couche protocolaire avec MODE_RECEPTEUR, l'id de celui qui a envoyé le message, la taille et le nombre de messages + Le message avec la taille correcte. On incrémente i pour l'affichage et on passe à l'élément suivant.*/ + while(elementCourant->suiv != elementFinal->suiv) + { + paramMessage = formatTextParam(MODE_RECEPTEUR,elementCourant->messageBALActuel->idEmetteur,elementCourant->messageBALActuel->tailleData,getMessages(boiteAuxLettres,recepteur)->nbMessages); + longueurEmis = write(sock,paramMessage,13); + printAndVerif(paramMessage,13,longueurEmis,i); + + longueurEmis = write(sock,elementCourant->messageBALActuel->data,elementCourant->messageBALActuel->tailleData); + printAndVerif(elementCourant->messageBALActuel->data,elementCourant->messageBALActuel->tailleData,longueurEmis,i); + i++; + elementCourant=elementCourant->suiv; + } + return sock; +} + +void receptionEmetteur(int sock, int tailleMessagePrevu, int * tailleMessageRecu, int emetteur, int recepteur, struct listeBAL *boiteAuxLettres) +{ + /*On créer un pointeur char car nouveauMessage utilise ce dernier pour l'associer à la boite aux lettres*/ + char * messageRecu = malloc(sizeof(char)*tailleMessagePrevu); + /*On lit les messages reçus après chaque envoi protocolaire -> la taille est donc connue*/ + *tailleMessageRecu = read(sock,messageRecu,tailleMessagePrevu); + /*Le nouveau message n'est mis dans la BAL que si la donnée est correcte : donc au dessus d'une taille de 0 octet*/ + if(*tailleMessageRecu>0) + { + nouveauMessage(boiteAuxLettres,emetteur,recepteur,messageRecu); } } int receiveMultipleData(int nombreMessages, int tailleMessage, int sock, struct sockaddr_in socketStruct, int isTCP) { + /*messageRecu sera affiché avec un printf. La variable count est créé au préalable pour le while, n est mis à 1 pour la même raison*/ char messageRecu[tailleMessage+1]; - int n=1, longueurRecu = sizeof(socketStruct); + int n=1, count=0, longueurRecu = sizeof(socketStruct); + /*Dans le cas d'une connexion TCP on lance la primitive listenAndAccept() pour établir la connexion avec la source/le client*/ if(isTCP) { - listen(sock,5); - sock = accept(sock,(struct sockaddr *)&socketStruct,(socklen_t * restrict)&longueurRecu); + sock = listenAndAccept(sock,&socketStruct,&longueurRecu,true); } + /*On reçoit des messages tant qu'ils sont vide (pour TCP uniquement)*/ if(nombreMessages < 0) { - int i=1; + /*Tant qu'on reçoit des messages on continue.*/ while(n>0) { - if(isTCP) - { - n = read(sock,messageRecu,tailleMessage); - } - else - { - n = recvfrom(sock, (char *)messageRecu, tailleMessage, 0, (struct sockaddr*) &socketStruct,(socklen_t *__restrict__)&longueurRecu); - } - messageRecu[n] = '\0'; - printf("Puit\tReception n°%d (%d) :\t[%s]\n",i,n,messageRecu); - i++; + n=readRecvFrom(sock,socketStruct,longueurRecu,messageRecu,tailleMessage,isTCP,count+1); + count++; } } else{ - for(int i=0;isin_addr; + inet_ntop( AF_INET, &ipAddressStruct, StripAddressStruct, INET_ADDRSTRLEN ); + struct elementIpTable * returnEmetteurId = existInListIP(*tabledIp,StripAddressStruct,&isInTable); + if(isInTable) + { + printf("[trouve] : idEmetteur = %d",returnEmetteurId->actualIpTable->idEmetteur); + return returnEmetteurId->actualIpTable->idEmetteur; + } + else + { + printf("[non trouve] : idEmetteur = %d",tabledIp->taille+1); + ajoutListeIpTable(tabledIp,creeIpTable(StripAddressStruct,tabledIp->taille+1)); + return tabledIp->taille; + } } \ No newline at end of file diff --git a/src/source.c b/src/source.c index e0723f0..6ef8636 100644 --- a/src/source.c +++ b/src/source.c @@ -15,6 +15,8 @@ int launchSource(int nombreMessage,int tailleMessage,int isTCP,int port,char * i if(recepteur != -1) { printf("Mode Recepteur, recois : %d\n",recepteur); + connectTCP(sock,socketSource,sizeof(socketSource)); + modeRecepteur(recepteur,sock,&socketSource,sizeof(socketSource),port,ipAddress); return 0; } if(emetteur != -1) @@ -37,15 +39,6 @@ int launchSource(int nombreMessage,int tailleMessage,int isTCP,int port,char * i return 0; } -void connectTCP(int sock, struct sockaddr_in socketStruct, int tailleSocket) -{ - if(connect(sock,(struct sockaddr *)&socketStruct,(socklen_t)tailleSocket) == -1) - { - perror("[tsock] : fonction connect() : echec connexion\n"); - exit(EXIT_FAILURE); - }; -} - int sendMultipleData(int nombreMessages, int tailleMessage, int sock, struct sockaddr_in * socketStruct, int sizeSocketStruct, int isTCP) { int longueurEmis; @@ -73,23 +66,38 @@ void modeEmetteur(int emetteur,int nombreMessage,int tailleMessage,int sock,stru char sendingMessage[tailleMessage],*paramMessage,*actualMessage,messageChar='a'; for(int i=0;i='z'?messageChar='a':messageChar++; } } -void printAndVerif(char * sendingMessage,int tailleMessage,int longueurEmis, int count) +void modeRecepteur(int recepteur,int sock,struct sockaddr_in * socketStruct,int tailleSocketStruct,int port,char * ipAddress) { - if(longueurEmis == -1) + int longueurEmis,oldSock,param,emetteurRecepteur,tailleMessage,nbMessage=2,i=0; + char paramRecu[13]; + char *paramMessage; + paramMessage = formatTextParam(MODE_RECEPTEUR,recepteur,0,0); + longueurEmis = write(sock,paramMessage,13); + + close(sock); + oldSock = initSocket(SOCK_STREAM,socketStruct,port,ipAddress); + sock = listenAndAccept(oldSock,socketStruct,&tailleSocketStruct,true); + while(i1500){ + if(var>tailleMax){ printf("-l doit être <1500 \n"); exit(EXIT_FAILURE); } return 0; } -int testProtocol(void) +char * formatTextParam(int modeParam, int emeteurRecepteur, int tailleMessage, int nbMessage) { - char * msg,*msg2; - msg=formatTextParam(7, 8, 64, 1); - printf("%s\n",msg); - msg2=formatTextMessage("aaaaaa",6); - printf("%s\n",msg2); - - recuperationParam(msg); - - return 0; -} - -int recuperationParam(char * msgParam) -{ - - int messageOrPram; - int numEmetteurParam; - int numRecepeteurParam; - int numTailleMessageParam; - int nbMessageParam; - printf("Message param %s\n",msgParam); - messageOrPram=msgParam[0]-0x30; - printf("messageOrPram = %d \n",messageOrPram); - - numEmetteurParam = int2String(msgParam,1); - printf("Param Emetteur = %d\n",numEmetteurParam); - - numRecepeteurParam= int2String(msgParam,5); - printf("Param numRecepeteurParam = %d\n",numRecepeteurParam); - - numTailleMessageParam= int2String(msgParam,9); - printf("Param numTailleMessageParam = %d\n",numTailleMessageParam); - - nbMessageParam=int2String(msgParam,13); - printf("Param nbMessageParam = %d\n",nbMessageParam); - - return 0; -} - -int int2String(char *msgParam, int offset) -{ - int taille =4; - char buffEntier[taille]; - for(int i=offset,j=0;i<=offset+taille;i++,j++){ - buffEntier[j]=msgParam[i]; - } - return atoi(buffEntier); -} - -char * formatTextParam(int numEmetteur, int numRecepteur, int tailleMessage, int nbMessage) -{ - char * actualMessage = malloc(sizeof(char)*16); - actualMessage[0]='1'; - gestionOffset(actualMessage, 4,1,numEmetteur); - gestionOffset(actualMessage, 8,5,numRecepteur); - gestionOffset(actualMessage, 12,9,tailleMessage); - gestionOffset(actualMessage, 16,13,nbMessage); + char * actualMessage = malloc(sizeof(char)*13); + actualMessage[0]=modeParam+0x30; + gestionOffset(actualMessage, 4,1,emeteurRecepteur); + gestionOffset(actualMessage, 8,5,tailleMessage); + gestionOffset(actualMessage, 12,9,nbMessage); return actualMessage; } @@ -153,17 +120,11 @@ char * formatTextMessage(char * message, int tailleMessage) return actualMessage; } -int convertion(int nbr,char *numbuffer) -{ - sprintf(numbuffer, "%d", (nbr)%10000); - return 0; -} - int gestionOffset(char *actualMessage,int encadrementHaut,int encadrementBas,int nbr) { int taillechaine=0; char numbuffer[30]; - convertion(nbr,numbuffer); + sprintf(numbuffer, "%d", (nbr)%10000); taillechaine=strlen(numbuffer); for(int i=encadrementBas;i