//--------------------------PROG C ET RESEAUX----------------------- // Nom : Quintana // Prénom : Béranger // Grp : 3AE E //------------------------------------------------------------------ #ifndef __tsock__ //Variable qui donne la longueur max d'un message int maxsize=9999; //Définitions des types typedef struct BAL { int num ; int nb; struct LETTRE * l_first ; struct LETTRE * l_last ; struct LETTRE * l_current ; struct BAL * suiv ; }BAL ; typedef struct LETTRE { int num ; int lg; char *message ; struct LETTRE * suiv ; }LETTRE ; typedef struct LISTE_BAL { struct BAL * first ; struct BAL * last ; struct BAL * current ; int nb; }LISTE_BAL; //--------------------------------------------------- //---------Déclaration des fonctions----------------- //--------------------------------------------------- LISTE_BAL* init_BAL(); void add_BAL(int num , LISTE_BAL* liste); BAL* find_BAL(LISTE_BAL*liste, int num); int find_BALR(LISTE_BAL*liste, int num); void add_LETTRE (int n, int lg, BAL* bal , char* mess); void printBAL(BAL* bal,int lg); void empty(BAL*bal); void EBAL(int port, char* dest, int nb_message, int lg_msg, int nBAL); void SBAL(int port, char* dest); void RBAL(int port, char* dest, int nBAL); //--------------------------------------------------- //--------------------GESTION BAL-------------------- //--------------------------------------------------- LISTE_BAL* init_BAL() { LISTE_BAL* liste =(LISTE_BAL*)malloc(sizeof(struct LISTE_BAL)); liste->first = NULL; liste->last=NULL; liste->current = NULL; liste->nb=0; return liste ; } //------------------------------------------------ //----Afficher le contenu d'une Liste de BAL------ //6----------------------------------------------- void printLISTE(struct LISTE_BAL* liste) { printf(" __________________________________________\n"); printf(" Check général des BAL de notre liste :\n\n"); printf(" %d BAL dans notre liste \n\n",liste->nb); liste->current=liste->first; while (liste->current!=NULL) { printf(" BAL n°%d : %d Lettres \n",liste->current->num,liste->current->nb); liste->current=liste->current->suiv; } printf(" __________________________________________\n\n"); } //------------------------------------------------ //--------Afficher le contenu d'une BAL----------- //------------------------------------------------ void printBAL(BAL* bal,int lg) { printf("Contenu de la BAL n°%d qui contient %d lettres \n",bal->num,bal->nb) ; bal->l_current=bal->l_first; printf("\n"); int n=1; while(bal->l_current!=NULL) { printf("BAL n°%d | %d Lettres, lettre n°%d : [",bal->num,bal->nb,n); afficher_message(bal->l_current->message,lg); bal->l_current=bal->l_current->suiv; n++; } printf("\n\n"); } //------------------------------------------------ //----------------Ajouter une BAL----------------- //------------------------------------------------ void add_BAL(int n, LISTE_BAL * liste) { BAL *nouv =malloc(sizeof(struct BAL)); nouv->num=n; nouv->nb=0; nouv->l_first=NULL; nouv->l_last=NULL; nouv->l_current=NULL; nouv->suiv=NULL; if (liste->first == NULL) { liste->first = nouv ; liste->last = nouv ; } else { liste->last->suiv= nouv ; liste->last=nouv ; } liste->nb++; } //------------------------------------------------ //----Retourne une BAL en fonction de son num----- //6----------------------------------------------- BAL* find_BAL(LISTE_BAL*liste, int num) { BAL* bal=malloc(sizeof(struct BAL)); liste->current=liste->first; if (liste->first==NULL) { add_BAL(num,liste); bal=liste->first; } else { liste->current=liste->first; if (liste->first==liste->last) { if (liste->first->num==num) bal=liste->current; else { add_BAL(num,liste); bal=liste->last; } } else if (liste->first->num==num) bal=liste->first; else { int var=0; while(var==0) { if (liste->current->suiv==NULL) var=-1; else { liste->current=liste->current->suiv; if (liste->current->num==num) var=1; if (liste->current==NULL) var=-1; } } if (var==1) bal=liste->current; else { add_BAL(num,liste); bal=liste->last; } } } return bal; } //-------------------------------------------------------------------------------------------- //----------------------------------------findBALR-------------------------------------------- //-------Retourne -1 si BAL inexistante ou BAL Vide, lg 1ère lettre si BAL existante---------- //-------------------------------------------------------------------------------------------- int find_BALR(LISTE_BAL*liste, int num) { int ret; if (liste->first==NULL) { ret=-1; } else { liste->current=liste->first; if (liste->current==liste->last) { if (liste->current->num==num) { if (liste->current->l_first==NULL) ret=-1; else ret=liste->current->l_first->lg; } else ret=-1; } else if (liste->first->num==num) { if (liste->current->l_first==NULL) ret=-1; else ret=liste->current->l_first->lg; } else { int var=0; while(var==0) { if (liste->current->suiv==NULL) var=-1; else { liste->current=liste->current->suiv; if (liste->current->num==num) var=1; if (liste->current==NULL) var=-1; } } if (var==1) { if (liste->current->l_first==NULL) ret=-1; else ret=liste->current->l_first->lg; } else ret=-1; } } return ret; } //----------------------------------------------------------------- //----------------Ajouter une lettre en fin de BAL----------------- //----------------------------------------------------------------- void add_LETTRE (int n, int lg, BAL* bal , char* mess) { bal->nb=(bal->nb)+1; LETTRE* nouv; nouv=(LETTRE*)malloc(sizeof(LETTRE)); nouv->num=n+1; nouv->lg=lg; nouv->suiv=NULL; if (bal->l_first==NULL) { bal->l_first=nouv; bal->l_last=nouv; bal->l_current=nouv; } else { bal->l_last->suiv=nouv; bal->l_last=bal->l_last->suiv; } nouv->message=malloc(lg* sizeof(char)); for (int i=0 ; imessage[i] = mess[i]; } //------------------------------------------------------------------------------------- //----------------Détruit une liste de BAL en fin d'utilisation de BAL----------------- //6------------------------------------------------------------------------------------ void empty(BAL*bal) { bal->l_current=bal->l_first; while(bal->l_current!=NULL) { bal->l_current=bal->l_current->suiv; free(bal->l_first); bal->l_first=bal->l_current; (bal->nb)--; } } void EBAL(int port, char* dest, int nb_message, int lg_msg, int nBAL) { //Déclarations int sock; struct sockaddr_in addr_distant ; int lg_addr_distant=sizeof(addr_distant); struct hostent *hp; char motif; char * message=malloc(lg_msg*sizeof(char)); int envoi=-1; int lg_pdu=50; int lg_recv; char*pdu=malloc(lg_pdu*sizeof(char)); //--------------------------------------- //--------Etablissement connexion-------- //--------------------------------------- printf(" SOURCE : Emission de lettres pour la BAL n°%d\n",nBAL); printf("____________________________________________________________________\n\n"); sprintf(pdu,"0 %d %d %d",nBAL, nb_message,lg_msg); //Création socket if((sock=socket(AF_INET,SOCK_STREAM,0))==-1) { printf("Erreur à l'ouverture du Socket Stream"); exit(1); } //Construction adresse socket distant memset((char*)&addr_distant,0,sizeof(addr_distant)); addr_distant.sin_family=AF_INET; //Internet addr_distant.sin_port=port; //Numéro de Port //Affectation IP if((hp=gethostbyname(dest))==NULL) { printf("Erreur de requête IP.\n"); exit(1); } memcpy((char*)&(addr_distant.sin_addr.s_addr), hp->h_addr , hp->h_length); //Demande de connexion if (connect(sock,(struct sockaddr *)&addr_distant,sizeof(addr_distant))==-1) { printf("Erreur lors de la connexion, en attente de la tentative suivante \n"); exit(1); } //----------------------------------------- //----------------Envoi PDU---------------- //----------------------------------------- if ((envoi=write(sock,pdu,lg_pdu))==-1) { printf("Echec de l'envoi du PDU Emetteur (fonction write en défaut)\n"); exit(1); } //----------------------------------------- //----------TRANSFERT DE DONNEES----------- //----------------------------------------- for (int i=1; i<=nb_message;i++) { printf("SOURCE : lettre n°%d (%d) [", i,lg_msg); //Création du message construire_message2(message,motif,lg_msg,i); printbuffer2(nBAL,message); afficher_message(message,lg_msg); //Envoi du message if ((envoi=write(sock,message,(lg_msg)/*,0,(struct sockaddr*)&addr_distant,lg_addr_distant)*/))==-1) { printf("Echec de l'envoi du message (fonction write en défaut)\n"); exit(1); } } //Fermeture connexion if(shutdown(sock,2)==-1) { printf("Erreur à la fermeture de la connexion TCP \n"); exit(1); } //Fermeture Socket if (close(sock)==-1) { printf("Echec de la fermeture du socket distant"); exit(1); } free(message); free(pdu); printf("Envoi effectué avec succès\n"); } void SBAL(int port, char*dest) { //Déclarations int sock , sock2; //sock bis local orienté échanges struct sockaddr* addr_distant; struct sockaddr_in addr_local; int lg_addr_distant=sizeof(addr_distant); int lg_addr_local=sizeof(addr_local); struct hostent *hp; char motif; char *message; int lg_recv=-1; int lg_sent=-1; int lg_pdu=50; int type=-1; int nb; int lg; int n=1; int nBAL; BAL*bal=malloc(sizeof(struct BAL)); char *pdu;//=malloc(sizeof(char)); LISTE_BAL* liste; //---------------------------------- //------------Connexion ------------ //---------------------------------- //Création socket local if ((sock=socket(AF_INET,SOCK_STREAM,0))==-1) { printf("Echec de la création d'un socket local\n"); exit(1); } //Construction adresse socket local | Affectation port et domaine memset((char*)&addr_local, 0 , sizeof(addr_local)); addr_local.sin_family=AF_INET; addr_local.sin_addr.s_addr=INADDR_ANY; addr_local.sin_port=port; //Bind if (bind(sock,(struct sockaddr *)&addr_local, lg_addr_local)==-1) { printf("Echec du bind.\n"); exit(1); } //Check connexions entrantes if (listen(sock,100)<0) { printf("Trop de connexions en attentes, échec de la demande\n"); exit(1); } liste=init_BAL(); while (1) { if ((sock2=accept(sock,(struct sockaddr*)&addr_distant,&lg_addr_distant))==-1) { printf("Refus de connexion par le serveur\n"); exit(1); } pdu=malloc(50*sizeof(char)); if((lg_pdu=read(sock2,pdu, lg_pdu))<0) { printf("Echec de lecture du PDU entrant\n"); exit(1); } sscanf(pdu, "%d %d %d %d", &type, &nBAL, &nb, &lg); //GESTION EMETTEUR if (atoi(pdu)==0) { printf(" ||||||| Réception des lettres pour la BAL n°%d |||||\n\n",nBAL); message=malloc(lg*sizeof(char)); int n=0; sscanf(pdu, "%d %d %d %d", &type, &nBAL, &nb, &lg); bal=find_BAL(liste,nBAL); while (n!=nb) { message = malloc(lg* sizeof(char)); if ((lg_recv = read(sock2, message, lg)) == -1) { printf("Erreur de lecture\n"); exit(1); } if (lg_recv>0) { add_LETTRE(n,lg, bal,message); } n++; } printBAL(bal,lg); } //GESTION RECEPTEUR else if (atoi(pdu)==1) { sscanf(pdu, "%d %d", &type, &nBAL); printf(" ||||||| Restitution des lettres de la BAL n°%d |||||||\n\n",nBAL); lg=find_BALR(liste,nBAL); if (lg==-1) // Gestion du cas ou la BAL est vide, on envoie un PDU qui sera analysé par le récepteur. { printf(" BAL inexistante, PDU=0 pour informer le récepteur\n\n"); sprintf(pdu,"%d %d",lg,nb); //printf ("PDU à envoyer : %d\n",lg); int lg_sent=-1; nb=1; if ((lg_sent=write(sock2,pdu,lg_pdu))==-1) /*,0,(struct sockaddr*)&addr_distant,lg_addr_distant)*/ { printf("Echec de l'envoi du PDU (fonction write en défaut)\n"); exit(1); } } else { bal=find_BAL(liste,nBAL); bal->l_current=bal->l_first; while(bal->l_current!=NULL) { lg=bal->l_current->lg; nb=bal->nb; sprintf(pdu,"%d %d",lg,nb); if ((lg_sent=write(sock2,pdu,lg_pdu))==-1) /*,0,(struct sockaddr*)&addr_distant,lg_addr_distant)*/ { printf("Echec de l'envoi du PDU Emetteur (fonction write en défaut)\n"); exit(1); } message=malloc(lg*sizeof(char)); message=bal->l_current->message; if ((lg_sent=write(sock2,message,lg))==-1) { printf("Erreur lors de l'envoi du message n°%d\n",n); exit(1); } printf("BAL n°%d : Restitution de la lettre n°%d (%d) [",nBAL,n,lg); afficher_message(message,lg); bal->l_current=bal->l_current->suiv; n++; } empty(bal); if ((shutdown(sock2 , 2))==-1) { printf("Erreur à la fermeture de la connexion : shutdown\n"); exit(1); } } } else { printf("PDU non reconnu, on quitte par sécurité\n"); exit(1); } printLISTE(liste); free(pdu); free(message); } } void RBAL(int port, char* dest, int nBAL) { //Déclarations int sock; struct sockaddr_in addr_distant; int lg_addr_distant = sizeof(addr_distant); struct hostent *hp; char *message; //Penser au free en fin de programme pour libérer l'espace mémoire int envoi = -1; int lg_pdu=50; int lg_recv=-1; int lg; int nb; char *pdu = malloc(lg_pdu*sizeof(char)); //--------------------------------------- //--------Etablissement connexion-------- //--------------------------------------- sprintf(pdu,"1 %d",nBAL); if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("Erreur à l'ouverture du Socket Stream"); exit(1); } //Construction adresse socket distant memset((char *) &addr_distant, 0, sizeof(addr_distant)); addr_distant.sin_family = AF_INET; //Internet addr_distant.sin_port = port; //Numéro de Port //Affectation IP if ((hp = gethostbyname(dest)) == NULL) { printf("Erreur de requête IP.\n"); exit(1); } memcpy((char *) &(addr_distant.sin_addr.s_addr), hp->h_addr, hp->h_length); //Demande de connexion if (connect(sock, (struct sockaddr *) &addr_distant, sizeof(addr_distant)) == -1) { printf("Erreur lors de la connexion, en attente de la tentative suivante \n"); exit(1); } //----------------------------------------- //----------------Envoi PDU---------------- //----------------------------------------- if ((envoi = write(sock, pdu, lg_pdu)) == -1) /*,0,(struct sockaddr*)&addr_distant,lg_addr_distant)*/ { printf("Echec de l'envoi du PDU Emetteur (fonction write en défaut)\n"); exit(1); } char*lgmsg=malloc(maxsize* sizeof(char)); nb=10; int n=1; lg_recv=1; printf(" PUITS : Réception du contenu de la BAL n°%d\n",nBAL); printf("____________________________________________________________________\n\n"); while(n<=nb) { if ((lg_recv=read(sock,lgmsg,lg_pdu))==-1) { printf("Erreur à la réception du PDU de longueur de message\n"); exit(1); } sscanf(lgmsg,"%d %d", &lg , &nb); if (lg==-1) { printf(" ATTENTION : Pas de courrier à récupérer dans la BAL n°%d\n\n",nBAL); exit(0); } message=malloc(lg*sizeof(char)); if ((lg_recv=read(sock,message,lg))==-1) { printf("Erreur à la réception du message\n"); exit(1); } printf("PUITS : Réception de la lettre n°%d : [",n); afficher_message(message,lg); n++; } printf("Fermeture de la Connexion\n"); //Ciao le socket if(close(sock)==-1) { printf("Impossible de fermer le socket"); exit(1); } } #endif