salut,
dans le cadre d'un homework, je dois développer un serveur d'autorisation de voyages relatif aux trains avec une seule voix ferrés, pour cela j'utilise une socket, 3 sémaphores systemV, mémoire partagée et evidement le fork pour garantir la continuité de service offert par le serveur, le code est quasiment prêt pour le serveur il reste uniquement la partie intractions avec les clients, mais j'ai eu 8 erreurs de compilations relatifs aux sémaphores et à l'appel d'une structure de données qui constitue la section critique: mon code s'étale sur deuc fichiers: train.h et train.c
code du fichier train.h
code du fichier train.c
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148 #include <stdio.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdlib.h> #include <string.h> #include <sys/sem.h> #include <sys/ipc.h> #include <sys/shm.h> void StartServerTCP (int PortNum,int sockfd,int newsockfd,int clilen, struct sockaddr_in* serv_addr, struct sockaddr_in* cli_addr) { char buffer[256]; //struct sockaddr_in serv_addr, cli_addr; // declarer une @ de type IPv4 int n; if (PortNum ==0) { fprintf(stderr,"Erreur, Spécifiez le port"); exit(1); } sockfd = socket(AF_INET, SOCK_STREAM,0); // création de socket if(sockfd<0) error("erreur d'ouverture de socket"); bzero((char*)&serv_addr, sizeof(serv_addr));//remplir la structure par 0 : padding serv_addr->sin_family = AF_INET; // association d'une @ de type IPv4 serv_addr->sin_addr.s_addr = INADDR_ANY; serv_addr->sin_port = htons(PortNum); // association de port en format Rx // association d'une @ et un port qcq à la socket crée if(bind(sockfd,(struct sockaddr*)&serv_addr, sizeof(serv_addr))<0) error("erreur d'association au port"); // mark the socket so it will listen for incoming connexions listen(sockfd, 5); // écoute sur le port spécifié avec un max de 5 Connx possible en attente clilen= sizeof(cli_addr); // conversion de Type d'@ de client } int CreerSem(key_t cle, int NombreSem) // creation d'un sémaphore sysV { int semid; semid=semget(cle,NombreSem,IPC_CREAT|IPC_EXCL|600); if(semid==-1) {perror("SEMget");} return semid; } void InitialiserSem(int semid,int NumSem,int Val) { if(semctl(semid,NumSem,SETVAL,Val)==-1) { perror("Initialiser");exit(EXIT_FAILURE); } } void DetruireSem(int semid) { if(semctl(semid,0,IPC_RMID,0)==-1) { perror("Destroy"); exit(EXIT_FAILURE); } } void Down(int semid,int NumSem) { struct sembuf sb; sb.sem_num=NumSem; // id de sémaphore sb.sem_op=-1; // opération sb.sem_flg=SEM_UNDO ; //Bloquant ou non sinon IPC_WAIT semop(semid,&sb,1); } void Up(int semid,int NumSem) //int pour tester la valeur de retour { struct sembuf sb; sb.sem_num=NumSem; sb.sem_op=1; sb.sem_flg=SEM_UNDO ; semop(semid,&sb,1); } void Train_Tunis_Sousse_avant_voyage(Compteur * Compteur ,int mutexAB,int autorisation,int semid) { Down(semid,&mutexAB); if(Compteur->nbtrain_AB==0) { Compteur->nbtrain_AB++; Up(semid,&mutexAB); Down(semid,&autorisation); } else { Compteur->nbtrain_AB++; Up(semid,&mutexAB); } } void Train_Tunis_Sousse_apres_voyage(Compteur* Compteur,int mutexAB,int autorisation,int semid) { Down(semid,&mutexAB); Compteur->nbtrainAB--; if(Compteur->nbtrain_AB==0) { Up(semid,&mutexAB); Up(semid,&mutexAB); } else { Up(semid,&mutexAB); } } void Train_Sousse_Tunis_avant_voyage(Compteur* Compteur,int mutexBA,int autorisation,int semid) { Down(semid,&mutexBA); if(Compteur->nbtrain_BA==0) { Compteur->nbtrain_BA++; Up(semid,&mutexBA); Down(semid,autorisation); } else { Compteur->nbtrain_AB++; Up(semid,&mutexBA); } } void Train_Sousse_Tunis_apres_voyage(Compteur* Compteur,int mutexBA,int autorisation,int semid) { Down(semid,&mutexAB); Compteur->nbtrainAB--; if(Compteur->nbtrain_AB==0) { Up(semid,&mutexAB); Up(semid,&mutexAB); } else { Up(semid,&mutexAB); } }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92 #include <stdio.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdlib.h> #include "train.h" #include <string.h> #define mutexAB 1 #define mutexBA 2 #define autorisation 3 // Section critique : Ressource partagée typedef struct{int nbtrain_AB; int nbtrain_BA ;} Compteur; int main(int argc, char *argv[]) { struct sockaddr_in serv_addr,client_addr; int sockfd,newsockfd,clilen; char buffer[256]; if(argc<2) {perror("Erreur de port");exit(EXIT_FAILURE);} int shmid; // creation d'une zone memoire //------------------------------------------------------------------------- //************************************************************************* shmid=shmget(IPC_PRIVATE,sizeof(Compteur),IPC_CREAT|IPC_EXCL|0666); // création mem partagée entre père et fils if(shmid==-1) { perror("shmget"),exit(EXIT_FAILURE); } Compteur *var=(Compteur*)malloc(sizeof(Compteur)); // déclaration d'une variable de type Compteur var=(Compteur*)shmat(shmid,NULL,0); // attachement du père à la zone mémoire if(var==NULL) { perror("shmat"),exit(EXIT_FAILURE); } var->nbtrain_AB=0; // initialisation à 0 var->nbtrain_BA=0; // initialisation à 0 //--------------------------------------------------------------------------- //Création de sémaphore //*********************************************************************** int semid=CreerSem(IPC_PRIVATE,3); // creation de 3 sémaphores systemV InitialiserSem(semid,mutexAB,1); // initialisation à 1 InitialiserSem(semid,mutexBA,1); // initialisation à 1 InitialiserSem(semid,autorisation,1); // initialisation à 1 int nb=atoi(argv[1]); // casting de type int // ouverture socket StartServerTCP(nb,sockfd,newsockfd,clilen,&serv_addr,&client_addr); while(1) { // traitement de père // accepter le client avec son @ et son port : socket client newsockfd = accept(sockfd, (struct sockaddr*)&client_addr, &clilen); if (newsockfd<0) // erreur dans le socket du client error("erreur d'acceptation"); if(!fork()) { // traitement de fils var=(Compteur*)shmat(shmid,NULL,0); // attachement de fils à la memoire if(var==NULL){perror("shmat"),exit(EXIT_FAILURE);} //**************************************************************** // traitement de la demande de client //**************************************************************** bzero(buffer,256); int n = read(newsockfd, buffer, 255); // lecture depuis le socket if (n<0)error("erreur de lecture du socket"); char message[]="Train_Tunis_Sousse"; if(strcmp(message,buffer)==0) { // prendre l'autorisation pour voyager de Tunis vers Sousse Train_Tunis_Sousse_avant_voyage(&Compteur,mutexAB,autorisation,semid); // apurement de nombre de train après le voyage Train_Tunis_Sousse_apres_voyage(&Compteur,mutexAB,autorisation,semid); } else { // prendre l'autorisation pour le voyage de Sousse vers Tunis Train_Sousse_Tunis_avant_voyage(&Compteur,mutexBA,autorisation,semid); // apurement de nombre de train après le voyage Train_Sousse_Tunis_apres_voyage(&Compteur,mutexBA,autorisation,semid); } //détachement de la mémoire après la fin du traitement du fils clone if(shmdt(var)==-1){perror("Erreur détachement");exit(EXIT_FAILURE);} if(shmct(shmid,IPC_RMID,NULL)==-1) {perror("destruction");exit(EXIT_FAILURE);} // dégage lil fils ba3ed el voyage :p :p :p exit(EXIT_SUCCESS); } } return 0; }
le message d'erreur est illustré par ce screen-shot
j'ai pas compris l'erreur dans le fichier train.h !!! il s'agit d'une erreur à chaque fois que les 4 fonctions de traitement de l'autorisations sont appelés
De plus l'erreur dans le fichier train.c qui indique une erreur lors de passage par adresse de la structure compteur qui constitue une section critique !!! je soupsonne le passage par @ de la structure
Vos avis S'il vous plaît c'est très urgent !!!
Partager