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 :

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);
 
}
Je pence que le probleme vient que la fin de fichier et mauvaise mais je en suis pas sur de moi.

Merci d'avance pour votre aide