[QT & C++] Problème de flux de donnée

Résolu/Fermé
Lefouleo91 - 13 oct. 2008 à 18:13
 Lefouleo91 - 16 oct. 2008 à 18:19
Bonjour a tous .
Je code actuellement un programme sur QT avec le langage c++.
Ce programme est un chat . la partie chat marchai très bien jusqu'à que je décide de coder une autre fonction de ce programme , le programme ne devais plus recevoir que des paquets contenant un quint16(la taille du message) et un QString désormais il devrais recevoir deux quint 16 et un QString(le premier quint 16 etant un chiffre servant a savoir si le paquet contient un int (quint16 = 1) ou un QString(quint16 = 2)
Problème ! le message est bien envoyé et bien recus(je le sais grace a des marqueurs d'erreurs que j'ai inserer dans le slot receovirDonnées du serveur , la taille du message est bien extraite le problème vient du fait que je ne sais pas comment faire pour enlever un quint16 d'un flux
voila mon code :
void FenServeur::donneesRecues()
{
   envoyerATous(newMessage);
   QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());
    if (socket == 0) // Si par hasard on n'a pas trouvé le client à l'origine du signal, on arrête la méthode
        return;

    // Si tout va bien, on continue : on récupère le message
    QDataStream in(socket);

    if (tailleMessage == 0) // Si on ne connaît pas encore la taille du message, on essaie de la récupérer
    {
        if (socket->bytesAvailable() < (int)sizeof(quint16))
        return;


        in >> tailleMessage; // Si on a reçu la taille du message en entier, on la récupère
    }

    if (socket->bytesAvailable() < (int)  (sizeof(quint16) *2)   ) // Si on n'a pas encore tout reçu, on arrête la méthode
    return;

       in >> type;
       type - tailleMessage;

    if(type == 1)
    {
    envoyerATous(erreur);
        return;
    }

    erreur = "pas de problème !";
    envoyerATous(erreur);
    // Si on connaît la taille du message, on vérifie si on a reçu le message en entier
    if (socket->bytesAvailable() < tailleMessage) // Si on n'a pas encore tout reçu, on arrête la méthode
        return;

 // Si ces lignes s'exécutent, c'est qu'on a reçu tout le message : on peut le récupérer !
    QString message;
    in >> message;

    envoyerATous(message);

    // 3 : remise de la taille du message à 0 pour permettre la réception des futurs messages
    tailleMessage = 0;

}


Le problème viens de cette partie je pense :
 in >> message;


le message ne peut pas s'afficher car le in ne contient pas qu'un QString donc comment faire pour supprimer les deux quint16du in(le flux) .

Merci d'avance et bonne journée.

10 réponses

Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
14 oct. 2008 à 16:58
heu...
je pense qu'il suffit de dépiler :
Quint16 a;
in>>a;
in>>a;
in>>message;
Tu envoie deux quint16 et un string, il faut donc récupérer deux quint16 et un string. Non ?
1
up !
0
Oui.
Merci de ta réponse mais comme les quint16 sont insérés d'abord il faut faire l'opération que tu viens d'écrire dans l'autre sens non?
0
Je crois que j'ai trouver une erreur(mais ca marche toujours pas)

j'ai transformer :

in >> tailleMessage; // Si on a reçu la taille du message en entier, on la récupère
    }

    if (socket->bytesAvailable() < (int)  (sizeof(quint16) *2)   )


en :

if (socket->bytesAvailable() < (int)sizeof(quint16)   )// recupération du type


le fois deux ne servait a rien car le premier quint16 etait deja enlever dans le :

in >> tailleMessage;


mais ca ne marche toujours pas donc .. si quelqu'un trouve ! :)
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Salut , les deux variables sont bien des quint16 :

quint16 tailleMessage , type;


J'ai un peu changer mon code :

 if (tailleMessage == 0) // Si on ne connaît pas encore la taille du message, on essaie de la récupérer
    {
        if (socket->bytesAvailable() < (int)sizeof(quint16))
        return;


        in >> tailleMessage; // Si on a reçu la taille du message en entier, on la récupère
    }


