Bonjours à tous,
J'essaye de faire un petit client/serveur pour échanger des fichiers sur mon réseau local (pour comprendre le principe).Le client se connecte au serveur et le serveur lui envoi un fichier.
Le problème est que le fichier reçu par le client n'est pas bon , il n'est pas identique au fichier envoyé par le serveur et je ne comprend pas trop pourquoi...![]()
Voici le code du serveur
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235 #include <iostream> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <sys/un.h> #include <string.h> #include <stdio.h> using namespace std; #define TAILLE_BUF 1000 int main() { /*** Declaration des fonction ***/ void Traitement(int connfd); /*** Declaration des variables ***/ int port; int listenfd; int connfd; struct sockaddr_in servaddr; /*** Code ***/ cout << "Entrer le port du serveur : "; cin >> port; if ( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { perror("socket error"); exit(1); } bzero(&servaddr, sizeof(servaddr));//on met toute la structure a 0 //on remplit la structure avec l'ip du serveur et le num de son port servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY);//INADDR_ANY signifie que le serveur va accepter une connection client sur n'importe-quelle interface servaddr.sin_port = htons(port); //on lie le port du serveur au socket en remplissant la "internet socket //adresse structure" et en appellant bind if (bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) { perror("bind error"); exit(1); } //avec listen, le socket est converti en listening socket (ecoute) //sur lequel les demandes de connections vont etre acceptees par le Kernel if (listen(listenfd, 1) < 0) { perror("listen error"); exit(1); } //accept retourne un "descripteur de connection" (connected descriptor) qui est //utilise pour la communication avec le nouveau client. Un nouveau pour chaque client if ((connfd = accept(listenfd, (struct sockaddr *) NULL, NULL)) < 0) { perror("accept error"); exit(1); } Traitement(connfd); close(connfd); return 0; } void Traitement (int connfd) { /*** Declaration des variables ***/ char indirection[100]; char nom_fichier[50]; char ok[3]; char transfert[TAILLE_BUF+1]; FILE* fichier; int taille,temp=0,i,j,lg,lg_nom,lg_chaine,erreur; /*** Code ***/ erreur=read(connfd,(char*)ok,sizeof(ok)); if (erreur < 0) { perror("Erreur read"); exit(1); } if (strcmp(ok,"ok")!=0) { cout << endl << "ERREUR" << endl; exit(1); } cout << endl << "Client ok !" << endl; //demande indirection fichier à envoyer cout<<endl<<endl<<"Entrer l'indirection complette du fichier a envoyer (ex : /media/hda2/metro.pdf)" << endl << "il ne doit pas y avoir d'espace dans le l'indirection : "; cin>>indirection; //on ouvre le fichier et on test si il existe fichier=fopen(indirection,"r+b"); if(fichier == NULL) { perror("Erreur d'ouverture du fichier"); exit(1); } //On recupere le nom du fichier dans l'indirection lg_chaine=strlen(indirection); i=lg_chaine -1; lg_nom=0; while((indirection[i])!='/') { lg_nom++; i--; } j=0; for (i=(lg_chaine - lg_nom); i<= lg_chaine; i++) { nom_fichier[j]=indirection[i]; j++; } //on envoi le nom du fichier cout << endl << "Envoie du nom du fichier" << endl; erreur = write(connfd,(char*)&nom_fichier,sizeof(nom_fichier)); if (erreur < 0) { perror("Erreur write"); exit(1); } fseek( fichier, 0, SEEK_END ); //on se place a la fin du fichier taille=ftell(fichier); //on récupere la position donc la taille fseek( fichier, 0, SEEK_SET ); //on se replace au début du fichier cout << endl << "taille du fichier: "<<taille<<" octets"<<endl; cout << endl << "Envoie de la taille du fichier: "<<endl; //on envoi la taille du fichier erreur = write(connfd,(char*)&taille,sizeof(taille)); if (erreur < 0) { perror("Erreur write"); exit(1); } temp = taille; cout << endl << "Transfert en cours ..." << endl; while (temp > TAILLE_BUF) { lg = fread(transfert,1, TAILLE_BUF, fichier); //transfert[lg]=0; if (lg <= 0) { perror("Erreur fread"); exit(1); } erreur = write(connfd,transfert,lg); if (erreur < 0) { perror("Erreur write"); exit(1); } temp = temp - TAILLE_BUF; } lg=fread(transfert,1, TAILLE_BUF, fichier); //transfert[lg]=0; if (lg <= 0) { perror("Erreur fread"); exit(1); } erreur = write(connfd,transfert,lg); if (erreur < 0) { perror("Erreur write final"); exit(1); } fclose (fichier); cout << endl << "FICHIER TRANSMIS !!!" << endl; }
et voici le code du client :
Je pence que le probleme vient que la fin de fichier et mauvaise mais je en suis pas sur de moi.
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230 #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <sys/un.h> #include <stdio.h> #include <arpa/inet.h> #include <iostream> using namespace std; #define TAILLE_BUF 1000 int main () { /*** Declaration des fonction ***/ void Traitement(int sockfd); /*** Declaration des variables ***/ int sockfd, n; int port; struct sockaddr_in servaddr; char ad_serveur[255]; /*** Code ***/ //saisie de la configuration cout<< "Entrer l'adresse IP du serveur : "; cin >> ad_serveur; cout << endl << "Entrer le port du serveur : "; cin >> port; if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { //la fonction socket cree un socket de flux (SOCK_STREAM)internet(AF_INET) //(incomprehensible en francais)(plus simplement : Internet stream socket). //Renvoit un int pour identifier le socket plus tard (cf. read & connect) perror("socket error"); exit(1); } bzero(&servaddr, sizeof(servaddr)); //on met toute la structure a 0 //on remplit la structure avec l'ip du serveur et le num de son port servaddr.sin_family = AF_INET; servaddr.sin_port = htons(port); //htons: pour convertir le numero de port if (inet_pton(AF_INET, ad_serveur, &servaddr.sin_addr) <= 0) { //inet_pton: convertit l'argument ASCII (Ex: 127.0.0.1) dans le bon format perror("inet_pton error"); exit(1); } if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) { //connect etablit la connection TCP avec le serveur specifie par la structure de //l'adresse du socket pointe par le second argument perror("connect error"); exit(1); } Traitement(sockfd); return 0; } void Traitement(int sockfd) { /*** Declaration des variables ***/ int taille,temp,lg,erreur; char nom_fichier[50]; char transfert[TAILLE_BUF+1]; char indirection[100]; char ok[]={'o','k','\0'}; FILE* fichier; /*** Code ***/ cout << endl << "Connecter au serveur!" << endl; cout << endl << endl << "Entrer l'indirection ou vous voulez enregistrer le fichier (ex : '/media/hda2/') : "; cin >> indirection; erreur = write(sockfd,ok,sizeof(ok)); if (erreur < 0) { perror("Erreur write"); exit(1); } cout << endl << "Reception du nom de fichier..." << endl; erreur = read(sockfd,(char*)&nom_fichier,sizeof(nom_fichier)); if (erreur < 0) { perror("Erreur read"); exit(1); } cout << endl << "Nom du fichier : " << nom_fichier << endl; cout << endl << "Reception de la taille du fichier..." << endl; erreur = read (sockfd,(char*)&taille,sizeof(taille)); if (erreur < 0) { perror("Erreur read"); exit(1); } cout << endl << "Taille du fichier : " << taille << " octets" << endl; strcat(indirection,nom_fichier); fichier=fopen(indirection,"w+b"); if(fichier == NULL) { perror("Erreur d'ouverture fichier"); exit(1); } temp=taille; cout << endl << "Reception en cours..." << endl; while(temp>TAILLE_BUF) //si la taille du fichier est supérieure à la taille du buffer { lg = read(sockfd, transfert, TAILLE_BUF); //transfert[lg]=0; if (lg < 0) { perror("Erreur read"); exit(1); } fwrite(transfert,1,lg,fichier); temp=temp-TAILLE_BUF; } lg = read(sockfd, transfert, TAILLE_BUF); transfert[lg]=0; if (lg < 0) { perror("Erreur read"); exit(1); } fwrite(transfert,1,lg,fichier); cout << endl << "Reception terminee" << endl; cout << endl << "Fichier enregistre : " << indirection << endl; fclose(fichier); }
Merci d'avance pour votre aide
Partager