Code Client/Server et envoi plusieurs fichiers ...
QuakeCoder
Messages postés17Date d'inscriptionjeudi 23 novembre 2000StatutMembreDernière intervention10 août 2005
-
5 août 2005 à 13:54
meech
Messages postés209Date d'inscriptionvendredi 11 avril 2003StatutMembreDernière intervention14 août 2007
-
8 août 2005 à 11:25
Bonjour,
Après des efforts j'ai réalisé une petite application Client/Server qui sert à
transférer plusieurs fichiers du client vers le serveur. Ca marche impeccable,
mais pas toujours. Parfois le client ne reçoit pas le fichier complet !
Si jenlève le Sleep(2000) alors un client sur le réseau
et pas sur le même PC ne reçoit pas les memes bytes qu'il doit recevoir ... ou es le probleme dans mon code ?
----- Code Serveur -----
//variables globales
Char FICHIERS[100][50] ; // tableau des noms des
fichiers
int N ;//nombre des fichiers à transmettre en entier
Char N2[3] ; //nombre des fichiers à transmettre en
char
int TailleFichier;//taille du fichier en entier
char T[10];//taille du fichier en char
Char *buffichier; // buffer memoire, va contenir le fichier
FILE *fich; // Pointeur fichier Source
/* fonction qui lit le continue dun répertoire et remplit
un tableau nommé char FICHIERS par les noms des fichiers, et une variable N par
le nombre des fichiers. */
ReadDirectory("C:\\Dev-Cpp\\txt\");
//Envoi du nombre de fichiers ...
sprintf(N2,"%d",N);//Conversion de type
if (send(sock2,N2,sizeof(N2),0) < 0) Erreur("Erreur
Transmission du Serveur") ;
int i=0 ;
while (i < N)
{
//Envoi le nom du fichier
if (send(sock2,fichiers[i],sizeof(fichiers[i]),0) < 0)
Erreur("Erreur Transmission du Serveur !");
if ((buffichier (char *)malloc(10000)) NULL)
Erreur("Reservation Memoire Impossible !");
if ((fich fopen(fichiers[i],"rb")) NULL)
Erreur("Ouverture Fichier Impossible !");
TailleFichier = fread(buffichier,1,10000,fich); // Lecture
dans buffichier
sprintf(T,"%d",TailleFichier);//conversion du int
en char
//Envoi de la taille du fichier
if (send(sock2,T,sizeof(T),0) < 0) Erreur("3:Erreur
Transmission du Serveur !");
i++ ;//incrementation du conteur
Sleep(2000);
if (send(sock2,buffichier,TailleFichier,0) < 0)
Erreur("Erreur Transmission du Serveur !");
_fcloseall();//
Fermeture Fichier
free(buffichier);//
Libère mémoire
}
----- Code Client -----
//reception du nombre de fichiers
recv(sock,N2,sizeof(N2),0);
N = atoi(N2); //conversion du char en integer
while (i++ < N)
{
//reception du nom
du fichier
char nomfichier[50];
recv(sock, nomfichier,sizeof(nomfichier),0);
if ((fich fopen(nomfichier,"wb"))
NULL) Erreur("Ouverture Fichier Impossible !");
//reception de la taille du fichier
recv(sock,T,sizeof(T),0);
TailleFichier = atoi(T) ; //conversion du char en
integer
if ((buffichier (char *)malloc(TailleFichier)) NULL)
Erreur("Reservation Memoire Impossible !");
//reception du fichier
int receved ;
if ((receved = recv(sock,buffichier, TailleFichier,0)) <
0) Erreur("Erreur Reception du Serveur !");
if(receved !=
TailleFichier)
{
printf("%d != %d", buffichier, TailleFichier);
Erreur("Erreur Lors du transfert !");
}
fwrite(buffichier,1, TailleFichier,fich);// Ecriture dans FICHIER
free(buffichier);//
Libère mémoire
_fcloseall();//
Fermeture Fichier
}
closesocket(sock);// Fermeture Socket
WSACleanup();//
LIBERATION DLL WINSOCK
A voir également:
Code Client/Server et envoi plusieurs fichiers ...
meech
Messages postés209Date d'inscriptionvendredi 11 avril 2003StatutMembreDernière intervention14 août 2007 5 août 2005 à 15:34
Salut,
Je pense que ça mer[...]ouille à cause de la ligne où tu lis le fichier avec la fonction fread :
TailleFichier = fread(buffichier,1,10000,fich);
Le troisième paramètre de fread spécifie le nombre de blocs à lire dans le fichier. Donc, si la taille du fichier est supérieure à environ 10 000 octets (environ 10 kilo-octets, ce qui est peu), tu ne lis que les 10 premiers kilo-octets et tu abandonnes le reste...
En tout cas, ta variable TailleFichier ne retourne la "bonne" taille du fichier seulement si celle-ci est inférieure ou égale à 10 000 blocs (la fonction fread retournant, sauf en cas d'erreur, le nombre de blocs de données réellement lus).
Ensuite, tu adresses au client le bloc de 10 ko au maximum, ce qui explique que le client ne reçoives pas toujours complètement le contenu du fichier.
La solution consiste à réaliser une boucle où :
1. tu stockes dans un buffer la partie du fichier à lire avec fread ;
2. tu envoies la partie lue au client avec send.
Exemple (en s'adaptant vite fait à ton code)
#define BUFFER_SIZE 1024
// (...)
int length;
while((length = fread(buffichier,1,BUFFER_SIZE,fich)) != 0)
{
if (send(sock2,buffichier,length,0) < 0)
Erreur("Erreur Transmission du Serveur !");
}
QuakeCoder
Messages postés17Date d'inscriptionjeudi 23 novembre 2000StatutMembreDernière intervention10 août 2005 5 août 2005 à 16:40
merci pour ta reponse.
bon.le probleme ne viens pas du fread, car noremalent j'ai mis dans le
code (#define FICH_MAX_SIZE 9000000 // Taille Maximum
de Fichier (octets)) 9 mega.
Et tous mes fichiers < 9megas. en plus le programe marche nickel si
je le lance dans le meme poste avec le serveur. j'ai le probleme juste
avec les clients distants !
meech
Messages postés209Date d'inscriptionvendredi 11 avril 2003StatutMembreDernière intervention14 août 2007 5 août 2005 à 16:51
Sans vouloir te vexer, tu peux
augmenter la taille de ton buffer à 600 millions si tu veux, ce n'est
pas ce qu'il y a de mieux au niveau du code... je te conseille la
boucle avec un buffer plus petit : tu envoies ainsi de petites bribes
de fichier sans saturer ni le client, ni le serveur... Bref, fais comme
tu veux mais, un moment où un autre, tu seras embêter par cela.
Côté client, c'est le même genre de problème :
En fait, rien ne te force à bricoler des histoires de récupération de
taille de fichier : la fonction recv() n'a pas besoin de cela pour
repérer quand elle ne trouve plus aucune donnée en provenance du
serveur. Même solution une boucle : ici, tant que le client reçois
quelque chose c'est à dire tant que :
Fais comme tu veux, mais tu ne trouveras aucun exemple (ou ils ne
seront pas terribles) où le transfert se fait d'un seul bloc. Ce qui
est certain, c'est que des serveurs HTTP (comme Apache ou Microsoft
IIS) n'adresse pas la réponse en un seul morceau... c'est également le
cas des serveurs FTP ou de tout ce qui fonctionne en mode connecté (ie.
socket).
QuakeCoder
Messages postés17Date d'inscriptionjeudi 23 novembre 2000StatutMembreDernière intervention10 août 2005 8 août 2005 à 11:07
Bonjour. voila j'ai fais pour le transfert des fichiers ce que vous
m'avez dis.Maintenant c'est bon ... mais ya encore un probleme, parfois
et pas toujours, quand le serveur envoi le nom du fichier à transferer
le client se bug et il recoit une parti du nom et recoit l 'autre parti
quand il recoit la taille du fichier.( voir le code ).
voila.j c pas ou le probleme. dois je faire une boucle aussi pour le transfert du nom du fichier et sa taille ??