Boite aux lettres fonctionnels en local ou non. Gestion des Emetteurs avec l'IP. Ajout d'un Makefile. Pour le mode puit/boite aux lettres, l'IP n'est plus obligatoire. #13 from yoboujon/yohan

Boite aux lettres fonctionnels en local ou non. Gestion des Emetteurs avec l'IP. Ajout d'un Makefile. Pour le mode puit/boite aux lettres, l'IP n'est plus obligatoire.
This commit is contained in:
Yohan Boujon 2023-01-25 12:54:58 +01:00 committed by GitHub
commit f119906a15
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 1053 additions and 178 deletions

53
Makefile Normal file
View file

@ -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

View file

@ -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

112
header/iptable.h Normal file
View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -13,20 +13,213 @@
#include <errno.h>
#include <arpa/inet.h>
#include <stdbool.h>
#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

View file

@ -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;
}
@ -52,6 +52,7 @@ void ajoutListeMessage(struct listeMessage * listeActuel,messageBAL * leMessage)
elementActuel->suiv=listeActuel->courant;
listeActuel->debut=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;
}
}

76
src/iptable.c Normal file
View file

@ -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;
}

View file

@ -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);
}

View file

@ -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,&param,&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;i<nombreMessages;i++)
/*On lit un certain nombre de message donné par l'utilisateur*/
for(count=0;count<nombreMessages;count++)
{
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+1,tailleMessage,messageRecu);
n=readRecvFrom(sock,socketStruct,longueurRecu,messageRecu,tailleMessage,isTCP,count+1);
}
}
return 0;
}
int readRecvFrom(int sock, struct sockaddr_in socketStruct, int longueurRecu, char * messageRecu, int tailleMessage, int isTCP, int i)
{
int n;
/*Pour TCP on utilise read(), pour UDP recvfrom()*/
if(isTCP)
{
n = read(sock,messageRecu,tailleMessage);
}
else
{
n = recvfrom(sock, (char *)messageRecu, tailleMessage, 0, (struct sockaddr*) &socketStruct,(socklen_t *__restrict__)&longueurRecu);
}
/*On ajoute \0 en fin de chaîne pour l'afficher correctement sur la console.*/
messageRecu[n] = '\0';
printf("Puit\tReception n°%d (%d) :\t[%s]\n",i,n,messageRecu);
return n;
}
int getEmetteurId(struct sockaddr_in socketStruct, struct listeIpTable * tabledIp)
{
bool isInTable;
char StripAddressStruct[INET_ADDRSTRLEN];
struct in_addr ipAddressStruct = ((struct sockaddr_in*)&socketStruct)->sin_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;
}
}

View file

@ -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<nombreMessage;i++)
{
paramMessage = formatTextParam(1,emetteur,tailleMessage+1,nombreMessage);
longueurEmis = write(sock,paramMessage,16);
printAndVerif(paramMessage,16,longueurEmis,i);
paramMessage = formatTextParam(MODE_EMIS,emetteur,tailleMessage+1,nombreMessage);
longueurEmis = write(sock,paramMessage,13);
printAndVerif(paramMessage,13,longueurEmis,i);
memset(sendingMessage, messageChar, tailleMessage);
actualMessage = formatTextMessage(sendingMessage,tailleMessage+1);
longueurEmis = write(sock,actualMessage,tailleMessage+1);
printAndVerif(actualMessage,tailleMessage+1,longueurEmis,i);
messageChar>='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(i<nbMessage)
{
perror("[tsock] : fonction sendto()/write() : echec d'envoi\n");
exit(EXIT_FAILURE);
longueurEmis = read(sock,paramRecu,13);
recuperationParam(paramRecu,&param,&emetteurRecepteur,&tailleMessage,&nbMessage);
char * messageRecu = malloc(sizeof(char)*tailleMessage);
longueurEmis = read(sock,messageRecu,tailleMessage);
printf("Emetteur : %d\t",emetteurRecepteur);
printAndVerif(messageRecu,tailleMessage,longueurEmis,i);
i++;
}
printf("Source\tEnvoi n°%d (%d) :\t[%s]\n",count+1,longueurEmis,sendingMessage);
close(sock);
}

View file

