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

Réseau Discussion :

Problème de réception via TCP


Sujet :

Réseau

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    75
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2007
    Messages : 75
    Points : 61
    Points
    61
    Par défaut Problème de réception via TCP
    Bonjour à tous,
    je voudrais pourvoir récupérer le message que j envoie depuis mon application client mais la le serveur ne me renvoie rien.
    Il arrête après l 'etape1.
    Et je ne vois pas d'où vient le problème.
    D'avance merci.

    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
    38
    39
    40
    41
    void FenConnecter::donneesRecues()
    {
        QMessageBox::information(this,"test","Données recue");
     
        // 1 : on reçoit un paquet (ou un sous-paquet) d'un des clients
     
        // On détermine quel client envoie le message (recherche du QTcpSocket du client)
        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)) // On n'a pas reçu la taille du message en entier
                 return;
     
            in >> tailleMessage; // Si on a reçu la taille du message en entier, on la récupère
        }
        QMessageBox::information(this,"test","Taille message :"+QString::number(tailleMessage));
        QMessageBox::information(this,"test","Taille du socket:"+QString::number(socket->bytesAvailable()));
        QMessageBox::information(this,"test","etape1");
        // 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;
        QMessageBox::information(this,"test","etape2");
     
        // 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;
        QMessageBox::information(this,"test","etape3");
     
     
        // 2 : on renvoie le message à tous les clients
        QMessageBox::information(this,"test","le message est : "+message);
     
        // 3 : remise de la taille du message à 0 pour permettre la réception des futurs messages
        tailleMessage = 0;
        QMessageBox::information(this,"test","etape4");

  2. #2
    Membre confirmé

    Inscrit en
    Décembre 2009
    Messages
    164
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 164
    Points : 490
    Points
    490
    Par défaut
    Salut,
    Il faut attendre l'émission du signal readyRead() dans QTcpSocket pour commencer à lire ce que tu as reçu.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    75
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2007
    Messages : 75
    Points : 61
    Points
    61
    Par défaut
    Mais ca je le fait lorsque je reçois des données voici le code complet:
    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    #include "fenconnecter.h"
    #include "ui_fenconnecter.h"
    #include <QMessageBox>
     
     
    FenConnecter::FenConnecter(QWidget *parent,int port) :
        QMainWindow(parent),
        ui(new Ui::FenConnecter)
    {
     
        ui->setupUi(this);
        tailleMessage=0;
        serveur = new QTcpServer(this);
     
        if(serveur->listen(QHostAddress::Any, port)){
            QMessageBox::information(this, "Information", "Le serveur est chargé sur le port 50000", QMessageBox::Ok);
            connect(serveur, SIGNAL(newConnection()), this, SLOT(nouvelleConnexion()));
            this->close();
        }else{
            QMessageBox::critical(this,"Erreur","Le serveur n'a pu etre chargé");
        }
     
        modele = new QStandardItemModel(1, 1);
        //modele->setItem(3, 1, new QStandardItem("Zéro !"));
        ui->tableView->setModel(modele);
        //HorizontalHeader
        //ui->tableView->setHorizontalHeader();
     
     
     
    }
     
    FenConnecter::~FenConnecter()
    {
        delete ui;
    }
    void FenConnecter::remplirTable(){
     
     
        modele->setItem(clients.length(), 0, new QStandardItem("Clients "+QString::number(clients.length())));
     
    }
    void FenConnecter::ajoutServer(QTcpServer *srv){
        serveur=srv;
         QMessageBox::information(this,"test",serveur->errorString()+" / "+ QString::number(serveur->serverPort())+" / ");
     
     
     }
     
    void FenConnecter::nouvelleConnexion()
    {
     
     
       QMessageBox::information(this,"test","Un nouveau client vient de se connecter");
        QTcpSocket *nouveauClient = serveur->nextPendingConnection();
        clients << nouveauClient;
        connect(nouveauClient, SIGNAL(readyRead()), this, SLOT(donneesRecues()));
        remplirTable();
        //connect(nouveauClient, SIGNAL(disconnected()), this, SLOT(deconnexionClient()));
     
    }
    void FenConnecter::donneesRecues()
    {
        QMessageBox::information(this,"test","Données recue");
     
        // 1 : on reçoit un paquet (ou un sous-paquet) d'un des clients
     
        // On détermine quel client envoie le message (recherche du QTcpSocket du client)
        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);
        QMessageBox::information(this,"test",QString::number(tailleMessage));
        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)) // On n'a pas reçu la taille du message en entier
                 return;
     
            in >> tailleMessage; // Si on a reçu la taille du message en entier, on la récupère
        }
        QMessageBox::information(this,"test","Taille message :"+QString::number(tailleMessage));
        QMessageBox::information(this,"test","Taille du socket:"+QString::number(socket->bytesAvailable()));
        QMessageBox::information(this,"test","etape1");
        // 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;
        QMessageBox::information(this,"test","etape2");
     
        // 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;
        QMessageBox::information(this,"test","etape3");
     
     
        // 2 : on renvoie le message à tous les clients
        QMessageBox::information(this,"test","le message est : "+message);
     
        // 3 : remise de la taille du message à 0 pour permettre la réception des futurs messages
        tailleMessage = 0;
        QMessageBox::information(this,"test","etape4");
     
    }
     
    void FenConnecter::deconnexionClient()
    {
        //envoyerATous(tr("<em>Un client vient de se déconnecter</em>"));
     
        // On détermine quel client se déconnecte
        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;
     
        clients.removeOne(socket);
     
        socket->deleteLater();
    }
    mais le problème est vraiment après l'étape 1
    Apparemment il ne reçoit pas le message complet d'où cella peut provenir ?

  4. #4
    Membre éprouvé

    Profil pro
    Responsable logiciel
    Inscrit en
    Octobre 2010
    Messages
    223
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Responsable logiciel

    Informations forums :
    Inscription : Octobre 2010
    Messages : 223
    Points : 1 183
    Points
    1 183
    Par défaut
    Il se passe quoi précisément à l'exécution ?
    NB tu devrais peut être tracer dans la console avec qDebug plutôt que d'utiliser des messageBox qui risquent de perturber l'exécution de ton traitement.

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    75
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2007
    Messages : 75
    Points : 61
    Points
    61
    Par défaut
    Oui effectivement qDebug serait plus judicieux.

    en faite c'est tout simple cette condition est remplie.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if (socket->bytesAvailable() < tailleMessage) // Si on n'a pas encore tout reçu, on arrête la méthode
            return;
    Donc il quitte la fonction

    Mais je ne comprends pas pourquoi il ne reçoit pas le message complètement. Alors que je teste ca en local sur ma machine.

    Lorsque j effectue mes teste le socket->bytesAvailable() vaut 28 sur mon client et sur mon serveur il est de 26.

  6. #6
    Membre confirmé

    Inscrit en
    Décembre 2009
    Messages
    164
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 164
    Points : 490
    Points
    490
    Par défaut
    Est ce que tu pourrais montrer le code pour envoyer un message ?
    Quel est le type de ta variable tailleMessage ?

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    75
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2007
    Messages : 75
    Points : 61
    Points
    61
    Par défaut
    Voila le code pour envoier:
    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
     
    void Client::slotEnvoie(){
        QByteArray paquet=0;
        QDataStream out(&paquet, QIODevice::WriteOnly);
        // On prépare le paquet à envoyer
        QString messageAEnvoyer =  "qqch"+ui->leNom->text();
     
        out << (quint16) 0;
        out << messageAEnvoyer;
        out.device()->seek(0);
        out << (quint16) (paquet.size() - sizeof(quint16));
        QMessageBox::information(this,"test",QString::number(paquet.size()));
        socket->write(paquet); // On envoie le paquet
     
    }
    Arfff effectivement j avais mis tailleMessage en int et pas en quint16

    Merci beaucoup pour votre aide.

    @ bientôt

  8. #8
    Membre confirmé

    Inscrit en
    Décembre 2009
    Messages
    164
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 164
    Points : 490
    Points
    490
    Par défaut
    Sinon, fais attention à la lecture :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
        if (socket->bytesAvailable() < tailleMessage) 
            return;
     
     
        QString message;
        in >> message;
    car tu es sûr d'avoir reçu un message en entier mais il n'est pas improbable que tu aies reçu un bout du message suivant ...
    Il faudrait ne lire que ton message courant et refaire la même procédure pour relire l'entête et le corps du message suivant.

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

Discussions similaires

  1. [Débutant] Problème de réception de trame via dialogue IP
    Par mck74 dans le forum C#
    Réponses: 40
    Dernier message: 27/03/2015, 10h05
  2. Problème de réception RECV (TCP/IP)
    Par CleeM dans le forum Réseau
    Réponses: 3
    Dernier message: 25/05/2012, 11h48
  3. Problème de réception de données via QTcpSocket
    Par bilou_2007 dans le forum Débuter
    Réponses: 12
    Dernier message: 16/04/2011, 20h45
  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. Problème de réception TCP/IP.
    Par BigBulle dans le forum C#
    Réponses: 4
    Dernier message: 02/04/2007, 21h27

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