Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
3032 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  "vider" une socket

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

"vider" une socket

n°338185
polo021
Posté le 20-03-2003 à 09:02:25  profilanswer
 

bonjour,  
 
lorsque mon programme client envoie une requete au programme serveur, il arrive parfois que le send fonctionne mais pas le recv. Donc quand je reenvoie ma demande une deuxieme fois et que le recv fonctionne j'ai deux fois ma reponse dans le buffer de reception.
 
Existe t'il un moyen quelconque pour "vider" les informations contenues dans la socket avant de faire un recv? afin de ne pas avoir deux fois la reponse.
 
Merci

mood
Publicité
Posté le 20-03-2003 à 09:02:25  profilanswer
 

n°338187
antsite
Je me souviens
Posté le 20-03-2003 à 09:03:43  profilanswer
 

Il faut faire attention à vider le buffer de réception avant chaque recv. Un petit strcpy(buf, "" ); et voila !

n°338194
polo021
Posté le 20-03-2003 à 09:09:53  profilanswer
 

ANTSite a écrit :

Il faut faire attention à vider le buffer de réception avant chaque recv. Un petit strcpy(buf, "" ); et voila !


 
Est ce que tu est sur que ca suffira?
 
Parce que quand mon recv ne fonctionne pas, le serveur de son cote a quand meme envoye les donnees. Et si mon recv n'a pas fonctionne je pensais que ca voulais dire que les donnees etaient encore dans la socket et non pas dans le buffer. Est ce possible?

n°338244
polo021
Posté le 20-03-2003 à 09:59:44  profilanswer
 

polo021 a écrit :


 
Est ce que tu est sur que ca suffira?
 
Parce que quand mon recv ne fonctionne pas, le serveur de son cote a quand meme envoye les donnees. Et si mon recv n'a pas fonctionne je pensais que ca voulais dire que les donnees etaient encore dans la socket et non pas dans le buffer. Est ce possible?


 
Oui, je confirme. Je viens d'avoir un recv qui ne s'est pas effectue et malgre la remise a blanc de mon buffer de reception, j'ai quand meme recu les donnees deux fois au recv suivant!

n°338313
gatorette
Posté le 20-03-2003 à 11:19:56  profilanswer
 

J'ai eu l'occasion d'utiliser pas mal les sockets sous Windows (et un peu sous FreeBSD) et je n'ai jamais eu de problèmes de ce type.
 
Il faudrait que tu précise un peu dans quelles conditions ça se produit (OS utilisés, type de socket, lien utilisé entre le serveur et le client, fréquence d'apparition du problème...), et peut être fournir un peu de code.
 
Cependant, j'ai l'intuition que ton problème ne se situe pas au niveau des sockets mais plus de ton programme (ou de ta compréhension du fonctionnement des sockets). En effet, ton information est bien transférée du client vers le serveur (le deuxième recv le montre bien).
Si tu utilises des sockets "fiables" (par exemple TCP/IP), tu peux être sûr que l'information va atteindre sa destination (évidemment sauf si les sockets te renvoie une erreur). Tu n'as donc jamais besoin de renvoyer une information.
Si tu utilises des sockets "non-fiables" (par exemple UDP/IP), tu n'es pas sûr que l'information va atteindre sa destination. Mais ça ne doit pas causer de problèmes pour ton application. Si c'est un problème, il vaut mieux utiliser des sockets "fiables" plutôt que de réinventer la roue.


---------------
each day I don't die is cheating
n°338414
Deaddy
Posté le 20-03-2003 à 12:36:45  profilanswer
 

pour vider ce qui est en attente tu peut faire un recv (lol)
 
pourquoi et comment tu decides que le client doit renvoyer l'info au server ?
tu peux aussi établir un protocol d'echange avec accusé de rception

n°338640
polo021
Posté le 20-03-2003 à 15:58:37  profilanswer
 

Code :
  1. WSAStartup(0x0101,&wsadata);
  2. s = socket( AF_INET, SOCK_STREAM, 0 );


 
voici le code du recv

Code :
  1. if (ret=recv(s,msg2, 2048*sizeof(char), 0 )== SOCKET_ERROR )
  2.  {
  3.   AfxMessageBox((CString)"recv not ok" );
  4.   return '\0';
  5.  }
  6.  else
  7.  {
  8.   AfxMessageBox((CString)"recv ok" );
  9.   AfxMessageBox((CString)msg2);
  10.   return(msg2);
  11.  }


 
En effet, je dois avoir des problemes avec mon programme car parfois l'instruction recv ne se fait meme pas.
Mais comment se fait il que parfois le 1er recv ne fonctionne pas et que les suivants fonctionnent? Je fais pourtant appel a chaque fois a la meme fonction de mon application.  :(  
 
Et puis parfois aussi quand je fais un send d'un message (ex : 123-45678901), ca fonctionne a tous les coups (send et recv) mais quand je fais un send de 123-01987654, le send fonctionne mais pas le recv. Le format est pourtant identique. Vous n'avez jamais connu ca?
 
 
 

n°338655
VisualC++
J'va y penser ...
Posté le 20-03-2003 à 16:08:52  profilanswer
 

Et on code du send c koi ?
(l init socket et le buffer + send)

n°338765
polo021
Posté le 20-03-2003 à 17:10:46  profilanswer
 

VisualC++ a écrit :

Et on code du send c koi ?
(l init socket et le buffer + send)


pour le client

Code :
  1. if (send( s, msg, strlen(msg), 0 )== SOCKET_ERROR )
  2. {
  3.  AfxMessageBox((CString)"send not ok" );
  4.  return(false);
  5. }
  6. else
  7. {
  8.  AfxMessageBox((CString)"send ok" );
  9.  return (true);
  10. }


Code :
  1. if(connect( s, ( LPSOCKADDR ) &gw_addr, sizeof( gw_addr ) ) == SOCKET_ERROR )


les buffers, c'est a chaque fois  
        char* truc
 
si tu demandais la source du send du server, je ne l'ai pas.
 

n°338766
gatorette
Posté le 20-03-2003 à 17:10:50  profilanswer
 

Quand tu fais un recv ou un send, tu dois non seulement t'assurer qu'il n'y a pas eu d'erreurs mais aussi que tout a été envoyé (ou reçu). En effet, tu peux vouloir envoyer (ou recevoir) 32 octets et qu'en fait il y en ait eu juste 16 d'envoyé (ou de reçu).
Je ne suis pas sûr que ce soit réellement important mais rien ne dit que ça ne puisse pas arriver.


Message édité par gatorette le 20-03-2003 à 17:16:14

---------------
each day I don't die is cheating
mood
Publicité
Posté le 20-03-2003 à 17:10:50  profilanswer
 

n°338771
polo021
Posté le 20-03-2003 à 17:15:39  profilanswer
 

gatorette a écrit :

Quand tu fais un recv ou un send, tu dois non seulement t'assurer qu'il n'y a pas eu d'erreurs mais aussi que tout a été envoyé (ou reçu). En effet, tu peux vouloir d'envoyer (ou recevoir) 32 octets et qu'en fait il y en ait eu juste 16 d'envoyé (ou de reçu).


 
la taille des messages que le client recoit est variable mais jamais plus grande que 2048.
C'est vrai que je ne me suis pas assure que tout etait envoyem je v le faire. Merci

n°338778
VisualC++
J'va y penser ...
Posté le 20-03-2003 à 17:21:08  profilanswer
 

vi /agree
 
Aussi strlen() ok mais tu es sur que c que des chaines de car qui sont envoyee et bien terminee par \0 ?
 

Code :
  1. int iToSend = strlen(msg); // ou sizeof suivant si t es sur de ton buffer ou pas
  2. int iSent =send( s, msg, iToSend, 0);
  3. if ((iSent == SOCKET_ERROR ) || (iSent != iToSend)) {
  4.     AfxMessageBox(CString("send not ok" ));
  5.     return(false);
  6. }
  7. else {
  8.     AfxMessageBox(CString("send ok" ));
  9.     return (true);   
  10. }


 
Puis je te redit CString("" ) c mieu que (CString)"" ;)

n°338785
gatorette
Posté le 20-03-2003 à 17:26:13  profilanswer
 

Tu peux aller voir les exemples de code dans la faq Winsock.
 

polo021 a écrit :

Code :
  1. if (ret=recv(s,msg2, 2048*sizeof(char), 0 )== SOCKET_ERROR )
  2.  {
  3.   AfxMessageBox((CString)"recv not ok" );
  4.   return '\0';
  5.  }
  6.  else
  7.  {
  8.   AfxMessageBox((CString)"recv ok" );
  9.   AfxMessageBox((CString)msg2);
  10.   return(msg2);
  11.  }



 
Hors-Sujet : Renvoyer des pointeurs créés localement, je ne crois pas que ce soit bien. En effet, dès que tu sors de sa portée, rien ne te garanti que le pointeur ne va pas être modifié.
 

polo021 a écrit :

Et puis parfois aussi quand je fais un send d'un message (ex : 123-45678901), ca fonctionne a tous les coups (send et recv) mais quand je fais un send de 123-01987654, le send fonctionne mais pas le recv. Le format est pourtant identique. Vous n'avez jamais connu ca?


 
Non, peut être un bug provoqué par ton autre bug...


---------------
each day I don't die is cheating
n°338794
polo021
Posté le 20-03-2003 à 17:31:42  profilanswer
 

VisualC++ a écrit :


Puis je te redit CString("" ) c mieu que (CString)"" ;)


 
t'inquites pas, j'applique les conseils qui me sont donnes mais il s'agit la d'une partie plus ancienne de mon pgm et ou je n'ai pas pense a modifier mes AfxMessageBox.
 
