TP7 init.c #include<stdio.h> #include<sys/types.h> #include<stdlib.h> #include<errno.h> #include<sys/ipc.h> #include<sys/msg.h> #define CLE 555 int msqid; if((msqid=msgget((key_t) CLE,IPC_CREAT 0666))==-1)//creation de la file de message perror("echec de msgget"); printf("identificateur interne de la file : %d\n",msqid);//recuperation des caractã ristique de la file printf("cette file est identifiee par la cle unique : %d\n",(key_t)cle); exit(0); message.h #ifndef MESSAGE_H #define MESSAGE_H #include<stdio.h> #include<string.h> #include<sys/types.h> #include<stdlib.h> #include<errno.h> #include<sys/ipc.h> #include<sys/msg.h> #define CLE 555 typedef struct int numero;//numero de l'etudiant char nom[10]; float notes[5]; char MPass[10]; ETUDIANT; typedef struct long type;//type du message long pid;//le pid du processus client char commande; ETUDIANT etudiant; short resultat; MESSAGE; void init(); int getmsgid(); #endif
message.h void init() int msqid; if((msqid=msgget((key_t) CLE,IPC_CREAT 0666))==-1) perror("echec de msgget"); printf("identificateur interne de la file : %d\n",msqid); printf("cette file est identifiee par la cle unique : %d\n",(key_t)cle); int getmsgid(void) int id; if((id=msgget((key_t) CLE,IPC_CREAT 0666))==-1) perror("echec de msgget"); return id; serveur.c #include<stdio.h> MESSAGE mess; ETUDIANT etud[3]; int msqid,i; //initialisation de trois etudiants etud[0].numero=0; etud[1].numero=1; etud[2].numero=2; strcpy(etud[0].nom,"tata"); strcpy(etud[1].nom,"tete"); strcpy(etud[2].nom,"titi"); strcpy(etud[0].mpass,"tata"); strcpy(etud[1].mpass,"tete"); strcpy(etud[2].mpass,"titi"); etud[0].notes[0]=01;etud[0].notes[1]=02;etud[0].notes[2]=03;etud[0].notes[3]=04;etud[0].notes[4]=05; etud[1].notes[0]=11;etud[1].notes[1]=12;etud[1].notes[2]=13;etud[1].notes[3]=14;etud[1].notes[4]=15; etud[2].notes[0]=21;etud[2].notes[1]=22;etud[2].notes[2]=23;etud[2].notes[3]=24;etud[2].notes[4]=25; init(); msqid=getmsgid(); int type=0; while(1)//reception message; msgrcv(msqid,&mess,sizeof(mess),-2,0); if (mess.type==1)//cote enseignant printf("je gere un enseignant\n"); mess.etudiant=etud[mess.etudiant.numero];//on recupere les donnees enregistree dans la structure printf("num de l'etudiant : %d\n",mess.etudiant.numero); for(i=0;i<=4;i++) etud[mess.etudiant.numero].notes[i]=mess.etudiant.notes[i];//recuperation note par note printf("."); printf("notes recuperees\n"); mess.resultat=0; mess.type=mess.pid;
//envoie des donnees relative a l'etudiant à l'enseignant printf("fin de l'envoi des notes initiales\n\n"); //attente du message avec une note modifiee type=0; while(type!=1)//pour éviter de recevoir un message d'un etudiant. c'est la raison pour laquel ca bloque cote etudiant. msgrcv(msqid,&mess,sizeof(mess),-2,0); if(mess.type==1) type=1; //c'est ici qu'il faudrait recupere les donnees, sans avoir bloque l'etudiant printf("seconde reception du serveur\n"); //on est toujours sur le meme etudiant : pas besoin d'aller chercher des donnees printf("num de l'etudiant : %d",mess.etudiant.numero); for(i=0;i<=4;i++) printf("\n **notes modifiees** %d : ",i+1); etud[mess.etudiant.numero].notes[i]=mess.etudiant.notes[i]; printf("%f",mess.etudiant.notes[i]); printf("\n"); mess.resultat=0; mess.type=mess.pid; //envoie des nouvelles notes printf("fin de l'envoi\n\n\n\n"); printf("j'ai termine avec l'enseignant\n***********************\n\n"); if(mess.type==2)//coté etudiant printf("je gere un etudiant\n"); char motdepasse[10]; return 0; strcpy(motdepasse,mess.etudiant.mpass);//on recupere tout d'abord le mot de passe entre mess.resultat=0; mess.type=mess.pid; if(strcmp(motdepasse,etud[mess.etudiant.numero].mpass)==0) mess.etudiant=etud[mess.etudiant.numero];//si bon mot de passe, alors envoi des donnes else mess.resultat=1;//on renvoie une erreur, et pas les notes printf("j'ai termine avec l'etudiant\n**************************\n\n");
enseignant.h //on a reussi a faire en sorte (au niveau du serveur) que si un enseignant a pris la main, alors le serveur fini de s'occuper de lui, pour ne pas perdre les infos sur l'etudiant manipuler. Le probleme est donc qu'un etudiant ne peut pas consulter si un enseignant modifie les notes. //une solution pourrait etre de sauvegarder les donnees (cote serveur) et les recuperer apres reception du message de type 1 (enseignant) #include <unistd.h> int msqid,num,i,note; char com; char buf; MESSAGE mess; msqid=getmsgid(); while (1) printf("ecrire Notes (E) ou Quitter(Q)?\n"); scanf("%c",&com); if(com=='e' com=='e') printf("numero de l'etudiant (0,1 ou 2)?\n");//choix de l'etudiant pour afficher ses notes ensuite scanf("%d",&num); //sert a vider le buffer mess.etudiant.numero=num;//parametrage du message mess.type=1; mess.pid=getpid(); mess.resultat=-1; printf("envoi des informations\n"); //envoie du message au serveur pour lui indiquer l'étudiant 'manipule' if(msgsnd(msqid,&mess,(sizeof(mess)-sizeof(long)),0)==-1) perror("impossible d'envoyer le message"); //on recoit les donnees relatives a l'etudiant : les notes msgrcv(msqid,&mess,sizeof(mess)-sizeof(mess.type), mess.pid,0); if(mess.resultat!=-1) printf("etudiant numero %d\n",mess.etudiant.numero);//boucle d'affichage des notes de l'etudiant for(i=0;i<5;i++) printf("notes%d: %f\n",i+1,mess.etudiant.notes[i]); //modification d'une note printf("\nnumero de la note a modifier (1 a 5) : \n"); scanf("%d",&num); printf("nouvelle note : "); scanf("%d",¬e); mess.type=1;//parametrage du message mess.etudiant.notes[num-1]=note; //envoi de la valeur perror("impossible d'envoyer le message depuis enseignant"); msgrcv(msqid,&mess,sizeof(mess)-sizeof( mess.type), mess.pid,0);//notes recus if(mess.resultat!=-1) printf("apres modification :\n");
for(i=0;i<5;i++) printf("notes %f\n",mess.etudiant.notes[i]);//affichage de ses notes else //pas de saisie protegee pour quitter exit(0); return 0; etudiant.c //le probleme de ce code est que si l'enseignant est en train de modifier un etudiant, alors l'execution de etudiant est bloquée (on ne peut que l'arreter avec ctrl+z) //les donnes concernant un etudiant sont codes en statique dans serveur.c #include <unistd.h> char mdp[10]; int msqid,num,i; char com; char buf; MESSAGE mess; msqid=getmsgid(); while (1) printf("consulter Notes (C) ou Quitter(Q)?\n"); scanf("%c",&com); if(com=='c' com=='c') //on va d'abord envoyer le numã ro de l'etudiant avec un mot de passe. si ca correspond, alors on affiche les notes. sinon, on recommence la boucle. (pas de compteur de nombre d'erreur printf("numero de l'etudiant (0,1 ou 2)?\n"); scanf("%d",&num); //vidage du buffer printf("mot de passe : "); scanf("%s",mdp); mess.etudiant.numero=num;//copie des donnees pour les comparer ensuite, au niveau du serveur strcpy(mess.etudiant.mpass,mdp); mess.type=2; mess.pid=getpid(); mess.resultat=-1; printf("envoi des informations\n"); l'ã tudiant 'manipule' if(msgsnd(msqid,&mess,(sizeof(mess)-sizeof(long)),0)==-1)//envoie du message au serveur pour lui indiquer perror("impossible d'envoyer le message"); msgrcv(msqid,&mess,sizeof(mess)-sizeof(mess.type), mess.pid,0);//on recoit soit les donnees relatives a l'etudiant, soit une erreur (si mess.resultat = 1)
else return (0); if(mess.resultat==1) printf("erreur de Mot de passe\n"); if(mess.resultat==0)//bon mot de passe printf("etudiant numero %d\n",mess.etudiant.numero);//affichage de l'etudiant //boucle d'affichage des notes for(i=0;i<5;i++) printf("notes %f\n",mess.etudiant.notes[i]); exit(0); makefile all: serveur delete enseignant init etudiant delete: message.o delete.o gcc -o delete message.o delete.o serveur: message.o serveur.o gcc -o serveur message.o serveur.o init: init.o gcc -o init init.o enseignant: message.o enseignant.o gcc -o enseignant message.o enseignant.o etudiant: etudiant.o etudiant.o gcc -o etudiant message.o etudiant.o message.o: message.c gcc -o message.o -c message.c -g -Wall delete.o: delete.c message.h gcc -o delete.o -c delete.c -g -Wall serveur.o: serveur.c message.h gcc -o serveur.o -c serveur.c -g -Wall enseignant.o: enseignant.c message.h gcc -o enseignant.o -c enseignant.c -g -Wall etudiant.o: etudiant.c message.h gcc -o etudiant.o -c etudiant.c -g -Wall init.o: init.c gcc -o init.o -c init.c -g -Wall clean : rm -rf *.o