/* * mEtMmeServeur_threadQ2.corrige.c * * * */ #include #include #include #include #include #include #include #include #include #include #include #include "client-serveur.corrige.h" #define NBPOOL 3 sem_t placeDispo; sem_t infoPrete; pthread_mutex_t mutex_extrait; int iExtrait = 0; int iDepot = 0; requete_t requetes[NBPOOL]; void P(sem_t *semaphore) { sem_wait(semaphore); } void V(sem_t *semaphore) { int retcode; retcode = sem_post(semaphore); if (retcode == -1) { /* errno ERANGE, EBUSY */ perror("sem_post"); exit(EXIT_FAILURE); } } void _traiterRequete(FILE *f, requete_t *requete) { reponse_t reponse; char ligne[256]; int nbWrite; /* chaque thread a son propre point d'acces client */ int fdW; int retcode; fdW = open(requete->pointAccesClient, O_WRONLY); if (fdW == -1) { perror("open(pointAccessClient)"); exit(EXIT_FAILURE); } sleep(1); /* Calcul reponse.pointAccesPrive */ strcpy(reponse.pointAccesPrive, ""); /* Le point d'accès privé n'est pas utilisé cote serveur */ /* retour en debut de fichier */ retcode = fseek(f, 0, SEEK_SET); if (retcode == -1) { perror("fseek"); 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"); } /* Affichage */ printf("0x%x: Serveur a recu \"%s\" et repond \"%s\"\n", (unsigned int)pthread_self(), requete->contenu, reponse.contenu ); nbWrite = write(fdW, &reponse, sizeof(reponse)); if (nbWrite < sizeof(reponse)) { perror("pb ecriture sur pipe nomme"); exit(EXIT_FAILURE); } close(fdW); } void *traiterRequete(void *arg){ FILE *f; requete_t *requete; /* Calcul reponse.contenu */ f = fopen("mEtMme.txt", "r"); if (f == NULL) { perror("open(mEtMme.txt)"); exit(EXIT_FAILURE); } while(1) { requete_t requete; P(&infoPrete); /* Connexion au point d'accès client et réponse */ pthread_mutex_lock(&mutex_extrait); memcpy (&requete, &requetes[iExtrait], sizeof(requete_t)); iExtrait = (iExtrait + 1) % NBPOOL; pthread_mutex_unlock(&mutex_extrait); _traiterRequete(f, &requete); V(&placeDispo); } fclose(f); return NULL; } int main() { pthread_attr_t attr; pthread_t pthreads[NBPOOL]; int fdR; int nbRead; int retcode; int i; /* 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); pthread_mutex_init(&mutex_extrait, NULL); sem_init(&infoPrete, 0, 0); sem_init(&placeDispo, 0, NBPOOL); /* On traite la requête */ for(i = 0; i < NBPOOL; i ++) { retcode = pthread_create(&(pthreads[i]), &attr, traiterRequete, NULL); if (retcode != 0) { fprintf(stderr, "pthread_create: %s", strerror(retcode)); exit(EXIT_FAILURE); } } /* Boucle principale */ while (1) { /* Attente d'une requête */ P(&placeDispo); nbRead = read(fdR, &(requetes[iDepot]), sizeof(requete_t)); if (nbRead != sizeof(requete_t)) { printf("Communication avec le client probablement rompue\n"); exit(EXIT_FAILURE); } iDepot = (iDepot + 1) % NBPOOL; V(&infoPrete); } pthread_attr_destroy(&attr); pthread_mutex_destroy(&mutex_extrait); sem_destroy(&infoPrete); sem_destroy(&placeDispo); close(fdR); return EXIT_SUCCESS; }