Fiabiliser transfert par socket

masseur Messages postés 64 Date d'inscription samedi 10 janvier 2004 Statut Membre Dernière intervention 24 avril 2010 - 28 janv. 2005 à 18:53
menjra2000 Messages postés 6 Date d'inscription samedi 29 mars 2003 Statut Membre Dernière intervention 6 mars 2006 - 30 avril 2005 à 23:30
Salut.


Je vais vous expliquer mon petit problème.


Je crée un client et un serveur.


Des que le serveur recoit une demande il envoie un fichier en utilisant un thread vers le client.


Seulement quand je teste sur mon PC tout se passe bien.





Dès que je teste les deux programmes sur deux ordis différents du
réseau le client recoit le fichier mais l'image est toute décalée (elle
ressemble plus à rien).


Pourquoi un tel phénomène quand on test sur le réseau et le net?





Comment y remédier.






char buffer[512];



struct sockaddr_in sin;



int i, r;



int size = sizeof(struct sockaddr_in);



sin.sin_family = AF_INET;



sin.sin_port = htons(50);



sin.sin_addr.s_addr = inet_addr("127.0.0.1");







if(WSAStartup(0x101, &w) == 0)



{



if((sock_client = socket(AF_INET, SOCK_STREAM, 0)) != INVALID_SOCKET)



{



if(connect(sock_client, (struct sockaddr *)&sin, size) == 0)



{



//création fichier sur le disque



fichier=fopen("1.bmp","w+b");



if(fichier == NULL)



{







exit(1);



}







//recevoir taille



recv(sock_client,(char *)&taille,sizeof(taille),0);







//tant que taille>taille_buf



temp=taille;



while(temp>TAILLE_BUF)



{



//recoit partie fichier



recv(sock_client,transfert, TAILLE_BUF, 0);



//on ecrit le contenu dans le fichier



fwrite(transfert,1, TAILLE_BUF, fichier);



temp=temp-TAILLE_BUF;



}







recv(sock_client, transfert, temp, 0);



fwrite(transfert,1, TAILLE_BUF, fichier);







fclose (fichier);



closesocket (sock_client);











}



else MessageBox(0, "Erreur connexion Serveur !", NULL, MB_ICONERROR);



}



else MessageBox(0, "Erreur création Socket Client !", NULL, MB_ICONERROR);



}



else MessageBox(0, "erreur WSAStartup() !", NULL, MB_ICONERROR);



}











Ceci marche parfaitement sur mon PC mais pas sur le réseau ce qui est le principe des clients serveurs snifff.

18 réponses

yoyo269 Messages postés 1403 Date d'inscription lundi 23 février 2004 Statut Membre Dernière intervention 11 janvier 2009 2
30 janv. 2005 à 09:37
Salut masseur,

je peux te proposer une solution, celle que j'utilise, mais certainement pas la meilleure, car elle rend le débit lent voir très lent (par internet 5 Ko/s).
En fait il faut qu'à chaque fois que tu reçois, tu envoies qq chose au serveur pour lui dire que c'est bon et qu'il peut envoyer à son tour.
Dans le même temps, il faut que ton serveur attende la réponse comme quoi il peut envoyer autre chose, cela revient à envoyer attendre la réponse, envoyer, attendre la réponse et ainsi de suite.
J'espère avoir été clair.

Si t'as des questions, je suis là.

YOYO, @+.
YOYO
0
masseur Messages postés 64 Date d'inscription samedi 10 janvier 2004 Statut Membre Dernière intervention 24 avril 2010
30 janv. 2005 à 10:09
Ben les fichiers à transmettre peuvent atteindre plusieurs Mo donc cette solution ne peux etre envisageable.

Merci quand meme.
0
simtiers Messages postés 207 Date d'inscription jeudi 3 avril 2003 Statut Membre Dernière intervention 2 novembre 2006
30 janv. 2005 à 16:42
Pour un décalage, je dirais plutot que le pb vient de la lecture ou de l'ecriture du fichier...

Verifie bien tes fonctions.

Sinon, la variable transfert, c'est quoi un tableau de char ou un pointeur

( char transfert[TAILLE_BUF] ou char* transfert = (char*)malloc(TAILLE_BUF) ) ?
0
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
30 janv. 2005 à 17:22
Salut,