@ -1,10 +1,21 @@
#include "../header/tsock.h"
int testProtocol(void)
{
char * msg,*msg2;
msg=formatTextParam(0, 8, 64, 1);
printf("%s\n",msg);
msg2=formatTextMessage("aaaaaa",6);
printf("%s\n",msg2);
//recuperationParam(msg);
return 0;
}
void setNbMessage(int * nb, int source)
{
if((*nb == -1) && (source))
{
*nb = 10;
*nb = NBMESSAGE_DEFAULT;
}
}
@ -45,12 +56,19 @@ void initStructSocket(struct sockaddr_in *socketTempStruct, int source, int port
}
}
void getNonOtpArgs(char ** argv, int argc, int * portNumber, char ** ipAddress)
void getNonOtpArgs(char ** argv, int argc, int * portNumber, char * ipAddress[], bool portOnly)
{
*portNumber = atoi(argv[argc-2]);
*ipAddress = NULL;
*ipAddress = (char *)malloc(sizeof(argv[argc-1]));
strcpy(*ipAddress,argv[argc-1]);
if(portOnly)
{
*portNumber = atoi(argv[argc-1]);
}
else
{
*portNumber = atoi(argv[argc-2]);
*ipAddress = NULL;
*ipAddress = (char *)malloc(sizeof(argv[argc-1]));
strcpy(*ipAddress,argv[argc-1]);
}
}
void formatText(char * actualMessage, int num, int tailleMessage, char messageChar)
@ -74,71 +92,20 @@ void formatText(char * actualMessage, int num, int tailleMessage, char messageCh
}
int exitMax(int var,int tailleMax){
if(var>1500){
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<encadrementHaut-taillechaine+1;i++)
{
@ -175,5 +136,95 @@ int gestionOffset(char *actualMessage,int encadrementHaut,int encadrementBas,int
actualMessage[i]=numbuffer[j];
}
return encadrementHaut;
return encadrementHaut;
}
int recuperationParam(char * msgParam, int * messageOrPram, int * numEmetteurRecepteur, int * numTailleMessageParam, int * nbMessageParam)
{
*messageOrPram=msgParam[0]-0x30;
*numEmetteurRecepteur =protocol2int(msgParam,1);
*numTailleMessageParam=protocol2int(msgParam,MAX_MESSAGE+1);
*nbMessageParam=protocol2int(msgParam,(2*MAX_MESSAGE)+1);
return 0;
}
int protocol2int(char * data, int offset)
{
char buff[MAX_MESSAGE+1];
for(int i=offset,j=0;i<MAX_MESSAGE+offset;i++,j++)
{
buff[j]=data[i];
}
buff[MAX_MESSAGE+1]='\0';
return atoi(buff)%10000;
}
int connectTCP(int sock, struct sockaddr_in socketStruct, int tailleSocket)
{
int returnConnect = connect(sock,(struct sockaddr *)&socketStruct,(socklen_t)tailleSocket);
if(returnConnect == -1)
{
perror("[tsock] : fonction connect() : echec connexion\n");
};
return returnConnect;
}
void printAndVerif(char * sendingMessage,int tailleMessage,int longueurEmis, int count)
{
if(longueurEmis == -1)
{
perror("[tsock] : fonction sendto()/write() : echec d'envoi\n");
exit(EXIT_FAILURE);
}
printf("Source\tEnvoi n°%d (%d) :\t[%s]\n",count+1,longueurEmis,sendingMessage);
}
int initSocket(int socketType, struct sockaddr_in * socketStruct, int port, char * ipAddress)
{
int sockReturn,option=1;
if((sockReturn=socket(AF_INET,socketType,0)) == -1)
{
perror("[tsock] : fonction socket() : echec creation du socket\n");
exit(EXIT_FAILURE);
}
setsockopt(sockReturn, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
initStructSocket(socketStruct,0,port,ipAddress);
if (bind(sockReturn, (struct sockaddr *)socketStruct, sizeof(*socketStruct)) < 0 )
{
printf("[tsock] : socket n°%d : \n",sockReturn);
perror("[tsock] : fonction bind() : echec du lien avec socket serveur.\n");
exit(EXIT_FAILURE);
}
return sockReturn;
}
int openSocket(int socketType)
{
int returnSock;
if((returnSock=socket(AF_INET,socketType,0)) == -1)
{
perror("[tsock] : fonction socket() : echec creation du socket\n");
exit(EXIT_FAILURE);
}
return returnSock;
}
int listenAndAccept(int sock, struct sockaddr_in * socketStruct, int * sizeSocketStruct, bool closeSocket)
{
int listenStatus;
listenStatus = listen(sock,5);
if(listenStatus < 0)
{
perror("[tsock] : listen() failed.");
}
int returnSock = accept(sock,(struct sockaddr *)socketStruct,(socklen_t * restrict)sizeSocketStruct);
if(returnSock < 0)
{
perror("[tsock] : accept() failed.");
}
if(closeSocket)
{
close(sock);
}
return returnSock;
}