#include <stdio.h> #include <stdlib.h> #include "reseau.h" #define SOURCE 26 #define DESTINATION 42 #define MAXRETRANSMISSION 10 #define FEMISSION "flux1.dat" #define FRECEPTION "flux2.dat" int erreurcrc=0; void envoyer(ttrame Trame) /* Envoie la trame Trame vers la couche physique en rajoutant si nécessaire des erreurs */ { if ((erreurcrc!=0) && ((rand() % erreurcrc)==0)) { Trame.CRC++; envoyer_vers_couche_physique(Trame); Trame.CRC--; } else envoyer_vers_couche_physique(Trame); return; } char entre(int a, int b, int c) { return( ((a<=b)&&(b<c)) || ((c<a)&&(a<=b)) || ((b<c)&&(c<a)) ); } int main(int argc, char **argv) /* Programme principal, argument optionnel : quantité d'erreurs */ { int AS,AD; ttrame buffer[MAXTAILLEFENETRE]; int compteur[MAXTAILLEFENETRE]; int i, numack, ack_attendu=0, trame_a_emettre=0, nbuffer=0; ttampon TamponEmission, tamponaux; ttrame Trame; char recepteur_pret=1; if (argc>1) erreurcrc=atoi(argv[1]); fprintf(stderr,"Initialisation du protocole 4, erreurcrc=%d\n",erreurcrc); initialise_couche_physique(FEMISSION, FRECEPTION); initialise_couche_reseau(SOURCE, DESTINATION); while (1) { if (recepteur_pret && signale(SIGEMIS) && (nbuffer<MAXTAILLEFENETRE-1)) { prendre_de_la_couche_reseau(&AS, &AD, &TamponEmission); construire_trame(trame_a_emettre, AS, AD, TamponEmission, &buffer[trame_a_emettre]); nbuffer++; fprintf(stderr,"Envoi de trame %d : %d->%d, %s\n",trame_a_emettre,AS,AD,TamponEmission.info); envoyer(buffer[trame_a_emettre]); tempo(trame_a_emettre); compteur[trame_a_emettre]=MAXRETRANSMISSION; trame_a_emettre=(trame_a_emettre+1)%MAXTAILLEFENETRE; } if (signale(SIGTEMPO)) { fprintf(stderr,"Timeout\n"); trame_a_emettre=ack_attendu; for (i=0;i<nbuffer;i++) { if (compteur[trame_a_emettre]==0) { fprintf(stderr,"Trop d'erreurs de retransmission\n"); return(1); } fprintf(stderr,"Renvoi de trame %d : %d->%d, %s\n",trame_a_emettre,AS,AD,buffer[trame_a_emettre].tampon.info); envoyer(buffer[trame_a_emettre]); tempo(trame_a_emettre); compteur[trame_a_emettre]--; trame_a_emettre=(trame_a_emettre+1)%MAXTAILLEFENETRE; } } if (signale(SIGRECU)) { prendre_de_la_couche_physique(&Trame); recuperer_donnees(Trame,&tamponaux,&numack,&AS,&AD); fprintf(stderr,"ACK RECU %d, ACK ATTENDU %d, TRAME A EMETTRE %d\n",numack,ack_attendu,trame_a_emettre); while (entre(ack_attendu,numack,trame_a_emettre)) { fprintf(stderr,"Trame %d acquitee\n",ack_attendu); nbuffer--; stoptempo(ack_attendu); ack_attendu=(ack_attendu+1)%MAXTAILLEFENETRE; } switch (tamponaux.info[0]) { case 'R':{ if (recepteur_pret==0) fprintf(stderr,"RR recu\n"); recepteur_pret=1; break; } case 'N':{ recepteur_pret=0; fprintf(stderr,"RNR recu\n"); break; } } } } return(0); }