#include #include #include #include #include #include #include #include #include #include #include "client-serveur.corrige.h" void *traiterRequete(void *arg){ /* chaque thread a sa propre reponse */ reponse_t reponse; char ligne[256]; /* chaque thread gere son propre pointeur de flux */ FILE *f; /* chaque thread a son propre point d'acces client */ int fdW; int nbWrite; requete_t *requete; requete = (requete_t *)arg; /* Calcul reponse.pointAccesPrive */ strcpy(reponse.pointAccesPrive, ""); /* Le point d'accès privé n'est pas utilisé dans cette appli */ /* Calcul reponse.contenu */ /* chaque thread ouvre le fichier de manière à ne pas partager f */ f = fopen("mEtMme.txt", "r"); if (f == NULL) { perror("open(mEtMme.txt)"); exit(EXIT_FAILURE); } while (feof(f) == 0) { if (fgets(ligne, sizeof(ligne), f) != NULL) { if (strncmp(ligne, requete->contenu, strlen(requete->contenu)) == 0) { break; } } } if (feof(f) == 0) { strcpy(reponse.contenu, ligne); reponse.contenu[strlen(ligne)-1] = '\0'; /* Supprime le '\n' final */ } else { strcpy(reponse.contenu,"Desole, je ne le connais pas"); } fclose(f); /* Affichage */ printf("0x%x: Serveur a recu \"%s\" et repond \"%s\"\n", (unsigned int)pthread_self(), requete->contenu, reponse.contenu ); /* Connexion au point d'accès client et réponse */ /* chaque thread a son propre point d'acces client */ fdW = open(requete->pointAccesClient, O_WRONLY); if (fdW == -1) { perror("open(pointAccessClient)"); exit(EXIT_FAILURE); } nbWrite = write(fdW, &reponse, sizeof(reponse)); if (nbWrite < sizeof(reponse)) { perror("pb ecriture sur pipe nomme"); exit(EXIT_FAILURE); } /* Dans cette application, le client ne renvoie pas de requête ultérieure*/ /* nécessitant une réponse ==> On peut fermer ce tube */ close(fdW); /* liberation de la requete allouee par le thread principal */ free(requete); pthread_exit(NULL); } int main() { pthread_attr_t attr; pthread_t pthread; requete_t *requete; int fdR; int nbRead; int retcode; /* Création du tube nommé du serveur */ if (mkfifo(NOMPOINTACCESSERV, S_IRUSR|S_IWUSR) < 0) { if (errno != EEXIST) { perror("mkfifo(tube nommé client"); exit(EXIT_FAILURE); } else { printf("%s existe deja : on suppose que c'est un pipe nomme\n", NOMPOINTACCESSERV ); printf("et qu'on peut continuer le programme sans probleme\n"); puts(""); } } /* * Ouverture de ce tube nommé (équivalent à une attente de connexion) * * Ouverture en ecriture pour que la connexion ne se termine pas * a la terminaison du client. * */ fdR = open(NOMPOINTACCESSERV, O_RDWR); if (fdR == -1) { perror("open(tube nommé)"); exit(EXIT_FAILURE); } pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); /* Boucle principale */ while (1) { /* une requete pour chaque thread pour ne pas les partager! * requete est liberee par le thread */ requete = malloc(sizeof(requete_t)); if (requete == NULL) { perror("malloc"); exit(EXIT_FAILURE); } /* Attente d'une requête */ nbRead = read(fdR, requete, sizeof(requete_t)); if (nbRead != sizeof(requete_t)) { printf("Communication avec le client probablement rompue\n"); exit(EXIT_FAILURE); } /* On traite la requête */ retcode = pthread_create(&pthread, &attr, traiterRequete, requete); if (retcode != 0) { perror("pthread_create"); exit(EXIT_FAILURE); } } pthread_attr_destroy(&attr); close(fdR); return EXIT_SUCCESS; }