Fiabiliser transfert par socket

Signaler
Messages postés
64
Date d'inscription
samedi 10 janvier 2004
Statut
Membre
Dernière intervention
24 avril 2010
-
Messages postés
6
Date d'inscription
samedi 29 mars 2003
Statut
Membre
Dernière intervention
6 mars 2006
-
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

Messages postés
1403
Date d'inscription
lundi 23 février 2004
Statut
Membre
Dernière intervention
11 janvier 2009
3
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
Messages postés
64
Date d'inscription
samedi 10 janvier 2004
Statut
Membre
Dernière intervention
24 avril 2010

Ben les fichiers à transmettre peuvent atteindre plusieurs Mo donc cette solution ne peux etre envisageable.

Merci quand meme.
Messages postés
207
Date d'inscription
jeudi 3 avril 2003
Statut
Membre
Dernière intervention
2 novembre 2006

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) ) ?
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
3
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.
Messages postés
64
Date d'inscription
samedi 10 janvier 2004
Statut
Membre
Dernière intervention
24 avril 2010

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.
Messages postés
207
Date d'inscription
jeudi 3 avril 2003
Statut
Membre
Dernière intervention
2 novembre 2006

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...
Messages postés
1403
Date d'inscription
lundi 23 février 2004
Statut
Membre
Dernière intervention
11 janvier 2009
3
Pour Aardman : si ce que je fais est pas bon, alors tu fais parce que ça m'intéresse bcp.

YOYO, @+.
YOYO
Messages postés
64
Date d'inscription
samedi 10 janvier 2004
Statut
Membre
Dernière intervention
24 avril 2010

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.
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
3
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.
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
3
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).
Messages postés
64
Date d'inscription
samedi 10 janvier 2004
Statut
Membre
Dernière intervention
24 avril 2010

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.
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
3
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.
Messages postés
64
Date d'inscription
samedi 10 janvier 2004
Statut
Membre
Dernière intervention
24 avril 2010

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.
Messages postés
1403
Date d'inscription
lundi 23 février 2004
Statut
Membre
Dernière intervention
11 janvier 2009
3
Est-ce que l'utilisation d'un thread est obligatoire (1 pour l'envoi et 1 pour la réception) ?

YOYO, @+.
YOYO
Messages postés
64
Date d'inscription
samedi 10 janvier 2004
Statut
Membre
Dernière intervention
24 avril 2010

Ben obligatoire je ne le pense pas mais fortement recommandé je dirais.

Attends l'avis des experts du forum.

Voila ++
Messages postés
207
Date d'inscription
jeudi 3 avril 2003
Statut
Membre
Dernière intervention
2 novembre 2006

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.
Messages postés
1403
Date d'inscription
lundi 23 février 2004
Statut
Membre
Dernière intervention
11 janvier 2009
3
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
Messages postés
6
Date d'inscription
samedi 29 mars 2003
Statut
Membre
Dernière intervention
6 mars 2006

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