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 :

QByteArray mal décodé à la réception

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Développeur Front
    Inscrit en
    Décembre 2013
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Front
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2013
    Messages : 59
    Par défaut QByteArray mal décodé à la réception
    Salut à tous!
    Voilà, je suis en train de me faire un petit updater histoire de rendre mes distributions pérennes dans le temps. Toute la partie de test de fichiers, détermination de la similitude entre le fichier client et le fichier serveur via Md5 et Sh4 est fonctionnelle (revue, testée, validée, mangée, recrachée, etc), et je me retrouve donc avec une QStringList contenant le nom des fichiers à envoyer du serveur au client. Le code que je fait suivre concerne uniquement la partie émission-réception du fichier.
    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
    Server.cpp
    void Server::sendFile(QStringList &files, QString ClientPath)
    {
        if (indexDL < files.size())
        {
            QByteArray paquet;
            QDataStream out(&paquet, QIODevice::WriteOnly);
            out << quint32(0); // On écrit 0 au début du paquet pour réserver la place pour écrire la taille
            //Ouverture du fichier
            QFile fileReading(ClientPath+files[indexDL]);
            if (fileReading.open(QIODevice::ReadOnly))
            {
                out << (quint16) QString("1111").toInt(0 , 16); //On insère la balise
                out << fileReading.readAll();//On ajoute le contenu du fichier
            }
            else
                out << (quint16) QString("1110").toInt(0 , 16);//On insère une balise d'échec
            fileReading.close();
     
            out.device()->seek(0); // On se replace au début du paquet
            out << quint32(paquet.size() - (sizeof(quint16)+sizeof(quint32))); // On écrase le 0 qu'on avait réservé par la longueur du message
            // Envoi du message au client
            m_TcpSocket->write(paquet, paquet.size());
            indexDL++;
        }
        else
        {
            QByteArray paquet;
            QDataStream out(&paquet, QIODevice::WriteOnly);
            out << (quint32) 0; // On écrit 0 au début du paquet pour réserver la place pour écrire la taille
            out << (quint16) QString("1112").toInt(0 , 16); //On insère la balise de fin de téléchargement
            out.device()->seek(0); // On se replace au début du paquet
            out << (quint32) (paquet.size() - (sizeof(quint16)+sizeof(quint32))); // On écrase le 0 qu'on avait réservé par la longueur du message
            // Envoi du message au client
            m_TcpSocket->write(paquet);
        }
    }
    Et maintenant le client:
    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
    Client.cpp
    void Client::serverRece()
    {
        quint16 balise;
        QByteArray dataBA;
        quint32 messageSizeDL=0;
        // Même principe que lorsque le serveur reçoit un paquet : On essaie de récupérer la taille du message Une fois qu'on l'a, on attend d'avoir reçu le message entier (en se basant sur la taille annoncée messageSizeDL)
        QDataStream in(socket);
        if (messageSizeDL == 0)
        {
            if (socket->bytesAvailable() < sizeof(quint32))
                return;
            in >> messageSizeDL;
        }
        if (socket->bytesAvailable() < messageSizeDL)
           return;
        // Si on arrive jusqu'à cette ligne, on peut récupérer le message entier
        in >> balise;
        in >> dataBA;                
        statusQPB->setValue(dataBA.size()+statusQPB->value());
        messageSizeDL = 0;
        ...
    }
    Là où tout cela devient bizarre, c'est qu'au premier fichier, tout fonctionne comme il faut. Mon fichier est écrit au bon endroit, avec le bon contenu (à savoir, dataBA que j'utilise plus loin dans la méthode, mais que je n'ai pas montré ici). En revanche, au second fichier, messageSizeDL prend une valeur de 286261248 au lieu du 13 lié à la longueur de mon fichier test! Et après avoir poussé un peu plus mes tests, je me suis aperçu que cela ne dépendait pas du fichier envoyé, mais simplement du fait qu'il soit le 2ème.

    Quelqu'un pourrait-t'il m'éclairer sur l'origine de cette valeur pour le moins fantasque?

    Par avance, merci,

    Nihi

  2. #2
    Membre très actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2010
    Messages
    248
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2010
    Messages : 248
    Par défaut
    Bonjour,

    Il semblerait qu'une erreur de lecture se produise sur votre deuxième fichier, en effet le valeur 286261248 en décimal correspond à 0x11100000 en hexadécimal, ce qui ressemble étrangement à votre balise d'erreur (1110) avec un décalage de 16 bit (visiblement intérpretée comme une quint32)

    Une chose que je ne comprend pas, dans la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void Server::sendFile(QStringList &files, QString ClientPath)
    , vous passez une liste de nom de fichier, j'en conclut que vous voulez envoyer la liste en une seule fois ?
    Pourtant dans cette même fonction vous n'envoyer qu'un seul fichier, ou la balise de fin, dépendamment de la valeur de . Mais j'imagine que c'est parce que je ne vois pas tous le code que je ne comprend pas.

    Encore une petite remarque, vous pouvez remplacer pour vous simplifier la vie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    out << (quint16) QString("1112").toInt(0 , 16);
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    out << (quint16) 0x1112;

  3. #3
    Membre éclairé
    Homme Profil pro
    Développeur Front
    Inscrit en
    Décembre 2013
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Front
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2013
    Messages : 59
    Par défaut
    Merci pour cette réponse. Je vais effectivement essayer de me débarasser d'un maximum d'arguments en les mettant comme attributs de la classe. Néanmoins, j'avais réussit à contourner le problème. Je suis maintenant confronté à un autre, qui est peut-être lié, à ce lien.
    Cordialement,
    Nihilivin

Discussions similaires

  1. [XWiki] Caractères accentués mal décodés
    Par AurelienDev dans le forum Autres
    Réponses: 0
    Dernier message: 07/07/2009, 11h32
  2. plantage lors de réception de fihier
    Par marsupile dans le forum C++Builder
    Réponses: 9
    Dernier message: 22/01/2004, 18h08
  3. Pb de pointeur mal détruit
    Par olive_le_malin dans le forum MFC
    Réponses: 20
    Dernier message: 15/01/2004, 21h20
  4. Réponses: 3
    Dernier message: 12/05/2003, 12h11

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