yoyo269: ce que tu fais (envois de message et attente d'un accusé de reception) ne sert a rien car ce systeme est déja implementé au niveau TCP.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
masseur Messages postés 64 Date d'inscription samedi 10 janvier 2004 Statut Membre Dernière intervention 24 avril 2010
30 janv. 2005 à 18:13
Transfert c'est ceci : char transfert[TAILLE_BUF];



Mais bon ce qui est bizarre c'est que le programme marche si je teste sur mon PC mais dès que c'est en réseau ca amrche plus.
0
simtiers Messages postés 207 Date d'inscription jeudi 3 avril 2003 Statut Membre Dernière intervention 2 novembre 2006
30 janv. 2005 à 18:46
T'as essayé en inversant les roles (serveur devient client et vice-versa)



Si transfert est un tableau,; alor j'écrirais plutot, &transfert au lieu de transfert...
0
yoyo269 Messages postés 1403 Date d'inscription lundi 23 février 2004 Statut Membre Dernière intervention 11 janvier 2009 2
30 janv. 2005 à 19:04
Pour Aardman : si ce que je fais est pas bon, alors tu fais parce que ça m'intéresse bcp.

YOYO, @+.
YOYO
0
masseur Messages postés 64 Date d'inscription samedi 10 janvier 2004 Statut Membre Dernière intervention 24 avril 2010
30 janv. 2005 à 19:06
J'avais deja essayé.

Le problème ne vient pas de la.

Ca commence à etre saoulant.

Ca marche sur un PC mais pas sur le réseau.

Vive microsoft.

Mon prof m'a dit qu'il avait galéré aussi car il avait le meme probleme.

Mais bon que faire?

Il m'avait parlé d'utiliser le select mais bon je vois pas en quoi ca pourrait resoudre le probleme.



Je pense plutot que les données doivent se mélanger car la taille recue est bonne.
0
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
30 janv. 2005 à 19:13
Salut,
yoyo269: ben tu n'a rien a faire, une boucle avec des send() qui coté qui emet, et une boucle avec des recv() du coté qui recoit. Il faut aussi tester la valeur de retour de send(): si elle est differente de 0 ou -1 tu peux etre sur que le client a bien recu les données que tu lui as envoyé.
Tout ca est valable pour les sockets bloquants, en utilisant TCP biensur.
0
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
30 janv. 2005 à 19:20
Salut,
masseur: Tu utilises le protocol TCP, donc tu peux etre sur que les données arriveront dans le meme ordre qu'elles ont été envoyées.
Au lieu de remetre en cause microsoft, remet en cause ton programme:
Tu utilises un buffer de type char pour envoyer un *.bmp, autrement dit un fichier binaire ? c'est pas tres logique.
Quand tu appeles recv, le nombre d'octet recu est la valeur de retour de recv(), ce n'est pas forcement TAILLE_BUF.
Enfin, je décrementerais a chaque iteration la variable taille du nombre d'octet recu, et la condition de la boucle serait: while(taille > 0).
0
masseur Messages postés 64 Date d'inscription samedi 10 janvier 2004 Statut Membre Dernière intervention 24 avril 2010
30 janv. 2005 à 19:50
C'est exact j'utilise l'envoie binaire comme ca cela me permet d'envoyer n'importe quoi.

Sinon je vais essayer ce que tu me dis.

Mais bon si je met un sleep(500) dans mon programme l'envoie marche.

Donc de nombreux probleme s'entremelent j'ai l'impression.

Merci aardman vais essayer de faire ce que tu m'as dit quand meme.
0
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
30 janv. 2005 à 19:59
Salut,
masseur: je pense que ca vient du fait que tu écris tout le temp TAILLE_BUF octets dans le fichier, alors qu'il est possible que tu en ai recu moins.
Quant a l'envois binaire: un octet n'est pas signé, donc il faut utiliser un buffer de type unsigned char.
0
masseur Messages postés 64 Date d'inscription samedi 10 janvier 2004 Statut Membre Dernière intervention 24 avril 2010
30 janv. 2005 à 20:15
Merci aardman enfin ca marche.

Et ben 3 semaines et enfin ca marche.

Merci à tous.



Pour info j'ai fait comme ceci

octetsRecus = recv(sock_client,transfert, TAILLE_BUF, 0);

if ((octetsRecus>0))

{

// fwrite(transfert,1, TAILLE_BUF, fichier);

fwrite(transfert,1, octetsRecus, fichier);

temp=temp-octetsRecus;

}



et c'est tout bon.
0
yoyo269 Messages postés 1403 Date d'inscription lundi 23 février 2004 Statut Membre Dernière intervention 11 janvier 2009 2
30 janv. 2005 à 20:25
Est-ce que l'utilisation d'un thread est obligatoire (1 pour l'envoi et 1 pour la réception) ?

YOYO, @+.
YOYO
0
masseur Messages postés 64 Date d'inscription samedi 10 janvier 2004 Statut Membre Dernière intervention 24 avril 2010
30 janv. 2005 à 20:34
Ben obligatoire je ne le pense pas mais fortement recommandé je dirais.

Attends l'avis des experts du forum.

Voila ++
0
simtiers Messages postés 207 Date d'inscription jeudi 3 avril 2003 Statut Membre Dernière intervention 2 novembre 2006
30 janv. 2005 à 20:52
Je suis pas un expert, mias je pense que c'est le mieux pour un prog de dialogue.



Pour un protocole du type FTP : a éviter, car il faut tjs attendre une réponse du serveur avant de faire quoi que ce soit.



Le fait d'utiliser les threads permet d'éviter un blocage du programme.
0
yoyo269 Messages postés 1403 Date d'inscription lundi 23 février 2004 Statut Membre Dernière intervention 11 janvier 2009 2
30 janv. 2005 à 20:55
Je suis sous Dev-C++ et je sais pas comment utiliser les threads avec.
Si l'un de vous le sait, ça serait sympa qu'il partage ses connaissances avec moi.

YOYO, @+.
YOYO
0
menjra2000 Messages postés 6 Date d'inscription samedi 29 mars 2003 Statut Membre Dernière intervention 6 mars 2006
30 avril 2005 à 23:30
salut,

esk tu peux m envoyer un projet client serveur qui intègre le téléchargement de fichier, authentification (Ex : P2P, KAZAA) , en C sous unix , le plus vite possible

merci
0
Rejoignez-nous