Problème avec un socket bloquant

Signaler
Messages postés
16
Date d'inscription
samedi 24 janvier 2004
Statut
Membre
Dernière intervention
2 septembre 2007
-
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
-
Bonjour,
Après une journée de recherches, je ne suis pas parvenu à identifier clairement mon problème, j'ai donc décider de poster.
J'utilise depuis longtemps déjà une fonction permettant d'obtenir son IP internet (vu que je passe par un routeur, l'ip locale ne suffit pas). Cette fonction m'a été donnée par yoyo.
Voici le code:

#include <winsock2.h>
char * IP_Internet()
  {
  SOCKET W_IP;
  IN_ADDR Adresse;
  SOCKADDR_IN SockAddrIn;
  HOSTENT * Hote;
  WSADATA WSAData;
  char Buffer[1024];
  static char IP[16];
  WSAStartup(0x0202, &WSAData);
  W_IP = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  Hote = gethostbyname("siteayoyo.free.fr");
  memcpy(&Adresse, Hote -> h_addr, Hote -> h_length);
  SockAddrIn.sin_family = AF_INET;
  SockAddrIn.sin_port = htons(80);
  SockAddrIn.sin_addr = Adresse;
  connect(W_IP, (SOCKADDR *)&SockAddrIn, sizeof(SockAddrIn));
  strcpy(Buffer, "GET http://siteayoyo.free.fr/ip.php HTTP/1.0\n\n"); // la requete http
  send(W_IP, Buffer, strlen(Buffer), 0);
  recv(W_IP, Buffer, sizeof(Buffer), 0);
  closesocket(W_IP);
  WSACleanup();

  strcpy(IP, Extraire_IP(Buffer));

  return IP;
  }

En fait c'est un request sur une page ou est affichée l'ip du visiteur. Ensuite je récupère la page j'extrait l'ip et je la renvoie!
Cette fonction me convenait parfaitement jusque là, le problème est que dans de très rares cas la fonction bloque le thread! Je teste systématiquement qu'une connexion est bien établie avant de m'en servir. Ce petit soucis pose un gros problème de stabilité à mon application.
Deux solutions me conviendraient:
Soit on configure le socket de manière à ce qu'il renvoie un bon gros message d'erreur,  dans ce cas il me suffirait de relancer la fonction si l'erreur est renvoyée. (elle ne peut pas planter deux fois de suite, c'est de l'ordre d'une fois sur 100 voir moin encore)
Soit on remplace carrément cette fonction, ce qui ne me dérange pas en soit mais il me faut absolument quelque chose de stable :)

Enfin ce ne sont que des suggestions, je laisse les conaisseurs répondre car ca fesait un bon moment que j'avais plus toucher à ce cher winsock2...

Merci d'avance pour vos réponces.

6 réponses

Messages postés
16
Date d'inscription
samedi 24 janvier 2004
Statut
Membre
Dernière intervention
2 septembre 2007

Up! S'il vous plait un signe de vie?
J'ai ajouter des Sleep(150); entre les fonctions bouvant bloquer le thread pour "donner un peu d'aise" et mon appli n'a plus planter depuis, mais j'imagine que le problème n'est pas entièrement réglé, je vois mal comment?
Merci d'au moins me donner quelques idées/pistes/informations à côté desquelles je suis passé.
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
2
Salut,

Je dirais tout simplement que le fait que cette fonction ne soit pas
stable est tout a fait normal etant donnée qu'aucun traitement d'erreur
n'est fait (autant au niveau tcp qu'http en plus). C'est assez
paradoxal d'exiger quelque chose de 'stable' et d'utiliser ce genre de
code, tu ne crois pas ?
Messages postés
16
Date d'inscription
samedi 24 janvier 2004
Statut
Membre
Dernière intervention
2 septembre 2007

Tout d'abort merci pour ta réponce!
Ensuite c'est tout à fait paradoxal en effet, mais c'est justement une des solutions que je cherche, le traitement d'erreurs ;-)
Cependant si la fonction bloque le thread, comment effectuer ce traitement? Quel genre d'outils ai-je à ma disposition pour détecter l'erreur? Personellement je m'attendais plus à ce que la fonction renvoie un timeout mais sans bloquer, ce qui m'aurait dispenser de tout traitement d'erreur à l'intérieur de la fonction puisque j'ai un traitement à l'extérieur.
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
2
Salut,
Il faut verifier que le retour de chaque fonction est bon ou
pas
(et dans le cas de winsock, on peut appeler WSAGetLastError pour avoir
une description plus précise lors d'une erreur). Au minimum il faudrait
tester la valeur de retour des fonctions gethostbyname (qui peut
retourner NULL, et donc provoquer un segfault), connect et send. Il
faudrait aussi tester la valeur de retour du recv, mais aussi rajouter
d'autres recv: rien ne te dis que tu va recevoir la réponse http et son
contenu d'un seul coup. Bien sur tout cela marche plus de 95% du temp
sans traitement d'erreur ni rien. Apres faut voir si on code ou si on
bricole :)
Messages postés
16
Date d'inscription
samedi 24 janvier 2004
Statut
Membre
Dernière intervention
2 septembre 2007

Merci pour ta réponce. Je ne suis pas chez moi en ce moment mais dès que je rentre, je m'occupe de ca et je te tiens au courant.
Cependant quelque chose me tracasse, si la fonction bloque le thread, c'est précisément quelle ne renvoie rien non? Quand je dis "la fonction" je parle de la fonction de winsock qui bloque effectivement.


Dans un tel cas, ne devrais-je pas lancer tout ca dans un nouveau thread et faire mon controle dans son parent?
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
2
Salut,

Si le fait que la fonction soit bloquante t'embete, oui tu peux faire ca.