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

  FORUM HardWare.fr
  Programmation
  C++

  [C] Problème réseau !

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C] Problème réseau !

n°186212
bb138
La vie est belle ...
Posté le 30-07-2002 à 15:39:02  profilanswer
 

Je me suis fait un petit client / serveur. Le client se charge de récupérer l'affichage d'une fenêtre de le transmettre au serveur qui doit ensuite l'afficher.
Lorsque j'exécute le client et le serveur sur la même machine il n'y a pas de problème mais dès qu'ils sont sur des machines différentes plus rien ne fonctionne correctement.
Le serveur (d'après ce qu'il affiche) semble recevoir les données dans le désordre... De plus il semble qu'il reçoive plus de donnée que ce qui lui est normalement envoyé...
J'utilise VC++ avec les fonction de base send() et recv().
Si vous avez une idée d'où cela pourrais provenir...
Merci d'avance !!!

mood
Publicité
Posté le 30-07-2002 à 15:39:02  profilanswer
 

n°186235
bb138
La vie est belle ...
Posté le 30-07-2002 à 15:49:12  profilanswer
 

Bigre !
J'utilise SOCK_STREAM et il me semblait que c'était du TCP/IP...
 
Je n'y comprend rien... j'ai juste renvoyé une valeur en retour et pouf ça marche...  :kaola:  
 
Quelqu'un pourrait-il m'expliquer ?

n°186245
therier
heu...coucou!
Posté le 30-07-2002 à 15:55:51  profilanswer
 

BB138 a écrit a écrit :

Je me suis fait un petit client / serveur. Le client se charge de récupérer l'affichage d'une fenêtre de le transmettre au serveur qui doit ensuite l'afficher.
Lorsque j'exécute le client et le serveur sur la même machine il n'y a pas de problème mais dès qu'ils sont sur des machines différentes plus rien ne fonctionne correctement.
Le serveur (d'après ce qu'il affiche) semble recevoir les données dans le désordre... De plus il semble qu'il reçoive plus de donnée que ce qui lui est normalement envoyé...
J'utilise VC++ avec les fonction de base send() et recv().
Si vous avez une idée d'où cela pourrais provenir...
Merci d'avance !!!




 
Tu ferais pas de l'udp par hasard...

n°186258
bb138
La vie est belle ...
Posté le 30-07-2002 à 16:10:45  profilanswer
 

Et bien il ne me semble pas, j'initialise ma chausette avec :
socket(AF_INET, SOCK_STREAM, 0)
 
et normalement SOCK_STREAM c'est pour du TCP...

n°186261
therier
heu...coucou!
Posté le 30-07-2002 à 16:19:28  profilanswer
 

BB138 a écrit a écrit :

Et bien il ne me semble pas, j'initialise ma chausette avec :
socket(AF_INET, SOCK_STREAM, 0)
 
et normalement SOCK_STREAM c'est pour du TCP...




 
Yep, effectivement...
 
C'est quoi ta commande connect derriere?

n°186291
bb138
La vie est belle ...
Posté le 30-07-2002 à 16:38:54  profilanswer
 

Voilà mon connect :
connect(*talk_socket, (struct sockaddr*)addr_server, sockaddr_len);
 
avec :
  sockaddr_len = sizeof(struct sockaddr_in);
  *talk_socket est un paramètre de fonction,
  addr_server a été rempli avec un pointeur sur une structure hostent

n°186296
bb138
La vie est belle ...
Posté le 30-07-2002 à 16:41:46  profilanswer
 

Citation :


Je n'y comprend rien... j'ai juste renvoyé une valeur en retour et pouf ça marche...  :kaola:  


En fait, ça fonctionne un certain temps puis hop ça plante... comme ça sans crier gare !  :cry:

n°186340
therier
heu...coucou!
Posté le 30-07-2002 à 17:13:49  profilanswer
 


un p'tit exemple:
 
 
m_s = socket (AF_INET, SOCK_STREAM, 0);
 
if (m_s == INVALID_SOCKET){
    return -1;
}
 
err = connect (m_s, (PSOCKADDR) &(lnkTItemconnexion->TItem.DestAdr), sizeof(lnkTItemconnexion->TItem.DestAdr));
    if (err == SOCKET_ERROR){
      return -1;
 }
 
 
 
Je sais pas si ça t'avance...
 
 
 

n°186352
bb138
La vie est belle ...
Posté le 30-07-2002 à 17:24:49  profilanswer
 

