mirror of
https://github.com/yoboujon/tsock.git
synced 2025-06-08 14:00:50 +02:00
Boîte aux lettres fonctionnel même hors localhost. Ajout de nombreux commentaires dans puit.c.
This commit is contained in:
parent
5b9b17b50a
commit
a5180da73f
5 changed files with 145 additions and 56 deletions
|
@ -66,6 +66,20 @@ void receptionEmetteur(int sock, int tailleMessagePrevu, int * tailleMessageRecu
|
|||
* @param recepteur int, id du recepteur.
|
||||
* @param boiteAuxLettres struct listeBAL, la boite aux lettres à renvoyer.
|
||||
*/
|
||||
void receptionRecepteur(int sock, int recepteur, struct listeBAL boiteAuxLettres);
|
||||
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);
|
||||
|
||||
#endif
|
|
@ -174,7 +174,7 @@ int protocol2int(char * data, int offset);
|
|||
* @param socketStruct struct sockaddr_in, structure du socket
|
||||
* @param tailleSocket int, sizeof(socketStruct)
|
||||
*/
|
||||
void connectTCP(int sock, struct sockaddr_in socketStruct, int tailleSocket);
|
||||
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)
|
||||
|
@ -202,4 +202,23 @@ void printAndVerif(char * sendingMessage,int tailleMessage,int longueurEmis, int
|
|||
*/
|
||||
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
|
121
src/puit.c
121
src/puit.c
|
@ -4,13 +4,17 @@ int launchPuit(int nombreMessage,int tailleMessage,int isTCP,int port,char * ipA
|
|||
{
|
||||
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,ipAddress);
|
||||
return 0;
|
||||
}
|
||||
/*Sinon on initialise le socket de base et on rentre dans receiveMultipleData() -> on ferme le socket avant*/
|
||||
sock = initSocket(socketType,&socketPuit,port,ipAddress);
|
||||
receiveMultipleData(nombreMessage,tailleMessage,sock,socketPuit,isTCP);
|
||||
close(sock);
|
||||
|
@ -19,17 +23,20 @@ int launchPuit(int nombreMessage,int tailleMessage,int isTCP,int port,char * ipA
|
|||
|
||||
void modeBoiteAuxLettres(struct sockaddr_in socketStruct, int socketType, int port, char * ipAddress)
|
||||
{
|
||||
/*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();
|
||||
char paramRecu[13];
|
||||
int n, longueurRecu = sizeof(socketStruct),sock,oldSock, trueTemp = 1,option=1;
|
||||
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);
|
||||
close(oldSock);
|
||||
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,paramRecu,13);
|
||||
|
@ -37,18 +44,8 @@ void modeBoiteAuxLettres(struct sockaddr_in socketStruct, int socketType, int po
|
|||
switch(param)
|
||||
{
|
||||
case MODE_RECEPTEUR:
|
||||
close(sock);
|
||||
if((sock=socket(AF_INET,socketType,0)) == -1)
|
||||
{
|
||||
perror("[tsock] : fonction socket() : echec creation du socket\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
initStructSocket(&socketStruct,1,port,ipAddress);
|
||||
/*On attend 1 seconde pour que la source lance un listen TCP*/
|
||||
sleep(1);
|
||||
/*On lance une connexion TCP et on envoit à l'aide de receptionRecepteur() les données*/
|
||||
connectTCP(sock,socketStruct,sizeof(socketStruct));
|
||||
receptionRecepteur(sock,emetteurRecepteur,boiteAuxLettres);
|
||||
/*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;
|
||||
|
@ -60,25 +57,46 @@ void modeBoiteAuxLettres(struct sockaddr_in socketStruct, int socketType, int po
|
|||
break;
|
||||
}
|
||||
}
|
||||
/*Si on est en mode emis, le serveur affiche les données rentrées dans la boite aux lettres*/
|
||||
if(param == MODE_EMIS)
|
||||
{
|
||||
afficheListeBAL(boiteAuxLettres);
|
||||
}
|
||||
/*On ferme le socket qu'il provienne du MODE_RECEPTEUR ou MODE_EMIS*/
|
||||
close(sock);
|
||||
}
|
||||
}
|
||||
|
||||
void receptionRecepteur(int sock, int recepteur, struct listeBAL boiteAuxLettres)
|
||||
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;
|
||||
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);
|
||||
struct elementMessage * elementFinal = getMessages(boiteAuxLettres,recepteur)->fin;
|
||||
struct elementMessage * elementCourant = getMessages(boiteAuxLettres,recepteur)->courant;
|
||||
/*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,recepteur,elementCourant->messageBALActuel->tailleData,getMessages(boiteAuxLettres,recepteur)->nbMessages);
|
||||
printf("paramMessage [%d] = %s\n",i,paramMessage);
|
||||
longueurEmis = write(sock,paramMessage,13);
|
||||
printAndVerif(paramMessage,13,longueurEmis,i);
|
||||
|
||||
|
@ -87,12 +105,16 @@ void receptionRecepteur(int sock, int recepteur, struct listeBAL boiteAuxLettres
|
|||
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);
|
||||
|
@ -101,45 +123,48 @@ void receptionEmetteur(int sock, int tailleMessagePrevu, int * tailleMessageRecu
|
|||
|
||||
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;
|
||||
}
|
|
@ -88,9 +88,7 @@ void modeRecepteur(int recepteur,int sock,struct sockaddr_in * socketStruct,int
|
|||
|
||||
close(sock);
|
||||
oldSock = initSocket(SOCK_STREAM,socketStruct,port,ipAddress);
|
||||
listen(oldSock,5);
|
||||
sock = accept(oldSock,(struct sockaddr *)&socketStruct,(socklen_t * restrict)&tailleSocketStruct);
|
||||
close(oldSock);
|
||||
sock = listenAndAccept(oldSock,socketStruct,&tailleSocketStruct,true);
|
||||
while(i<nbMessage)
|
||||
{
|
||||
longueurEmis = read(sock,paramRecu,13);
|
||||
|
@ -100,4 +98,5 @@ void modeRecepteur(int recepteur,int sock,struct sockaddr_in * socketStruct,int
|
|||
printAndVerif(messageRecu,tailleMessage,longueurEmis,i);
|
||||
i++;
|
||||
}
|
||||
close(sock);
|
||||
}
|
38
src/tsock.c
38
src/tsock.c
|
@ -152,13 +152,14 @@ int protocol2int(char * data, int offset)
|
|||
return atoi(buff)%10000;
|
||||
}
|
||||
|
||||
void connectTCP(int sock, struct sockaddr_in socketStruct, int tailleSocket)
|
||||
int connectTCP(int sock, struct sockaddr_in socketStruct, int tailleSocket)
|
||||
{
|
||||
if(connect(sock,(struct sockaddr *)&socketStruct,(socklen_t)tailleSocket) == -1)
|
||||
int returnConnect = connect(sock,(struct sockaddr *)&socketStruct,(socklen_t)tailleSocket);
|
||||
if(returnConnect == -1)
|
||||
{
|
||||
perror("[tsock] : fonction connect() : echec connexion\n");
|
||||
exit(EXIT_FAILURE);
|
||||
};
|
||||
return returnConnect;
|
||||
}
|
||||
|
||||
void printAndVerif(char * sendingMessage,int tailleMessage,int longueurEmis, int count)
|
||||
|
@ -189,3 +190,34 @@ int initSocket(int socketType, struct sockaddr_in * socketStruct, int port, char
|
|||
}
|
||||
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;
|
||||
}
|
Loading…
Add table
Reference in a new issue