Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    décembre 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : décembre 2009
    Messages : 23
    Points : 7
    Points
    7
    Par défaut Erreur 10038 sur une socket, renvoyée par l'appel à listen()
    Bonjour,

    Quelles pourraient être les raisons qui font qu'une socket, initialisée par l'appel à socket() et dont un bind() fonctionne, ne soit plus perçue comme une socket lors de l'appel à listen() ?

    Après l'appel à listen(), puisque le retour est égal à SOCKET_ERROR, j'ai voulu en savoir plus sur l'erreur levée en appelant WSAGetLastError(). Résultat : socket error 10038 : socket operation on nonsocket.

    Voici le code source de la partie qui flanche :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
    WSADATA WSAData;
    WSAStartup(MAKEWORD(2,0), &WSAData);
     
    socketServeur = socket(AF_INET, SOCK_STREAM, 0);
    sinServeur.sin_addr.s_addr = INADDR_ANY;
    sinServeur.sin_family = AF_INET;
    sinServeur.sin_port = htons(1500);
     
    SOCKET socketClient;
    SOCKADDR_IN sinClient;
     
    if(bind(socketServeur, (SOCKADDR *)&sinServeur, sizeof(sinServeur)) == SOCKET_ERROR)
    {
    		/* Traitement de l'erreur */
    }
     
    if(listen(socketServeur, 5) == SOCKET_ERROR)
    {
    	int err = WSAGetLastError();
    	FILE * pFile = NULL;
            pFile = fopen("listen.txt", "a");
    	if(pFile != NULL) 
           {
                    fprintf(pFile, "listen erreur = %d\n", err);
    	        fclose(pFile);
           }
    }
    J'ai testé le code sur plusieurs machines différentes et pour chaque machine, j'ai tenté d'écouter sur des ports différents mais le problème persiste.

    Voyez-vous quelle peut-être la cause de cette erreur ?

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    septembre 2007
    Messages
    7 195
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : septembre 2007
    Messages : 7 195
    Points : 22 966
    Points
    22 966
    Par défaut
    Je n'ai pas l'habitude des sockets sous Windows mais, à vue de nez, je dirais que :

    − Tu ne vérifies pas si l'appel socket() lui-même a réussi ou échoué. Dans le second cas, il doit renvoyer « -1 ».
    − Il se peut que bind() échoue également en renvoyant un code autre que SOCKET_ERROR (pure hypothèse, je ne suis pas allé vérifier).

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    décembre 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : décembre 2009
    Messages : 23
    Points : 7
    Points
    7
    Par défaut
    Bonjour,

    J'ai complètement loupé la réponse et j'avais été déporté sur une autre application, j'ai donc laissé un peu de côté les sockets mais maintenant je vais pouvoir me concentrer sur le problème.

    Alors j'ai toujours ce même problème (erreur socket avec le code 10038) lors de mon appel à listen(). J'ai vérifié les retours des appels à socket() et bind() et le code retourné est à chaque fois 0. Je ne vois pas pourquoi et c'est assez agaçant.

    Pour décrire un peu mon application :

    Je travaille dans un environnement graphique et c'est en cliquant sur un bouton que le serveur se met en route. Je lance un thread qui se charge d'écouter les différentes demandes de connexions : c'est peut-être de là que vient le problème, même si je reste perplexe puisque les appels antérieurs sur la même socket m'indiquent très clairement que ce que je considère être une socket en est effectivement une.
    J'ai cherché sur le net et je n'ai pas vraiment trouvé de description d'un problème similaire et de sa solution.

    Des idées ?

    D'avance merci !

  4. #4
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : juin 2009
    Messages : 1 909
    Points : 3 158
    Points
    3 158
    Par défaut
    en fouillant un peu j'ai trouvé ça

    http://support.microsoft.com/kb/155738/fr
    bazar: http://www.improetcompagnie.com/publ...ctacles-6.html

    BÉPO la disposition de clavier francophone, ergonomique et libre: http://bepo.fr/wiki/Accueil

    Emacs Wiki: http://www.emacswiki.org/

    En attente de ce que produira: http://www.pushmid.com

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    décembre 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : décembre 2009
    Messages : 23
    Points : 7
    Points
    7
    Par défaut
    Citation Envoyé par jabbounet Voir le message
    en fouillant un peu j'ai trouvé ça

    http://support.microsoft.com/kb/155738/fr
    J'ai lu le contenu du lien mais n'ai pas pu mettre en corrélation ce qui y est indiqué avec mon application (je travaille sous Windows Server 2003 R2). J'ai testé une application de version antérieure à la version actuelle et je n'ai eu aucun problème avec la fonction listen(). La seule chose qui différencie les deux versions est le lancement d'un thread dans la version la plus récente.
    C'est dans ce thread que j'appelle successivement socket(), bind() et listen().
    Je ne vois vraiment pas quelle peut être la raison du problème.

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    septembre 2005
    Messages
    27 109
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : septembre 2005
    Messages : 27 109
    Points : 40 509
    Points
    40 509
    Par défaut
    Essaie peut-être en mettant autre chose que 0 (défaut) dans le troisième paramètre de socket(). IPPROTO_TCP, par exemple.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    décembre 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : décembre 2009
    Messages : 23
    Points : 7
    Points
    7
    Par défaut
    Bon, j'ai fait encore quelques tests et j'ai récupérer la valeur de la socket à différentes étapes du code :

    - L'appel à WSAStartup() retourne 0 : tout se passe bien.
    - L'appel à socket() se déroule bien : le programme n'entre pas dans la conditionnelle basée sur INVALID_SOCKET et ma socket prend la valeur 308.
    - Je réalise une trace de la valeur de ma socket avant l'appel à bind() : valeur toujours égale à 308.
    - L'appel à bind() semble se dérouler correctement puisque la valeur de retour n'est pas SOCKET_ERROR mais 0.
    - Juste après l'appel à bind(), une nouvelle trace de ma socket m'indique qu'elle a une valeur nulle (0).
    - L'appel à listen() retourne l'erreur socket 10038.

    J'ai l'impression qu'un appel à closesocket() est simulé entre le moment où j'appelle bind() et celui où j'appelle listen()... vraiment agaçant.

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    décembre 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : décembre 2009
    Messages : 23
    Points : 7
    Points
    7
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Essaie peut-être en mettant autre chose que 0 (défaut) dans le troisième paramètre de socket(). IPPROTO_TCP, par exemple.
    Je viens d'essayer et j'obtiens toujours la même erreur au niveau de listen() et les mêmes résultats que ceux obtenus avec la valeur 0 dans le troisième paramètre de socket().

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    décembre 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : décembre 2009
    Messages : 23
    Points : 7
    Points
    7
    Par défaut
    Je n'ai pas pu trouver la véritable source du problème mais nous avons pu mettre en évidence de notre côté une cause de lien à effet avec le thread lancé pour écouter sur le port : en n'utilisant plus ce thread, il n'y avait plus le problème. Pour conserver une écoute non bloquante de l'application il aura juste fallu sortir les appels à socket() et à bind() du thread d'écoute.

  10. #10
    Futur Membre du Club
    Profil pro
    Inscrit en
    décembre 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : décembre 2009
    Messages : 23
    Points : 7
    Points
    7
    Par défaut
    Bonjour,

    Aujourd'hui les appels à socket() et bind() fonctionnent correctement. Comme dit hier, j'ai dû faire lesdits appels en dehors de mon thread. Le listen() fonctionne dans le thread : aucune erreur n'est retournée. Le serveur est donc bien en écoute sur le port utilisé (vérifié avec la commande dos netstat) mais maintenant je suis confronté à un problème de connexion du client. Cette dernière ne peut s'effectuer et d'après le code d'erreur obtenu (10061) il semblerait que le serveur n'est pas en activité. Je pense que là aussi ça bloque à cause du thread (rappel : un thread se charge d'écouter les différentes connexions au niveau du serveur).

    Est-ce que vous avez déjà été confronté à ce problème ?
    Sauriez-vous comment résoudre le problème tout en conservant le thread d'écoute ?

    (du coup, je ne sais pas si j'écris dans le fil de discussion approprié et il vaudrait peut-être mieux lancer une nouvelle discussion j'imagine)

    Edit :
    Quelques précisions :
    • Le serveur possède un pare-feu qui est désactivé,
    • Dans mes fichiers .c j'inclus ceci :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
       
      #include "winsock2.h"
      #pragma comment(lib, "ws2_32.lib")
      ,
    • Avec netstat -an, je vois bien que l'état du port destiné à l'écoute est "En écoute".
    • Je viens de tester avec une version précédente (qui ne possède pas de thread d'écoute) et la connexion m'est également refusée par le serveur.

Discussions similaires

  1. Réponses: 2
    Dernier message: 07/06/2012, 13h28
  2. Gérer proprement une erreur EMFILE sur une socket serveur
    Par Le Mérovingien dans le forum Réseau
    Réponses: 0
    Dernier message: 16/09/2011, 18h07
  3. Erreur etrange sur une requete
    Par mael94420 dans le forum ASP
    Réponses: 3
    Dernier message: 12/03/2006, 23h25
  4. [visual c++] connaitre le debit sur une socket
    Par khayyam90 dans le forum MFC
    Réponses: 4
    Dernier message: 25/10/2005, 17h12
  5. Mettre du texte sur une vidéo(ou par dessus un tmediaplayer)
    Par souch dans le forum Composants VCL
    Réponses: 9
    Dernier message: 08/07/2004, 14h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo