IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
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

C++ Discussion :

Fonction WSARecvFrom fail..


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2009
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

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

    Informations forums :
    Inscription : Mars 2009
    Messages : 20
    Par défaut Fonction WSARecvFrom fail..
    Bonjour,

    Je développe un serveur UDP en utilisant les fonctions WSA* de la lib winsock.

    Après avoir créer la socket (WSASocket) et la binder comme il faut, je suis face à un problème concernant la fonction WSARecvFrom, voici son implémentation :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    WSARecvFrom(
                        sock_,
                        &dataBuff,
                        1,
                        &bytesRecv,
                        &flags,
                        (SOCKADDR *)&senderAddr,
                        &senderAddrSize,
                        &overLapped,
                        NULL
                       );
    Le problème vient de la valeur de retour, j'obtiens constamment le code erreur WSAENOBUFS (10055) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    No buffer space available.
    An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full.
    Or, je pense avoir bien déclaré le buffer de réception (dataBuff) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    WSABUF dataBuff;
    const int buffLen = DATA_SIZE;
    char buff[DATA_SIZE];
     
    dataBuff.len = buffLen;
    dataBuff.buf = buff;
    J'ai lu quelque part que cette erreur apparaissait si le port bindé dépassé la valeur 5000 mais j'utilise le port 1234 et même résultat...

    Merci pour votre patience et de l'aide que vous pourrez m'apporter.

  2. #2
    Membre chevronné Avatar de niglo
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    379
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 379
    Par défaut
    Hello,

    ce que je comprends de ton message d'erreur, c'est que ton buffer n'est pas assez grand pour recevoir les données.

    Que vaut DATA_SIZE ?

    ++

  3. #3
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2009
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

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

    Informations forums :
    Inscription : Mars 2009
    Messages : 20
    Par défaut
    DATA_SIZE est une macro perso, elle vaut 1024, mais la fonction plante avant même une quelconque réception de données...

  4. #4
    Membre chevronné Avatar de niglo
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    379
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 379
    Par défaut
    d'après la MSDN, le problème vient du numéro de port de ton socket :
    http://support.microsoft.com/kb/196271/fr

    Comment sont déclarés senderAddr et sock_ ?

  5. #5
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Une petite info au passage : la bibliothèque winsock n'est pas portable (c'est une bibliothèque "made by microsoft" )

    Tu me diras sans doute que tu n'en as rien à foutre, mais il se fait qu'il existe une excellente bibliothèque qui permet de gérer les socket (TCP et UDP) de manière transparente et portable pour l'utilisateur, et ce, quel que soit le système pour lequel l'application sera compilée.

    Ce n'est pas le moindre intérêt de cette bibliothèque, car elle rend la gestion et l'utilisation des sockets, ports et autres protocoles liés à la transmission des données par le net bien plus faciles . j'ai nommé boost asio !

    Alors, oui, je sais... Tu vas me rétorquer que l'utilisation de cette bibliothèque te fait penser au fait d'utiliser un bazooka pour tuer une mouche, que tu n'as pas envie d'installer tout boost "uniquement" pour cela, ou encore me trouver plein d'autres faux prétextes pour ne pas suivre ce conseil.

    Et pourtant, je peux t'assurer que tu gagnera énormément tant en terme de facilité d'utilisation, qu'en terme de temps de développement ou qu'en terme de portabilité, et qu'il serait donc vraiment dommage de s'en priver
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2009
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

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

    Informations forums :
    Inscription : Mars 2009
    Messages : 20
    Par défaut
    Citation Envoyé par niglo Voir le message
    d'après la MSDN, le problème vient du numéro de port de ton socket :
    http://support.microsoft.com/kb/196271/fr

    Comment sont déclarés senderAddr et sock_ ?
    Je ne pense pas que cela vienne du numéro de port (j'ai testé avec beaucoup de valeurs différentes),
    sinon pour les déclarations :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    struct sockaddr_in senderAddr;
    SOCKET sock_;
    pour répondre a koala1 :
    on m'impose l'utilisation des fonctions WSA* ! je n'ai pas le choix

    La question de portabilité n'est pas un problème, le tout est abstrait et encapsulé. Je jongle entre deux objets version WIN32 et UNIX (avec les macros #ifdef #endif); du coup mon serveur est utilisable sous Windows et Unix.
    Au passage, ma version UNIX fonctionne parfaitement...

  7. #7
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par ouhare Voir le message
    pour répondre a koala1 :
    on m'impose l'utilisation des fonctions WSA* ! je n'ai pas le choix

    La question de portabilité n'est pas un problème, le tout est abstrait et encapsulé. Je jongle entre deux objets version WIN32 et UNIX (avec les macros #ifdef #endif); du coup mon serveur est utilisable sous Windows et Unix.
    Au passage, ma version UNIX fonctionne parfaitement...
    Mea culpa... j'ai oublié de préciser : c'est exactement ce que fait boost asio, en t'évitant de devoir réinventer la roue

    Maintenant, si c'est pour un TP... Mais penses à asio le jour où tu seras dans une situation similaire à titre privé (ou professionnel)
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  8. #8
    Membre chevronné Avatar de niglo
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    379
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 379
    Par défaut
    Peux-tu également montrer comment tu renseignes sock_ et senderAddr ?

    Sinon, plusieurs choses à vérifier :

    Winsock correctement initialisé ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        rc = WSAStartup(MAKEWORD(2, 2), &wsaData);
        if (rc != 0) {
            /* Could not find a usable Winsock DLL */
            wprintf(L"WSAStartup failed with error: %ld\n", rc);
            return 1;
        }
    socket bien crée ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        RecvSocket = WSASocket(AF_INET,
                               SOCK_DGRAM,
                               IPPROTO_UDP, NULL, 0, WSA_FLAG_OVERLAPPED);
     
        if (RecvSocket == INVALID_SOCKET) {
            /* Could not open a socket */
            wprintf(L"WSASocket failed with error: %ld\n", WSAGetLastError());
            WSACloseEvent(Overlapped.hEvent);
            WSACleanup();
            return 1;
        }
    socket bien lié ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
        rc = bind(RecvSocket, (SOCKADDR *) & RecvAddr, sizeof (RecvAddr));
        if (rc != 0) {
            /* Bind to the socket failed */
            wprintf(L"bind failed with error: %ld\n", WSAGetLastError());
            WSACloseEvent(Overlapped.hEvent);
            closesocket(RecvSocket);
            WSACleanup();
            return 1;
        }

  9. #9
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par défaut
    [hors-sujet]

    Citation Envoyé par ouhare Voir le message
    Je jongle entre deux objets version WIN32 et UNIX (avec les macros #ifdef #endif);
    Miam miam la portabilité à coup de pré processeur. Je crois que je vais écrire un petit article sur le sujet pour en finir avec ces mauvaises habitudes ^^

    [/hors-sujet]

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 01/09/2009, 07h38
  2. Réponses: 0
    Dernier message: 27/07/2009, 23h21
  3. Réponses: 7
    Dernier message: 26/02/2008, 14h08
  4. CDataExchange ; fonction fail
    Par Seth77 dans le forum MFC
    Réponses: 4
    Dernier message: 08/07/2007, 14h26
  5. Fonction 'failed' avec comme paramètre un HResult
    Par Leobaillard dans le forum Delphi
    Réponses: 1
    Dernier message: 08/08/2006, 20h29

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