Ben j'ai a peu près la même chose ...

Code :
  1. /* Opens a socket. */
  2. if ((*talk_socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
  3. {
  4.  message(MSG_ERROR, NULL, "Cannot open socket !\n(Error %d)", WSAGetLastError());
  5.  WSACleanup();
  6.  return -1;
  7. }
  8. /* Connects the client. */
  9. if (connect(*talk_socket, (struct sockaddr*)addr_server, sockaddr_len) == SOCKET_ERROR)
  10. {
  11.  message(MSG_ERROR, NULL, "connect() failed: %d", WSAGetLastError());
  12.  WSACleanup();
  13. }

n°186379
therier
heu...coucou!
Posté le 30-07-2002 à 17:34:00  profilanswer
 

Si ça plante au bout d'un moment c peut être du à un pb d'alloc memoire inherent au traitement que tu fais...

mood
Publicité
Posté le 30-07-2002 à 17:34:00  profilanswer
 

n°186740
bb138
La vie est belle ...
Posté le 31-07-2002 à 08:45:22  profilanswer
 

Je ne crois pas car il y a les mêmes symptômes qu'avant : la fonction recv() ne semble pas être bloquante car je compte ce que j'envoie par le client et à l'arrivée j'ai plus de données !!!
 
Cela pourrait-il être un problème réseau indépendant de moi ?

n°186780
therier
heu...coucou!
Posté le 31-07-2002 à 09:44:00  profilanswer
 

BB138 a écrit a écrit :

Je ne crois pas car il y a les mêmes symptômes qu'avant : la fonction recv() ne semble pas être bloquante car je compte ce que j'envoie par le client et à l'arrivée j'ai plus de données !!!
 
Cela pourrait-il être un problème réseau indépendant de moi ?




 
Oui, tu as raison pasque si ça fonctionne en local en plus....  :??:  
 
Le recv, tu le met bloquant à combien de byte? pasque si il a pas le compte, il peut partir en timeout si celui est trop agressif....
 

n°186796
bb138
La vie est belle ...
Posté le 31-07-2002 à 09:52:40  profilanswer
 

Euh, j'ai tout laissé par défaut...

n°186829
therier
heu...coucou!
Posté le 31-07-2002 à 10:33:27  profilanswer
 

BB138 a écrit a écrit :

Euh, j'ai tout laissé par défaut...




 
C'est quoi ton recv() ?
(mets ta ligne)
 

n°186837
bb138
La vie est belle ...
Posté le 31-07-2002 à 10:40:05  profilanswer
 

Voilà mon recv() :

Code :
  1. size = (data_remain > max_len) ? max_len : data_remain;
  2. status = recv(talk_socket, buffer, size, 0);
  3. /* data_remain est initialisé par l'envoi au préalable de la taille totale des données qui vont être envoyée. */


n°186840
therier
heu...coucou!
Posté le 31-07-2002 à 10:45:00  profilanswer
 

BB138 a écrit a écrit :

Voilà mon recv() :

Code :
  1. size = (data_remain > max_len) ? max_len : data_remain;
  2. status = recv(talk_socket, buffer, size, 0);
  3. /* data_remain est initialisé par l'envoi au préalable de la taille totale des données qui vont être envoyée. */


 




 
Moi ce que je fais en général, c'est que j'envois un paquet de taille fixe specifiant la taille de ce qui suit. Je le lis avec la param de taille fixe ds le recv.  
Ensuite je n'ai qu'a mettre en param du recv la taille attendue.
 
Là, j'ai l'impression que tu lis un peu comme ça arrive sur ta socket... mais je me trompe peut être!  :D  
 
Et status, il vaut quoi quand ça deconne? t'es sous quelle OS?

n°186850
bb138
La vie est belle ...
Posté le 31-07-2002 à 10:58:12  profilanswer
 

En fait si je ne met pas la taille reçu au préalable dans la fonction recv() c'est que généralament cette taille est en dehors de capacités disponible.  :(  
Sous windows 2000, sans modifier les valeurs par défaut, la taille maxi du buffer reçu ou envoyé est de 8192 octets ce qui n'est pas suffisant pour moi ! Du coup, je fais une petite boucle pour le client et le serveur qui récupère/envoie le maximum d'octets (8192) ou moins si on arrive vers la fin des donnée que je souhaite envoyer/recevoir d'où le data_remain.  :)

n°186857
bb138
La vie est belle ...
Posté le 31-07-2002 à 11:01:18  profilanswer
 

J'oubliais, j'ai fait une petite modif pour vérifier justement que status était bien égal à size. C'est le cas pour les deux premiers tours de boucle mais ensuite ce n'est plus le cas... :(  
Pourtant, j'envoie toujours les mêmes données (deux while imbriqués...  :sweat:


Message édité par bb138 le 31-07-2002 à 11:02:12
n°186861
therier
heu...coucou!
Posté le 31-07-2002 à 11:06:46  profilanswer
 

BB138 a écrit a écrit :

J'oubliais, j'ai fait une petite modif pour vérifier justement que status était bien égal à size. C'est le cas pour les deux premiers tours de boucle mais ensuite ce n'est plus le cas... :(  
Pourtant, j'envoie toujours les mêmes données (deux while imbriqués...  :sweat:




 
C'est que c'est un code d'erreur, faut le tester voir ce qu'il te dit.
 
Les codes de retour sont:
 
 
WSANOTINITIALISED A successful WSAStartup call must occur before using this function.
 
WSAENETDOWN The network subsystem has failed.  
 
WSAEFAULT The buf parameter is not completely contained in a valid part of the user address space.  
 
WSAENOTCONN The socket is not connected.  
 
WSAEINTR The (blocking) call was canceled through SACancelBlockingCall.  
 
WSAEINPROGRESS A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.  
 
WSAENETRESET The connection has been broken due to the keep-alive activity detecting a failure while the operation was in progress.  
 
WSAENOTSOCK The descriptor is not a socket.  
 
WSAEOPNOTSUPP MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, OOB data is not supported in the communication domain associated with this socket, or the socket is unidirectional and supports only send operations.  
 
WSAESHUTDOWN The socket has been shut down; it is not possible to receive on a socket after shutdown has been invoked with how set to SD_RECEIVE or SD_BOTH.  
 
WSAEWOULDBLOCK The socket is marked as nonblocking and the receive operation would block.  
 
WSAEMSGSIZE The message was too large to fit into the specified buffer and was truncated.  
 
WSAEINVAL The socket has not been bound with bind, or an unknown flag was specified, or MSG_OOB was specified for a socket with SO_OOBINLINE enabled or (for byte stream sockets only) len was zero or negative.  
 
WSAECONNABORTED The virtual circuit was terminated due to a time-out or other failure. The application should close the socket as it is no longer usable.  
 
WSAETIMEDOUT The connection has been dropped because of a network failure or because the peer system failed to respond.
 
WSAECONNRESET The virtual circuit was reset by the remote side executing a hard or abortive close. The application should close the socket as it is no longer usable. On a UPD-datagram socket this error would indicate that a previous send operation resulted in an ICMP "Port Unreachable" message.  
 
 
Un petit switch devrait nous aider à y voir plus clair...

n°186887
bb138
La vie est belle ...
Posté le 31-07-2002 à 11:26:39  profilanswer
 

En fait, j'ai déjà relevé les codes d'erreur qui sont :
WSAEINTR  10004
WSAEACCES  10013
WSAEFAULT  10014
WSAEINVAL  10022
WSAEWOULDBLOCK  10035
WSAEINPROGRESS  10036
WSAENOTSOCK  10038
WSAEMSGSIZE  10040
WSAEOPNOTSUPP  10045
WSAENETDOWN  10050
WSAENETRESET  10052
WSAECONNABORTED  10053
WSAECONNRESET  10054
WSAENOBUFS  10055
WSAENOTCONN  10057
WSAESHUTDOWN  10058
WSAETIMEDOUT  10060
WSAEHOSTUNREACH  10065
WSANOTINITIALISED 10093
(rangé par ordre croissant des valeurs correspondantes)
 
Mais status me renvoie des valeurs variables de 5000 a 8000 généralement...
et en fait il est censé renvoyer un SOCKET_ERROR (valeur = -1), les autres erreurs sont récupérées à l'aide de WSAGetLastError()...

n°186895
therier
heu...coucou!
Posté le 31-07-2002 à 11:29:42  profilanswer
 

Bon ben faut passer par un select pour voir ce qui est dispo en taille.
 
C'est marrant pasqu'il te renvoit bien la taille...  :??:

n°186946
bb138
La vie est belle ...
Posté le 31-07-2002 à 12:03:56  profilanswer
 

C'est à dire que normalement il ne devrait pas y avoir de soucis... mais en fait ma boucle de send() tourne jusqu'à 'saturer' (c'est ce qui me semble) la file d'attente et lorsque de l'autre côté il y a un recv(), il ne prend pas les données du send() qu'il devrait (là encore c'est ce qui me semble)... :sweat:

n°187144
therier
heu...coucou!
Posté le 31-07-2002 à 14:29:29  profilanswer
 


Mmmmhh... Dans ce cas, qu'a tu commes valeurs retour du send?
Il se peut que tu ais un WSAENOBUFS comme erreur... (Tu n'as plus de buffer dispo pour envoi)
 
ex:
 
Client>J'envois X bytes (1)
Serveur>je Reçois X bytes (1)
 
Client>J'envois X bytes (2)
Serveur>je ne suis pas rebloqué sur le recv...
 
Client>J'envois X bytes (3)
Serveur>je ne suis toujours pas rebloqué sur le recv...
 
Client>J'envois X bytes -> Le buffer d'envoi est depassé!
Serveur>je me bloque sur le receive
 
Client>J'envois X bytes (4)
Serveur>Je recois (4)
 
donc coté client tu as envoyé 1,2,3 et 4
coté serveur tu as reçu 1 et 4
 
 

n°187231
bb138
La vie est belle ...
Posté le 31-07-2002 à 15:18:14  profilanswer
 

Mais normalement en TCP/IP ne devrait-il pas conserver l'ordre ?
 
Et puis il doit y avoir un autre problème, je m'explique :
Voilà ma nouvelle formule...
 
Serveur>J'envoie X bytes (1)
Client>Je reçois X bytes (1)
 
Client>J'envoie 1 byte (a)
Serveur>Je reçois 1 byte (a)
 
Serveur>J'envoie X bytes (2)
Client>Je reçois X bytes (2)
 
Client>J'envoie 1 byte (b)
Serveur>Je reçois 1 byte (b)
...
 
et normalement comme ça il n'y a pas de problème  :) ...
En fait, il y en a tout de même un car quand je lance le client et le serveur ils "dialoguent" correctement pendant un moment variable (j'ai regardé combien de fois la boucle était parcourue) puis zou une erreur la taille de status (dans status = recv (...) ) ne correspond plus... :(

n°187237
bb138
La vie est belle ...
Posté le 31-07-2002 à 15:21:23  profilanswer
 

Si ça continue je vais être obligé de faire plein de contrôle dans tous les sens... mais j'ai un peu peur que ce soit indépendant de ma volonté...

n°187244
therier
heu...coucou!
Posté le 31-07-2002 à 15:25:01  profilanswer
 


Bizarre tout de meme...
 
Recapepetons:
 
1) tu envois X bytes, puis 1 byte, ca marche
2) au bout d'un moment, tu ne recois pas X, mais Y bytes (avec Y<X)
3) apres que se passe t'il?
 
 
Est ce que X est bien toujours le même (si j'ai bien compris...)?
Si X n'est pas tjrs le même, n'essais tu pas d'envoyer plus de bytes que le nb maximal (SO_MAX_MSG_SIZE)?
 
Le pb c'est que les fct send et recv ne retournent plus le même nb au bout d'un moment, c'est ça?

n°187289
bb138
La vie est belle ...
Posté le 31-07-2002 à 15:45:42  profilanswer
 

X n'est pas toujours le même mais le plus souvent égal 8192 (valeur max par défaut que le client/serveur peut recevoir/envoyer) cette valeur est récupérée à l'aide de getsockopt()
 
Je viens de faire un petit test :
-voilà ce qui est envoyé
acqWnd->lenZ 23585 (taille totale à envoyer via la boucle suivante)
8192 8192 7201 (taille des 'morceaux' envoyés)
 
acqWnd->lenZ 23659
8192 8192 7275  
 
acqWnd->lenZ 23450
8192 8192 7066  
 
acqWnd->lenZ 22963
8192  
 
-voilà ce qui est reçu
data_length 23585 (taille totale à recevoir dans la boucle suivante)
8192 8192 7201 (taille des 'morceaux" reçus)
 
data_length 23659
8192 8192 7275  
 
data_length 23450
8192 8192 7066  
 
data_length 22963
--> et là erreur !!! la taille du 'morceau' reçu est de 2920 alors que la taille attendue est de 8192...
 
Je ne vois vraiment pas d'où cela peut venir  :sweat:


Message édité par bb138 le 31-07-2002 à 15:46:14
n°187308
therier
heu...coucou!
Posté le 31-07-2002 à 15:53:17  profilanswer
 

Il doit y avoir une erreur si le recv se debloque sans avoir reçu le total!!!  :??:  
 
T'as rien comme erreur à ce moment là?
 

n°187355
bb138
La vie est belle ...
Posté le 31-07-2002 à 16:12:13  profilanswer
 

Il ne me donne pas d'erreur... il saute le test qui est sur la ligne suivante du recv(...) (if (status == SOCKET_ERROR))...
 
Par contre, j'ai une bonne nouvelle  :) si je lui indique que la taille maximum des données à faire transiter inférieure à la taille par défaut ça marche !!!  :)  
Depuis quelques minutes ça tourne avec une valeur de 1024 au lieu de 8192...  :??:  
 
Si j'arrive à mieux je te fais signe.

n°187407
therier
heu...coucou!
Posté le 31-07-2002 à 16:48:02  profilanswer
 

BB138 a écrit a écrit :

Il ne me donne pas d'erreur... il saute le test qui est sur la ligne suivante du recv(...) (if (status == SOCKET_ERROR))...
 
Par contre, j'ai une bonne nouvelle  :) si je lui indique que la taille maximum des données à faire transiter inférieure à la taille par défaut ça marche !!!  :)  
Depuis quelques minutes ça tourne avec une valeur de 1024 au lieu de 8192...  :??:  
 
Si j'arrive à mieux je te fais signe.




 
De toutes façon, c'est pas mal de pas avoir des paquets trop gros car tu minimise le risque d'erreur.

n°187472
bb138
La vie est belle ...
Posté le 31-07-2002 à 17:27:44  profilanswer
 

Même en me déconnectant du réseau global et en ne connectant que deux machines entre elles une valeur de 8192 ou 4096 est encore trop importante et fait tout planter ou bout d'un certain temps... Par contre avec 2048 ça semble bien aller !
 
En tout cas merci beaucoup pour ton aide c'était vraiment très gentil !  :love:  
 
Je ne regrette juste d'avoir perdu autant de temps sur ce satané problème...  :fou:

n°187478
therier
heu...coucou!
Posté le 31-07-2002 à 17:31:09  profilanswer
 

BB138 a écrit a écrit :

Même en me déconnectant du réseau global et en ne connectant que deux machines entre elles une valeur de 8192 ou 4096 est encore trop importante et fait tout planter ou bout d'un certain temps... Par contre avec 2048 ça semble bien aller !
 
En tout cas merci beaucoup pour ton aide c'était vraiment très gentil !  :love:  
 
Je ne regrette juste d'avoir perdu autant de temps sur ce satané problème...  :fou:  




 
a mon avis y dois y avoir une mouise avec winsock... :fou:  
 
J'ai verifié, je montais pas au dessuis de 2Ko/envoi dans mes progs...
 :(  
 
Bonne chance!  :hello:

n°187786
bb138
La vie est belle ...
Posté le 01-08-2002 à 08:53:37  profilanswer
 

Merci et à la prochaine !

n°187846
therier
heu...coucou!
Posté le 01-08-2002 à 10:25:02  profilanswer
 

Bon, j'en refous une couche... :D  
 
Tu as quoi comme valeurs par defaut dans SO_RCVBUF et SO_SNDBUF?
(option de setsockopt)
 

n°187867
bb138
La vie est belle ...
Posté le 01-08-2002 à 10:39:41  profilanswer
 

J'ai 8192 aussi bien en réception qu'en envoi, et ce, pour le serveur et le client !

n°187870
therier
heu...coucou!
Posté le 01-08-2002 à 10:45:23  profilanswer
 

BB138 a écrit a écrit :

J'ai 8192 aussi bien en réception qu'en envoi, et ce, pour le serveur et le client !




 
zut!  :D  
 

n°187924
bb138
La vie est belle ...
Posté le 01-08-2002 à 11:41:42  profilanswer
 

Dommmmaage !!  :D

mood
Publicité
Posté le   profilanswer
 


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

  [C] Problème réseau !

 

Sujets relatifs
PHP : problème pour upload de fichierProbleme avec showDocument
problème en camLProblème css style SELECT
Problème d'identification de DLL[PHP] Probleme pour faire passer des infos par l'url.
[PHP] Probleme avec functionproblème de compilation
probleme de permission ds une applet[PHP] probleme avec la fonction mail
Plus de sujets relatifs à : [C] Problème réseau !


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