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

Qt Discussion :

QTcpSocket read : pas de données


Sujet :

Qt

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 20
    Par défaut QTcpSocket read : pas de données
    Bonjour,

    J'ai un problème de réception de données avec mon appli client:

    J'ai essayé de suivre l'exemple : http://qt.developpez.com/doc/4.5/network-fortuneclient/

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    void MainWindow::readServerData()
    {
        QDataStream in(_tcpSocket);
          qDebug() << "bytesAvailable " << _tcpSocket->bytesAvailable();
            if (_tcpSocket->bytesAvailable() == 0)
                return;
     
        QString data;
        in >> data;
        qDebug() << "data " << data;
    }
    Le serveur envois la chaine suivante "hello"
    Le packet tcp est bien reçu, la fonction est appelée.
    Le nombre de byte est correcte, mais impossible d'afficher le contenu.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    bytesAvailable  6 
    data  "
    Quelqu'un aurait-il une idée?

  2. #2
    Membre très actif
    Avatar de FloMo
    Homme Profil pro
    Freelance iOS
    Inscrit en
    Juillet 2004
    Messages
    726
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Deux Sèvres (Poitou Charente)

    Informations professionnelles :
    Activité : Freelance iOS
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 726
    Par défaut
    Utiliser QByteArray au lieu de QString ?

  3. #3
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut
    Citation Envoyé par Ferllings Voir le message
    Le serveur envois la chaine suivante "hello"
    Visiblement, le string n'a pas été encodé côté serveur avec le même principe (QDataStream), qui utilise ce format d'encodage:
    QString
    * If the string is null: 0xFFFFFFFF (quint32)
    * Otherwise: The string length in bytes (quint32) followed by the data in UTF-16
    Ici, pour 'hello', on aurait plutôt dû recevoir 14 octets: 4 octets (32bits) pour la taille du string et (ici) chacune des 5 lettres encodée sur 2 octets (cf. UTF-16.

    Ce qui m'amène à penser que le string a probablement été encodée en tant que 'dump' direct d'un char* (6 octets = 5 lettres de 'hello' plus le caractère de fin '\0').

    Donc on en revient à la proposition de FloMo: passer par un QByterArray pour récupérer les 6 octets, puis utiliser le constructeur QString(QByteArray) pour retrouver ton 'hello' de départ.

    A noter qu'en utilisant une telle méthode d'encodage côté serveur, tu vas très vite être bloqué avec les caractères ne faisant pas partie de l'ASCII standard (genre '€'). Il est plus que conseillé d'encoder en passant par les QString côté serveur également.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 20
    Par défaut
    J'ai essayé ca, mais j'obtiens le même résultat.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    QByteArray data;
        _tcpSocket->read(data.data(), data.size());
          qDebug() << "bytesAvailable " << _tcpSocket->bytesAvailable();
        qDebug() << "data " << data;

  5. #5
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Salut,
    si tu veut pouvoir lire ta string envoyé, il faut que bytesAvailable() retourne un nombre >= à la taille de ta string. Sinon tu va faire des lecture corrompu.
    En principe, on ajoute la taille de l'élément envoyé en début del'envoie. A la réception, on lit ainsi la taille à attendre et l'on fait une récupération une fois ce nombre de byte atteins.
    regarde les exemple deans Qt, il montre le principe :
    http://qt.developpez.com/doc/4.4/network-fortuneserver/
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    QByteArray block;
         QDataStream out(&block, QIODevice::WriteOnly);
         out.setVersion(QDataStream::Qt_4_0);
         out << (quint16)0;
         out << fortunes.at(qrand() % fortunes.size());
         out.device()->seek(0);
         out << (quint16)(block.size() - sizeof(quint16));

    http://qt.developpez.com/doc/4.4/network-fortuneclient/
    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
         QDataStream in(tcpSocket);
         in.setVersion(QDataStream::Qt_4_0);
     
         if (blockSize == 0) {
             if (tcpSocket->bytesAvailable() < (int)sizeof(quint16))
                 return;
     
             in >> blockSize;
         }
     
         if (tcpSocket->bytesAvailable() < blockSize)
             return;
     
         QString nextFortune;
         in >> nextFortune;

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 20
    Par défaut
    Citation Envoyé par yan Voir le message
    Salut,
    si tu veut pouvoir lire ta string envoyé, il faut que bytesAvailable() retourne un nombre >= à la taille de ta string. Sinon tu va faire des lecture corrompu.
    En principe, on ajoute la taille de l'élément envoyé en début del'envoie. A la réception, on lit ainsi la taille à attendre et l'on fait une récupération une fois ce nombre de byte atteins.
    regarde les exemple deans Qt, il montre le principe :
    http://qt.developpez.com/doc/4.4/network-fortuneserver/
    Merci Yan mais tu n'as pas du comprendre ma question:
    Je suis justement parti de ces examples pour mon client.
    Mais dans mon cas ca ne fonctionnait pas vu que je n'ai pas de contrôle sur le serveur, et qu'il envoit des caractères dans un encodage different.
    C'est pourquoi on m'a conseillé d'utiliser QByteArray.
    En se qui concerne la taille de la donnée envoyée je m'en occuperais une fois que j'aurais reussi à reçevoir quelques caractères

  7. #7
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    ha ok.
    Ben il faut pas passer par une QString alors

  8. #8
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut
    La solution proposée par yan est effectivement indispensable pour ne pas corrompre à terme ton flux de données.

    Citation Envoyé par Ferllings Voir le message
    J'ai essayé ca, mais j'obtiens le même résultat
    Pour info, dans ton cas précis, le nombre d'octets et assez restreint pour qu'il soit envoyé dans un seul paquet, donc l'origine du problème ne venait pas de ce que t'explique (à raison) yan.

    Mais, dans ton exemple de code, tu initialises un QByteArray sans paramètre qui, d'après la doc:
    Constructs an empty byte array.
    C'est donc un QByteArray qui a une taille de ... zéro octets.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    _tcpSocket->read(data.data(), data.size());
    Donc, la ligne ci-dessus ne va lire ... rien du tout car data.size() vaut zéro !

    CQFD.

Discussions similaires

  1. pb de syntaxe XML ne reconnais pas les données ..
    Par lolodelp dans le forum XML/XSL et SOAP
    Réponses: 1
    Dernier message: 19/06/2006, 11h24
  2. y'a pas les données quand je veux imprimer
    Par StyleXP dans le forum Bases de données
    Réponses: 38
    Dernier message: 25/03/2006, 19h15
  3. probleme XPath, j'obtiens pas ma données ?
    Par Bruno13 dans le forum Langage
    Réponses: 7
    Dernier message: 02/02/2006, 14h25
  4. XMLEncoder ne sauvegarde pas la donnée d'un PlainDocument.
    Par mitje dans le forum Format d'échange (XML, JSON...)
    Réponses: 1
    Dernier message: 27/01/2006, 04h06
  5. [ORA-01403] Pas de données trouvées ; et alors ?
    Par szdavid dans le forum Oracle
    Réponses: 6
    Dernier message: 02/08/2005, 11h20

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