Pour le reste je v essayer demain car j'ai un bus dans 5 minutes.
Merci a+

n°338909
mrbebert
Posté le 20-03-2003 à 19:48:53  profilanswer
 

C'est peut être tout simplement un problème de taille de données reçues et attendues.
J'explique : en TCP, il n'y a pas de notion de limite de paquet. Si tu envoie 7 octets puis 9 autres, tu as envoyé 16 octets, sans savoir comment il sont séparés. Le recv peut très bien considéré qu'il a reçu 5 octets, puis 8 autres, puis encore 3 autres.
 
De plus, lorsque le recv est bloquant, il attend des données. Tant que son buffer n'est pas plein, il peut attendre.
Dans ton cas, ton recv attends 2048 octets. Tant qu'il ne les a pas reçus, il peut attendre [:proy]

n°338918
polo021
Posté le 20-03-2003 à 20:00:41  profilanswer
 

mrBebert a écrit :

C'est peut être tout simplement un problème de taille de données reçues et attendues.
J'explique : en TCP, il n'y a pas de notion de limite de paquet. Si tu envoie 7 octets puis 9 autres, tu as envoyé 16 octets, sans savoir comment il sont séparés. Le recv peut très bien considéré qu'il a reçu 5 octets, puis 8 autres, puis encore 3 autres.
 
De plus, lorsque le recv est bloquant, il attend des données. Tant que son buffer n'est pas plein, il peut attendre.
Dans ton cas, ton recv attends 2048 octets. Tant qu'il ne les a pas reçus, il peut attendre [:proy]  


 
comment est ce qu'il faudrait que je modifier mon programme alors pour etre sur de la taille a recevoir? Puisqu'elle peut etre variable. Il y a une solution?

n°338926
mrbebert
Posté le 20-03-2003 à 20:12:25  profilanswer
 

Tu peux faire en sorte de faire précéder chaque message par sa taille en octets (dans un entier).
Ainsi, tu lis d'abord l'entier (tu connais sa taille), puis les données (tu as leur taille) :)  
 
Ou alors, tu fais en sorte que tout les messages aient la même taille (mais ca risque de consommer inutilement de la bande passante :/ )

n°338930
polo021
Posté le 20-03-2003 à 20:16:08  profilanswer
 

mrBebert a écrit :

Tu peux faire en sorte de faire précéder chaque message par sa taille en octets (dans un entier).
Ainsi, tu lis d'abord l'entier (tu connais sa taille), puis les données (tu as leur taille) :)  
 
Ou alors, tu fais en sorte que tout les messages aient la même taille (mais ca risque de consommer inutilement de la bande passante :/ )


 
oui evidement mais bon je ne peux pas modifier le pgm serveur! Donc si je parviens q trouver ses sources, j'aurai peut etre une chance de connaitre les tailles.
Sinon y a pas d'autres moyens?
Je pense qu'il y a une fonction qui dit si il reste quelque chose dans la socket, je pourrai peut etre lire les octets un par un?  :heink:  
Cela dit je ne suis vraiment pas sur que mes problemes viennent de la.

n°338931
mrbebert
Posté le 20-03-2003 à 20:17:08  profilanswer
 

Tu peux aussi utiliser une socket non bloquante. Et tu boucles sur le recv() jusqu'à ce que tu ais reçu toutes les infos dont tu as besoin.

n°338962
polo021
Posté le 20-03-2003 à 20:53:22  profilanswer
 

mrBebert a écrit :

Tu peux aussi utiliser une socket non bloquante. Et tu boucles sur le recv() jusqu'à ce que tu ais reçu toutes les infos dont tu as besoin.


 
oui c'est ce que je voulais dire quand je disai lire les infos une par une.

n°339170
Deaddy
Posté le 20-03-2003 à 22:00:54  profilanswer
 

en udp t'aurais pas de pb avec un recv(s,buff,2048)
recv retournerai le nb d'octets qu'il a recu (<=2048)
 
maintenant, fo etre sur du protocol utilisé par ton server (tcp ou udp ?) ...

n°339222
elrond
Posté le 20-03-2003 à 22:21:07  profilanswer
 

Ca peut pas être des histoires de flush de buffer? Moi j'ai des problèmes étranges quand je transfert des fichiers... Ca marche un peu près bien, mais sur des gros fichiers, le fichiers produit contient aléatoirement des suites de 0.
Existe-t-il une fonction pour flusher des sockets? J'ai essayé fflush, mais sur un socket sous linux ca m'a fait des coredumps ;-/

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  "vider" une socket

 

Sujets relatifs
[c++] transfert de fichier via un socketWSAGetLastError et fonction Connect(...) pour socket
problème taille de buffer /socketencore un probleme de socket
Socket bloquante...Comment vider l'historique ?
En parlant de thread / socket ?probleme de socket (communication client/serveur)
Serveur socket --> client socket !?SOCKET ??!!
Plus de sujets relatifs à : "vider" une socket


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR