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

Discussion :

Problème de réception de données via QTcpSocket

  1. #1
    Membre du Club
    Homme Profil pro
    Inscrit en
    Février 2007
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 102
    Points : 66
    Points
    66
    Par défaut Problème de réception de données via QTcpSocket
    Salut à tous,
    J'ai une classe client et une classe serveur qui s'échangent des données de types QString, du coté du serveur, aucun probleme au niveau de la reception car j'arrive à voir les données emises par le client. Par contre du coté de celui la j'ai un souci:
    ce test est bon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    if (socket->bytesAvailable() < (int)sizeof(quint16))
            {//ça rentre pas ici donc on est dans les normes
                std::cout<<erreur1.toStdString()<<":"<<std::endl;
                return;
            }
            //la taille du message recu est bonne
            //on la stocke dans une variable
            in >> tailleMsg;
    Mais pas celui ci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    if (socket->bytesAvailable() < tailleMsg)
        {
            std::cout<<erreur2.toStdString()<<":"<<std::endl;
            return;
        }
    Sur la console s'affiche le message erreur2 donc socket->bytesAvailable() est bien inférieure à tailleMsg.
    À quoi tient ce probleme et pourquoi j'ai pas ce probleme au niveau de la classe serveur?
    Merci d'avance

  2. #2
    Rédacteur
    Avatar de Amnell
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2009
    Messages
    1 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 840
    Points : 5 545
    Points
    5 545
    Par défaut
    Bonjour,

    Dit comme ça, c'est comme si je demandais "pourquoi j'ai un arbre devant ma fenêtre", non pas parce que c'est évident, mais parce que c'est quelque chose qui a été établi, et dont la raison n'est pas déterminable avec les informations données.

    Toutefois, j'aurais tendance à dire que dans le deuxième cas, tailleMsg = 0, ce qui fait que forcément, on entre dans la fonction. Dans ce cas, il serait bon de tester la valeur de tailleMsg.

    Bonne continuation,
    Amnell.
    N'oubliez pas de consulter la FAQ Qt ainsi que les cours et tutoriels C++/Qt !

    Dernier article : Débuter avec les Enlightenment Foundation Libraries (EFL)
    Dernières traductions : Introduction à Qt Quick - Applications modernes avec Qt et QML
    Vous cherchez un livre sur Qt 5, Qt Quick et QML ? Créer des applications avec Qt 5 - Les essentiels

  3. #3
    Membre du Club
    Homme Profil pro
    Inscrit en
    Février 2007
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 102
    Points : 66
    Points
    66
    Par défaut
    Citation Envoyé par Amnell Voir le message
    Bonjour,

    Dit comme ça, c'est comme si je demandais "pourquoi j'ai un arbre devant ma fenêtre", non pas parce que c'est évident, mais parce que c'est quelque chose qui a été établi, et dont la raison n'est pas déterminable avec les informations données.

    Toutefois, j'aurais tendance à dire que dans le deuxième cas, tailleMsg = 0, ce qui fait que forcément, on entre dans la fonction. Dans ce cas, il serait bon de tester la valeur de tailleMsg.

    Bonne continuation,
    Amnell.
    Merci Amnell pour ta réponse.
    J'ai affiché le contenu de la tailleMsg ainsi que celui de socket->bytesAvailable(), les deux sont égaux à 6 durant l'exécution. Ce qui est vraiment étrange!
    Demo : Le slot chargé de traité les données recues:
    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    void maClasse::receptionDonnées//SLOT
    {
        QString erreur1="erreur1";
        QString erreur2="erreur2";
        std::cout<<testtest.toStdString()<<":"<<std::endl;
        QDataStream in(socket);
        if (tailleMessage == 0)
        {
            if (socket->bytesAvailable() < (int)sizeof(quint16))
            {
                std::cout<<erreur1.toStdString()<<":"<<std::endl;
                return;
            }
            in >> tailleMsg;
            QString t1=QString::number(tailleMessage);
            QString t2=QString::number(socket->bytesAvailable());
            std::cout<<t1.toStdString()<<":"<<std::endl;
            std::cout<<t2.toStdString()<<":"<<std::endl;
        }
    //****JE METS CETTE PARTIE "probleme" EN COMMENTAIRE
        //if (socket->bytesAvailable() < tailleMsg)
        //{
          //  std::cout<<erreur2.toStdString()<<":"<<std::endl;
            //return;
        //}
        // Si on arrive jusqu'à cette ligne, on peut récupérer le message entier
        QString str;
     
        in >> str;
     str+="*";
    str="*"+str;
        std::cout<<str.toStdString()<<":"<<std::endl;
     
     
    //    
        tailleMsg = 0;
    }
    Affichage console:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    6
    6
    *0*
    6
    6
    *0*
    6
    6
    *3*
    6
    6
    *8*
    Et si je "décommente" la pratie que j'ai appelée probleme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    erreur2:
    erreur2:
    erreur2:
    erreur2:
    Vraiment je comprends pas

  4. #4
    Rédacteur
    Avatar de Amnell
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2009
    Messages
    1 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 840
    Points : 5 545
    Points
    5 545
    Par défaut
    Citation Envoyé par bilou_2007 Voir le message
    J'ai affiché le contenu de la tailleMsg ainsi que celui de socket->bytesAvailable(), les deux sont égaux à 6 durant l'exécution. Ce qui est vraiment étrange!
    Vous faites :

    D'où la modification nécessaire de :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (socket->bytesAvailable() < tailleMsg)
    En :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (socket->bytesAvailable() <= tailleMsg)
    Bonne continuation,
    Amnell.
    N'oubliez pas de consulter la FAQ Qt ainsi que les cours et tutoriels C++/Qt !

    Dernier article : Débuter avec les Enlightenment Foundation Libraries (EFL)
    Dernières traductions : Introduction à Qt Quick - Applications modernes avec Qt et QML
    Vous cherchez un livre sur Qt 5, Qt Quick et QML ? Créer des applications avec Qt 5 - Les essentiels

  5. #5
    Membre du Club
    Homme Profil pro
    Inscrit en
    Février 2007
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 102
    Points : 66
    Points
    66
    Par défaut
    Citation Envoyé par Amnell Voir le message
    Vous faites :

    D'où la modification nécessaire de :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (socket->bytesAvailable() < tailleMsg)
    En :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (socket->bytesAvailable() <= tailleMsg)
    Bonne continuation,
    Amnell.
    Moi je ne veux pas qu'il rentre dans la condition,or le programme rentre quand meme bien que la condition ne soit pas satisfaite. De toutes facons j'ai modifié mon if et ça na pas donné le résultat souhaité:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (socket->bytesAvailable() <= tailleMsg)
    ça a donné ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    erreur2:
    erreur2:
    erreur2:
    erreur2:
    Merci pour votre patience
    PS: j'ai oublié peut etre de dire que tailleMsg est quint16

  6. #6
    Rédacteur
    Avatar de Amnell
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2009
    Messages
    1 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 840
    Points : 5 545
    Points
    5 545
    Par défaut
    Votre code, remaké en un peu plus joli :

    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
    void /* Votre slot de réception de données */
    {
        QDataStream in(socket);
     
        if (tailleMessage == 0)
        {
            if (socket->bytesAvailable() < (int)sizeof(quint16))
            {
                qDebug() << "Error: socket->bytesAvailable() < (int)sizeof(quint16)"
                return;
            }
            in >> tailleMessage;
        }
     
        if (socket->bytesAvailable() < tailleMessage)
        {
            qDebug() << "Error: socket->bytesAvailable() < tailleMessage";
            return;
        }
     
        QString message;
        in >> message;
     
        tailleMessage = 0;
    }
    Il faut savoir que la réception ne se fait pas d'un coup, d'où le fait qu'il y ait de tels tests dans le code. Mais à un moment ou à un autre, vous devez franchir les deux conditions.
    N'oubliez pas de consulter la FAQ Qt ainsi que les cours et tutoriels C++/Qt !

    Dernier article : Débuter avec les Enlightenment Foundation Libraries (EFL)
    Dernières traductions : Introduction à Qt Quick - Applications modernes avec Qt et QML
    Vous cherchez un livre sur Qt 5, Qt Quick et QML ? Créer des applications avec Qt 5 - Les essentiels

  7. #7
    Membre du Club
    Homme Profil pro
    Inscrit en
    Février 2007
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 102
    Points : 66
    Points
    66
    Par défaut
    Citation Envoyé par Amnell Voir le message
    Votre code, remaké en un peu plus joli :

    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
    void /* Votre slot de réception de données */
    {
        QDataStream in(socket);
     
        if (tailleMessage == 0)
        {
            if (socket->bytesAvailable() < (int)sizeof(quint16))
            {
                qDebug() << "Error: socket->bytesAvailable() < (int)sizeof(quint16)"
                return;
            }
            in >> tailleMessage;
        }
     
        if (socket->bytesAvailable() < tailleMessage)
        {
            qDebug() << "Error: socket->bytesAvailable() < tailleMessage";
            return;
        }
     
        QString message;
        in >> message;
     
        tailleMessage = 0;
    }
    Il faut savoir que la réception ne se fait pas d'un coup, d'où le fait qu'il y ait de tels tests dans le code. Mais à un moment ou à un autre, vous devez franchir les deux conditions.
    Ça donne ce résultat:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Error: socket->bytesAvailable() < tailleMessage 
    Error: socket->bytesAvailable() < tailleMessage 
    Error: socket->bytesAvailable() < tailleMessage 
    Error: socket->bytesAvailable() < tailleMessage 
    Error: socket->bytesAvailable() < tailleMessage

  8. #8
    Rédacteur
    Avatar de Amnell
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2009
    Messages
    1 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 840
    Points : 5 545
    Points
    5 545
    Par défaut
    C'est tout à fait normal. Et maintenant, si vous remplacez :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        QString message;
        in >> message;
    Par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        QString message;
        in >> message;
     
        qDebug() << "Message obtenu";
    Qu'obtenez-vous ?
    N'oubliez pas de consulter la FAQ Qt ainsi que les cours et tutoriels C++/Qt !

    Dernier article : Débuter avec les Enlightenment Foundation Libraries (EFL)
    Dernières traductions : Introduction à Qt Quick - Applications modernes avec Qt et QML
    Vous cherchez un livre sur Qt 5, Qt Quick et QML ? Créer des applications avec Qt 5 - Les essentiels

  9. #9
    Membre du Club
    Homme Profil pro
    Inscrit en
    Février 2007
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 102
    Points : 66
    Points
    66
    Par défaut
    Citation Envoyé par Amnell Voir le message
    C'est tout à fait normal. Et maintenant, si vous remplacez :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        QString message;
        in >> message;
    Par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        QString message;
        in >> message;
     
        qDebug() << "Message obtenu";
    Qu'obtenez-vous ?
    Ça donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Error: socket->bytesAvailable() < tailleMessage 
    Error: socket->bytesAvailable() < tailleMessage 
    Error: socket->bytesAvailable() < tailleMessage 
    Error: socket->bytesAvailable() < tailleMessage 
    Error: socket->bytesAvailable() < tailleMessage

  10. #10
    Rédacteur
    Avatar de Amnell
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2009
    Messages
    1 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 840
    Points : 5 545
    Points
    5 545
    Par défaut
    Dans ce cas, c'est sans doute la partie serveur qui pose problème. Puis-je voir la partie serveur où vous envoyez les données, s'il vous plait ?
    N'oubliez pas de consulter la FAQ Qt ainsi que les cours et tutoriels C++/Qt !

    Dernier article : Débuter avec les Enlightenment Foundation Libraries (EFL)
    Dernières traductions : Introduction à Qt Quick - Applications modernes avec Qt et QML
    Vous cherchez un livre sur Qt 5, Qt Quick et QML ? Créer des applications avec Qt 5 - Les essentiels

  11. #11
    Membre du Club
    Homme Profil pro
    Inscrit en
    Février 2007
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 102
    Points : 66
    Points
    66
    Par défaut
    Citation Envoyé par Amnell Voir le message
    Dans ce cas, c'est sans doute la partie serveur qui pose problème. Puis-je voir la partie serveur où vous envoyez les données, s'il vous plait ?
    Oui bien sur, voici la méthode qui permet d'envoyer
    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
    void FenServeur::envoyerATous(const QString &message,QTcpSocket* emetteur)
    {
        // Préparation du paquet
        QByteArray paquet;
        QDataStream out(&paquet, QIODevice::WriteOnly);
        out << (quint16) 0; //On écrit 0 au début du paquet pour réserver la place pour écrire la taille
        out << message;
        out.device()->seek(0); //On se replace au début du paquet
        //On écrase le 0 qu'on avait réservé par la longueur du message
        out << (quint16) (paquet.size() - sizeof(quint16));
        // Envoi du paquet préparé à tous les clients connectés au serveur
        for (int i = 0; i < clients.size(); i++)
        {
            if(clients[i]!=emetteur)
            {
                //ecrire sur la fenetre serveur ce qu'il envoie
                etatServeur->setText(message);
                clients[i]->write(paquet);
            }
        }
    }

  12. #12
    Rédacteur
    Avatar de Amnell
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2009
    Messages
    1 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 840
    Points : 5 545
    Points
    5 545
    Par défaut
    Tant qu'à faire, autant avoir des logs plus détaillés :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    qDebug() << "Error: socket->bytesAvailable() < tailleMessage";
    À remplacer par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    qDebug() << "Error: socket->bytesAvailable() < tailleMessage, with byteAvailable() = "
        << socket->bytesAvailable() << " and tailleMsg = " << tailleMessage;
    N'oubliez pas de consulter la FAQ Qt ainsi que les cours et tutoriels C++/Qt !

    Dernier article : Débuter avec les Enlightenment Foundation Libraries (EFL)
    Dernières traductions : Introduction à Qt Quick - Applications modernes avec Qt et QML
    Vous cherchez un livre sur Qt 5, Qt Quick et QML ? Créer des applications avec Qt 5 - Les essentiels

  13. #13
    Membre du Club
    Homme Profil pro
    Inscrit en
    Février 2007
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 102
    Points : 66
    Points
    66
    Par défaut
    Citation Envoyé par Amnell Voir le message
    Tant qu'à faire, autant avoir des logs plus détaillés :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    qDebug() << "Error: socket->bytesAvailable() < tailleMessage";
    À remplacer par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    qDebug() << "Error: socket->bytesAvailable() < tailleMessage, with byteAvailable() = "
        << socket->bytesAvailable() << " and tailleMsg = " << tailleMessage;
    J'avais pensé à ça comme derniere recours et j'ai obtenu:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    200  <  36852
    210  <  36852
    220  <  36852
    230  <  36852
    240  <  36852
    Donc j'ai pensé à initialisé tailleMessage à 0 au début de la fonction et ça marché, ceci dit, j'aimerais comprendre pourquoi au niveau de la meme fonction du serveur yavais pas ce probleme alors que dans ma classe client j'ai du faire cette initialisation dont je ne suis pas sur de la fiabilité.(ceci dit je suis content d'avoir trouvé quelque chose )

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

Discussions similaires

  1. envoi et réception des données via serial port
    Par azert2010 dans le forum C#
    Réponses: 2
    Dernier message: 09/05/2011, 23h53
  2. Réception de données via driver FTDI
    Par vtuning.net dans le forum C#
    Réponses: 3
    Dernier message: 22/03/2010, 02h05
  3. [Indy10][TIdUPDServer] Problème à la réception de données
    Par femtosa dans le forum Web & réseau
    Réponses: 0
    Dernier message: 18/10/2007, 14h28
  4. [Configuration] problème de réception de mail via formulaire
    Par FraK dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 5
    Dernier message: 26/06/2007, 17h45
  5. Réponses: 5
    Dernier message: 11/03/2004, 15h34

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