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 :

Probleme avec QtcpSocket


Sujet :

Qt

  1. #1
    Membre du Club
    Inscrit en
    Janvier 2010
    Messages
    68
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 68
    Points : 54
    Points
    54
    Par défaut Probleme avec QtcpSocket
    Bonjour,

    Je suis entrain de développer une interface pour communiquer avec un automate de type Beckhoff, j'utilise pour cela la classe QtcpSocket de Qt, et j'envoie la trame sur le réseaux. L'automate recois bien la trame et me repond, je le sais car j'analyse mes trame avec wireshark, le probléme c'est que je n'arrive pas à intercepter le signal avec le signal "readyRead" de la classe QIOdevice. j'ai essayé de debugger, mais le programme ne rentre jamais dans la fonction connecté au signal.

    N'y aurais il pas un probléme de socket bloquant ou pas?

    Merci

  2. #2
    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 : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    salut et bienvenue

    Sans code (et sans notre boule de cristal), il va nous être assez difficile de te répondre
    Mon projet du moment: BounceBox, un jeu multijoueurs sur Freebox, sur PC et depuis peu sur smartphone/tablette Android.

  3. #3
    Membre du Club
    Inscrit en
    Janvier 2010
    Messages
    68
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 68
    Points : 54
    Points
    54
    Par défaut
    Voila le code, j'espére que vous pourrait m'aider, 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
    #ifndef ADS_H
    #define ADS_H
     
     
    #include <QtNetwork>
    #include <QIODevice>
    #include <QtGui>
    #include "ui_FenClient.h"
    #include "types.h"
    #include "AdsHeaders.h"
     
     
    class Ads : public QWidget, private Ui::FenClient
    {    
    Q_OBJECT
     
    public:
        Ads();
     
    private slots:
        void on_boutonConnexion_clicked();
        void connecte();
        void deconnecte();
        void donneesRecues();
        void erreurSocket(QAbstractSocket::SocketError erreur);
        void on_boutonEnvoyer_clicked();
     
    private:
        QTcpSocket  *socket;
        quint16 tailleMessage;
    };
     
    #endif // ADS_H
    et le .cpp
    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
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
     
    #include "ads.h"
     
     
     
    Ads::Ads()
    {
        setupUi(this);
     
        socket = new QTcpSocket(this);
        connect(socket, SIGNAL(connected()), this, SLOT(connecte()));
        connect(socket, SIGNAL(disconnected()), this, SLOT(deconnecte()));
        connect(socket, SIGNAL(readyRead()), this, SLOT(donneesRecues()));
        connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(erreurSocket(QAbstractSocket::SocketError)));
     
    }
     
     
    //================================= Tentative de connexion au serveur==================================================
    void Ads::on_boutonConnexion_clicked()
    {
        // On annonce sur la fenêtre qu'on est en train de se connecter
        listeMessages->append(tr("<em>Tentative de connexion en cours...</em>"));
        boutonConnexion->setEnabled(false);
     
        socket->abort(); // On désactive les connexions précédentes s'il y en a   
        //socket->setSocketOption(QAbstractSocket::KeepAliveOption, 1);
        socket->connectToHost(serveurIP->text(), serveurPort->value()); // On se connecte au serveur demandé
     
    }
     
    //================================= Ce slot est appelé lorsque la connexion au serveur a réussi========================
    void Ads::connecte()
    {
        listeMessages->append(tr("<em>Connexion réussie !</em>"));
        boutonConnexion->setEnabled(true);
    }
     
     
     
    //================================= Ce slot est appelé lorsqu'on est déconnecté du serveur==============================
    void Ads::deconnecte()
    {
        listeMessages->append(tr("<em>Déconnecté du serveur</em>"));
    }
     
     
     
    //================================= Ce slot est appelé lorsqu'il y a une erreur=========================================
    void Ads::erreurSocket(QAbstractSocket::SocketError erreur)
    {
        switch(erreur) // On affiche un message différent selon l'erreur qu'on nous indique
        {        
            case QAbstractSocket::HostNotFoundError:
                listeMessages->append(tr("<em>ERREUR : le serveur n'a pas pu être trouvé. Vérifiez l'IP et le port.</em>"));
                break;
            case QAbstractSocket::ConnectionRefusedError:
                listeMessages->append(tr("<em>ERREUR : le serveur a refusé la connexion. Vérifiez si le programme \"serveur\" a bien été lancé. Vérifiez aussi l'IP et le port.</em>"));
                break;
            case QAbstractSocket::RemoteHostClosedError:
                listeMessages->append(tr("<em>ERREUR : le serveur a coupé la connexion.</em>"));
                break;
            case QAbstractSocket::SocketAccessError:
                listeMessages->append(tr("<em>ERREUR : Des droits sont demandés</em>"));
                break;
            case QAbstractSocket::SocketResourceError:
                listeMessages->append(tr("<em>ERREUR : Trop de sockets créés chez le serveur</em>"));
                break;
            case QAbstractSocket::DatagramTooLargeError:
                listeMessages->append(tr("<em>ERREUR : Le datagram etait plus grand que la limite de calcul du système</em>"));
                break;
            case QAbstractSocket::NetworkError:
                listeMessages->append(tr("<em>ERREUR : Une erreur est survenus sur le réseau</em>"));
                break;
            case QAbstractSocket::UnsupportedSocketOperationError:
                listeMessages->append(tr("<em>ERREUR : Opération non supporté par le système</em>"));
                break;
            case QAbstractSocket::ProxyAuthenticationRequiredError:
                listeMessages->append(tr("<em>ERREUR : Erreur Proxy</em>"));
                break;
            case QAbstractSocket::ProxyConnectionRefusedError:
                listeMessages->append(tr("<em>ERREUR : Erreur Proxy, connection refusé</em>"));
                break;
            case QAbstractSocket::ProxyConnectionClosedError:
                listeMessages->append(tr("<em>ERREUR : Erreur Proxy, Fermeture par le proxy</em>"));
                break;
            case QAbstractSocket::ProxyConnectionTimeoutError:
                listeMessages->append(tr("<em>ERREUR : Erreur Proxy, Time out</em>"));
                break;
            case QAbstractSocket::ProxyNotFoundError:
                listeMessages->append(tr("<em>ERREUR : Erreur Proxy, Le proxy n'a pas trouvé d'erreur</em>"));
                break;
            case QAbstractSocket::ProxyProtocolError:
                listeMessages->append(tr("<em>ERREUR : Erreur Proxy, Le proxy n'a pas compris</em>"));
                break;
            case QAbstractSocket::UnknownSocketError:
                listeMessages->append(tr("<em>ERREUR : Erreur inconnu</em>"));
                break;
            default:
                listeMessages->append(tr("<em>ERREUR : ") + socket->errorString() + tr("</em>"));
        }
     
        boutonConnexion->setEnabled(true);
    }
     
    //=================================Envoi d'un message au serveur=========================================================
    void Ads::on_boutonEnvoyer_clicked()
    {
        QByteArray paquet;
        QDataStream out(&paquet, QIODevice::WriteOnly);
        out.setVersion(QDataStream::Qt_4_6);
     
        //reserved
        out << (quint16) 0;
     
        //Length
        out << qToBigEndian((quint32) AMS_TCP_Header_Lenght->text().toInt());
     
        // AMSnetId Target
        QStringList NetIdList_dest = AMS_NetId_Target->text().split(".");
        if (NetIdList_dest.count()!=6)
            { listeMessages->append("Format : NetId target not Valid"); }
        foreach(QString Tk_Net_Id_dest, NetIdList_dest)
            { out << (quint8) Tk_Net_Id_dest.toInt(); }
     
        //AMSPortTarget
        out << qToBigEndian((quint16) AMS_Port_Target->text().toInt());
     
        // AMSnetId Source
        QStringList NetIdList_src = AMS_NetId_Source->text().split(".");
        if (NetIdList_src.count()!=6)
            { listeMessages->append("Format : NetId source not Valid"); }
        foreach(QString Tk_Net_Id_src, NetIdList_src)
            { out << (quint8) Tk_Net_Id_src.toInt(); }
     
        //AMSPort Source
        out << qToBigEndian((quint16) AMS_Port_Source->text().toInt());
     
        // Command Id
        out << qToBigEndian((quint16)ADS_READ);
     
        // State Flags
        out << qToBigEndian((quint16)STATE_ADS_COMMAND);
     
        // Data Length
        out << qToBigEndian((quint32) 12);
     
        //Error code
        out << qToBigEndian((quint32) ADSERR_NOERROR);
     
        //Invoke Id
        out<< (quint8) NetIdList_src[3].toInt() << (quint8) NetIdList_src[2].toInt()<< (quint8) NetIdList_src[1].toInt() << (quint8) NetIdList_src[0].toInt()  ;
     
     
        ////////read
        out << qToBigEndian((quint32)0x4020);
     
        out << qToBigEndian((quint32)0x0000);
     
        out << qToBigEndian((quint32) 2 );
     
     
        listeMessages->append(paquet.toHex());
        socket->write(paquet);
    }
     
    // On a reçu un paquet (ou un sous-paquet)
    void Ads::donneesRecues()
    {
     
        QDataStream in(socket);
        in.setVersion(QDataStream::Qt_4_6);
     
        QString messageRecu;
        in >> messageRecu;
     
        // On affiche le message sur la zone de Chat
        listeMessages->append(messageRecu);
     
        // On remet la taille du message à 0 pour pouvoir recevoir de futurs messages
        tailleMessage = 0;
    }

  4. #4
    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 : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    salut,

    je ne vois pas à première vue de souci dans ton code.

    - As-tu des messages d'erreur dans ta sortie console (genre un problème de connexion signal/slot, même si ici je n'en vois pas à priori) ?

    - Est-ce que tu récupères bien ton message 'connexion réussie' ?

    - Si tu ajoutes au tout début de la fonction donneesRecues() un message de debug, s'affiche-t-il ?

    - le thread qui exécute ton constructeur Ads est-il bien le même thread que celui qui utilsie la socket (typiquement, le thread principal de l'application) ?

    - lances-tu bien ton application avec quelque chose du genre 'qApp->exec()' dans ton main() (pour bien faire tourner l'event loop) ?

    - évites-tu bien de bloquer à un endroit où à un autre l'event loop avec un appel bloquant ?
    Mon projet du moment: BounceBox, un jeu multijoueurs sur Freebox, sur PC et depuis peu sur smartphone/tablette Android.

  5. #5
    Membre du Club
    Inscrit en
    Janvier 2010
    Messages
    68
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 68
    Points : 54
    Points
    54
    Par défaut
    Bonjour,

    D'abord merci pour cette réponse, c'est sympa, je vais répondre question par question:

    - Je n'ai n'y message d'erreur n'y même aucun warning.
    - Je récupére bien le message connexion réussie, d'ailleur je recois bien la réponse sur mon PC, je le vois sur wireshark (analyseur de trame)
    - j'ai essayé de debugger la fonction donneesRecues, et je ne rentre jamais dans la fonction. comme si le signal readyRead ne fonctionnait pas
    - j'utilise effectivement le thread de l'application de la maniére suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
            Ads test;
            test.show();     
        return a.exec();
    }
    - Je lance l'application comme montré au dessus (je débute en Qt, j'ai oublié de le dire)
    - je ne pense pas avoir d'événements bloquants, je ne pense pas en tout cas?

    Encore merci .

  6. #6
    Membre du Club
    Inscrit en
    Janvier 2010
    Messages
    68
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 68
    Points : 54
    Points
    54
    Par défaut
    Bon apparement en bricolant sur le serveur, je recois le msg, néamoins il est vide??? Pas possible d'apres mon analyseur de trame, ca veut dire que je récupére mal le msg.

    Le code de ma fonction est le suivant:

    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
    void Ads::donneesRecues()
    {
        //Petit message de debug pour verifier que l'on est dans la fonction
        qDebug() << "Je suis dans le fonction!!!";
     
        //On essaie de récupérer le message, une fois qu'on l'a, on attend d'avoir reçu le message entier (en se basant sur la taille annoncé
        QDataStream in(socket);
        in.setVersion(QDataStream::Qt_4_6);
     
        if (tailleMessage == 0)
        {
            if (socket->bytesAvailable() < (int)sizeof(quint16))
                {break;}
            in >> tailleMessage;
        }
     
        if (socket->bytesAvailable() < tailleMessage)
            {break;}
     
     
        // Si on arrive jusqu'à cette ligne, on peut récupérer le message entier
        QString messageRecu;
        in >> messageRecu;
     
        // On affiche le message sur la zone de Chat
        listeMessages->append(messageRecu);
     
        // On remet la taille du message à 0 pour pouvoir recevoir de futurs messages
        tailleMessage = 0;
    }
    quelqu'un serait-il pourquoi???

  7. #7
    Membre du Club
    Inscrit en
    Janvier 2010
    Messages
    68
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 68
    Points : 54
    Points
    54
    Par défaut
    euh erreur, c'est pas break mais return, juste pour précision je passe bien tout les "if", et "tailleMessage" reste a 0.

    dsl pour tout les post.

  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 : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    Citation Envoyé par tiagocerqueira Voir le message
    dsl pour tout les post.
    Y a pas de quoi.

    Par contre, n'oublie pas de mettre le fil de discussion en 'résolu' si ton problème l'est
    Mon projet du moment: BounceBox, un jeu multijoueurs sur Freebox, sur PC et depuis peu sur smartphone/tablette Android.

  9. #9
    Membre du Club
    Inscrit en
    Janvier 2010
    Messages
    68
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 68
    Points : 54
    Points
    54
    Par défaut
    bah c'est pas tout à fait résolu, j'ai tjr rien dans mon msg,

    Help me!!!

  10. #10
    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 : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    tu peux commencer par "épurer" ta fonction donneesRecues() pour faire des tests: tu te passes complètement du QDataStream, et au lieu de ça, tu récupères les données brutes (sous forme de QByteArray avec QIODevice::readAll() ) et tu les affiches sur la console.

    Eventuellement, si les sources de ton serveur sont accessibles, montrer l'algo qui écrit sur la socket seraitfort utile.
    Mon projet du moment: BounceBox, un jeu multijoueurs sur Freebox, sur PC et depuis peu sur smartphone/tablette Android.

  11. #11
    Membre du Club
    Inscrit en
    Janvier 2010
    Messages
    68
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 68
    Points : 54
    Points
    54
    Par défaut
    Merci pour le dernier conseil, ca fonctionne, j'ai plus qu'a mettre comme résolu.

    Bonne fin de journée.

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

Discussions similaires

  1. Probleme Reseau avec QTCPSocket
    Par SOAD08 dans le forum Qt
    Réponses: 2
    Dernier message: 18/09/2007, 14h38
  2. Probleme avec la copie des surfaces
    Par Black_Daimond dans le forum DirectX
    Réponses: 3
    Dernier message: 09/01/2003, 10h33
  3. probleme avec la touche F10
    Par b.grellee dans le forum Langage
    Réponses: 2
    Dernier message: 15/09/2002, 22h04
  4. Probleme avec fseek
    Par Bjorn dans le forum C
    Réponses: 5
    Dernier message: 04/08/2002, 07h17
  5. [Kylix] probleme avec un imagelist
    Par NicoLinux dans le forum EDI
    Réponses: 4
    Dernier message: 08/06/2002, 23h06

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