donc la on recoit la taille du message(la taille d'un quint16) puis on dépile , donc normalement pas de problème.

if (socket->bytesAvailable() < (int)sizeof(quint16) *2  ) // Si on n'a pas encore tout reçu, on arrête la méthode
    return;

       in >> type;


La on recoit le type (la taille de deux quint16 donc vus qu'on a deja recu al taille d'un quint16) puis on dépile , normalement il ne devrait pas y avoir de problème!

if (type == 1)
       return;

Si c'est un chiffre on arrete la méthode.

erreur = "pas de problème !";
    envoyerATous(erreur);
    // Si on connaît la taille du message, on vérifie si on a reçu le message en entier
    if (socket->bytesAvailable() < tailleMessage) // Si on n'a pas encore tout reçu, on arrête la méthode
        return;

 // Si ces lignes s'exécutent, c'est qu'on a reçu tout le message : on peut le récupérer !
    QString message;
    in >> message;

    envoyerATous(message);

    // 3 : remise de la taille du message à 0 pour permettre la réception des futurs messages
    tailleMessage = 0;
    type = 0;


Puis on envoie le message qui dit que tout c'est bien passer et on reçoit le message , on affiche le message et on remet tout a zéro. J'ai beau chercher je ne vois pas ce qui merde également.

Ce qui se passe c'est que :

Je lance le serveur il indique que le programme a bien été démarré.
Je lance un client en local , ill m'indique que la connexion a bien réussie.
Quand jenvoie un nouveau message ca me dit bien qu'un message a été reçu grâce a cette ligne au début du slot :
envoyerATous(newMessage);

Puis , ca alterne a chaque fois que j'envoie un message ca met un nouveau message , problème de type etc ... le programme s'execute parfaitemet mais il n'affiche pas les string .
j'envoie un screen :
https://www.hiboox.fr/
Voila merci !
0
Salut, je ne connais pas de print(je connais juste printf et c'est en C ! )
Donc c'est une fonction de QT ou de c++ en général(por savoir dans quelle doc je dois chercher) sinon comment l'utiliser?
0
Salut , j'ai modifier deux trois trucs et finalement j'ai réussi a tout faire marcher ! Super , merci beaucoup de ton aide en tout cas !
(j'ai enlever les marqueurs d'erreurs pour les remplacer par des cout et tout marche au poil) merci beaucoup !
0
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
15 oct. 2008 à 08:54
type - tailleMessage;
instruction inutile, à moins que type soit une classe.
le code n'est pas très clair, mais tu récupère in>>tailleMessage puis in>>type.
Tu as donc dépiler deux fois. Les deux variable sont elles bien de type quint16 ?
Je ne vois pas ce qui merde.
Essaie d'être plus explicite lorsque tu dit "ça ne marche pas", où ton programme s'arrete-t-il ?
-1
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
15 oct. 2008 à 14:59
méthode barbare : rajoute des print.
if (socket->bytesAvailable() < tailleMessage)
vérifie en sortie directe les valeurs de ces deux constantes.

Je ne suis pas très fort en stream, mais en théorie, in>>message doit bloqué tant qu'il n'y a rien à mettre dans message dans le pile non ?

Il faut peut être fermer proprement ton QDataStream aussi à la fin de la routine.

Le meilleur moyen, c'est de voir ce qui sort exactement dans chaque variable au fur et à mesure.
-1
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
16 oct. 2008 à 11:08
comme tu veux, soit tu inclus strdio et tu utilise printf, soit iostream et cout. (il faut donc compiler en conservant la console)
Sinon, tu peux aussi écrire dans un fichier avec (presque) les même commandes
Sinon, tu peux aussi utiliser Qt avec le statique : QMessageBox::information ( QWidget * parent, const QString & title, const QString & text, StandardButtons buttons = Ok,defaultButton = NoButton ) (je te laisse regarder la doc.)
-1