Partage
  • Partager sur Facebook
  • Partager sur Twitter

QT + debian

Sujet résolu
    3 septembre 2018 à 20:01:46

    Bonjours a tous,

    je développé un système de communication serveur client TCP avec QT .

    mon IDE est netbeans .

    j'ai crée le code sur windows est tout allez bien , mais quand j'ai porter mon code sur un debian sans interface graphique 

    j'ai eu un probleme avec 

    QApplication app(argc, argv);

    qui afficher : QTTCPServeur: cannot connect to X server (si je le compile avec mon IDE)

    si je l'exécute en ligne de commande il s'arrête a la même ligne .

    j'ai donc test sans est le serveur se lance ,il arrive a la fin (sémaphore ) le client se connect mais les QWidget::connect ne marche pas le serveur ne fait rien .

    code main :

        std::cout <<"main.12"<<std::endl;
        QApplication app(argc, argv);
        std::cout <<"main.14"<<std::endl;
        ServeurLogin *a = new ServeurLogin();
        std::cout <<"main.16"<<std::endl;
        QSemaphore semaphore(0);// faire mieu plus tard 
        semaphore.acquire(1);
        std::cout <<"main.19"<<std::endl;
        return app.exec();

    code ServeurLogin :

    class Serveur : public QObject
    {
        Q_OBJECT
    
        public:
            Serveur();
            
        private slots:
            void nouvelleConnexion();
    
        private:
    
            QTcpServer *serveur;
            QList<QTcpSocket *> clients;
            quint16 tailleMessage;
    };



    Serveur::Serveur()
    {
        // Gestion du serveur
        serveur = new QTcpServer(this);
        if (!serveur->listen(QHostAddress::Any, 50885)) // D�marrage du serveur sur toutes les IP disponibles et sur le port 50585
        {
            std::cout <<"Le serveur n'a pas pu étre démarré. Raison : "<<serveur->errorString().toStdString()<<std::endl;
        }
        else
        {
            std::cout <<"Le serveur a été démarré sur le port "<<QString::number(serveur->serverPort()).toStdString()<<std::endl;
            
            QWidget::connect(serveur, SIGNAL(newConnection()), this, SLOT(nouvelleConnexion()));
            serveur->waitForNewConnection();
        }
    
        tailleMessage = 0;
    }
    
    void Serveur::nouvelleConnexion()
    {
        std::cout <<"nouveau"<<std::endl;
        QTcpSocket *nouveauClient = serveur->nextPendingConnection();
        clients << nouveauClient;
        
        emit connexionS(nouveauClient);
        
        connect(nouveauClient, SIGNAL(readyRead()), this, SLOT(donneesRecues()));
        connect(nouveauClient, SIGNAL(disconnected()), this, SLOT(deconnexionClient()));
    }

    je ne vois pas comment faire .




    -
    Edité par di20 4 septembre 2018 à 12:47:43

    • Partager sur Facebook
    • Partager sur Twitter
      4 septembre 2018 à 20:12:44

      Bonjour,

      pourquoi faire un

              serveur->waitForNewConnection();

      juste après avoir fait l'association entre le signal de nouvelle connexion et le slot la traitant??

      à quoi sert ton

          emit connexionS(nouveauClient);

      ?

      D'autant que le signal "connexionS" n'a pas été défini dans la classe Serveur

      tu dis: "mais les QWidget::connect ne marche pas le serveur ne fait rien"

      D'où sort ce QWidget???

      • Partager sur Facebook
      • Partager sur Twitter
        4 septembre 2018 à 23:20:02

        salut bxdfr ,

        le serveur->waitForNewConnection();

        vient des tests que j'ai fait avec le client , qui si pour se dernier on ne rajoute pas waitForConnected(3000); il attend d'arrivée a app.exec();

        pour commencer la connexion .

        le connexionS est pour l'héritage le serveur a un système de login qui est géré par des classe plus haute .

        le QWidget est a la ligne 13 de serveur.cpp .

        • Partager sur Facebook
        • Partager sur Twitter
          5 septembre 2018 à 2:07:41

          Salut,

          Ton code est horrible à plus d'un termes :P 

          Je sais que c'est le code que le "cours" propose, mais cela confirme simplement que le cours qui concerne Qt (dans sa version 4.xx, alors que cela fait sept ans que l'on est passé à la version 5, et que la version stable actuelle est la 5.11.1) est aussi mauvais que le "soi disant" cours C++ ;)

          Je m'explique:

          1- La bonne manière de fournir des valeurs aux données membres passe par la liste d'initialisation. Le constructeur de ta classe Serveur devrait donc prendre une forme proche de

          Serveur::Serveur():server{new QTcpServer}, tailleMessage{0}
          {
             /* ce qu'il faut faire */
          }

          2- Si, pour une raison ou une autre, ton serveur n'arrive pas à démarrer correctement, tu te trouves face à une situation -- qui dépend sans doute d'avantage du "gestionnaire réseau" que de toi-même -- qui empêchera ton application de fonctionner correctement.

          La meilleure des choses à faire, dans ce cas là, est donc de lancer une exception, et de laisser "planter l'application" du fait de cette exception.  L'idéal étant d'avoir un message qui nous dise ce qui s'est réellement passé.

          Le corps de ton constructeur devrait donc ressembler à quelque chose comme

          Serveur::Serveur():server{new QTcpServer}, tailleMessage{0}
          {
             if(!server->listen(QHostAddress::Any,50885){
                 throw std::untime_error("Unable to launch server, please connect your lan manager");
             }
             /* si on arrive ici, c'est que tout s'est bien passé */
          }

          3- On n'utilise pas la sortie standard pour le débug!!!

          Si "quelque chose" va mal, on utilise ... le débuggeur ;)

          A priori, tu n'auras même pas accès à la console pour lancer ton serveur, car, d'une manière ou d'une autre, il devrait être considéré comme un service

          4- Les connexions de signaux aux slots ne se font plus comme tu les fait depuis ... 7 ans :p

          5- Tu essaies de connecter des signaux aux slots donneesRecues et deconnexionClient, mais les dits slots n'existent pas... Cherchez l'erreur

          6- heuu... à quoi sert ton semaphore dans main????

          7- Dans main, tu essaye d'utiliser la classe ServeurLogin, mais tu nous montre la classe Serveur...  Ce n'est sans doute qu'une erreur d'attention lorsque tu as rédigé ce message, mais... y a un os, tu crois pas???

          • Partager sur Facebook
          • Partager sur Twitter
          Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
            9 septembre 2018 à 11:21:24

            salut désole du temps ,

            1)

            Je sais que c'est le code que le "cours"

            désole mais ratée sait le code propose par QT . Pour ma par je dev avec QT 5.11.1 (j'utilise des méthodes propre a set version plus loin dans le programme ) .

            tu dit que mon code n'est pas propre (C'est vrai mais c'était pour simplifier ) et si on chipote "server" doit être un pointeur intelligent .

            std::string tableau {'t','a','b','e','a','u'};
            std::string tableau2 {"tableau"};
            int variable(10);
            std::vector <int> liste {10,20,12,10};

            3) tu a raison , mais je suis un peut contre le fait d'arrêter le programme si il y a une erreur . j'ai crée une autre fonction pour le démarrage serveur .

            4) je ne sait pas mais comment faire alors ?

            5) "j'ai crée le code sur windows est tout allez bien" donc si les signals existe bien .

            6) sait pour simuler que le thread principal exécute autre chose .

            7) bien vue .

            koala01 tu parle pour rien dire (propreté du code ,pour ton petit 4 peut tu donnée un exemple ? ) a la fin de ton message j'ai plus l'impression que tu a voulue monter tes compétences que de m'aider .

            j'ai trouvé la solution si ça intersecte quelqu'un  

            serveur->waitForNewConnection(-1);
            • Partager sur Facebook
            • Partager sur Twitter
              9 septembre 2018 à 13:38:14

              di20 a écrit:


              std::string tableau {'t','a','b','e','a','u'};
              std::string tableau2 {"tableau"};
              int variable(10);
              std::vector <int> liste {10,20,12,10};

              Qu'essaye tu de montrer avec ce code, dont la première ligne est totalement fausse ?

              Après vérification, il semblerait qu'elle soit "légale", mais fais attention au fait que std::string n'est pas "un simple tableau de char. Ce serait trop facile!!!

              Un char, par nature, c'est une valeur numérique, pour laquelle il existe une table d'équivalence qui fournit un glyphe à afficher (les chiffres, les lettres et autres symboles) et dont une partie (les valeurs comprises entre 0 et 31 inclus) ne sont pas affichables, mais correspondent à des "instructions" que l'on pouvait transmettre

              3) tu a raison , mais je suis un peut contre le fait d'arrêter le programme si il y a une erreur . j'ai crée une autre fonction pour le démarrage serveur .

              A vrai dire, il se peut que tu aies la possibilité de récupérer l'erreur (mais sûrement pas à l'endroit où elle survient :P) et je ne t'interdirai jamais d'essayer de récupérer une exception quelque part si tu sais que c'est l'endroit où tu pourras corriger le problème qui l'a provoquée, mais... tu n'auras pas le choix:

              Si ton application dispose, pour une raison ou une autre, d'une donnée "aberrante", il y a deux solutions:

              • Si tu as de la chance, ton application plantera
              • si tu n'as pas de chance, ton application continuera à travailler (parfois pendant longtemps) et te renverra un résultat totalement aberrant, que, du fait de sa complexité, tu ne rendra même pas compte qu'il est erroné

              Il y a donc deux situations possibles quand une fonction obtient une valeur incorrecte (par exemple : tu envoies la valeur 11 alors que tu attends une valeur comprise entre 1 et 10):

              • Soit le problème vient de la personne qui appelle la fonction et qui n'a pas testé suffisamment la valeur pour s'assurer qu'elle "entrait dans les clous" : il faut alors faire planter l'application en utilisant les assertions
              • Soit le problème vient de "de l'extérieur de l'application" (d'un fichier, d'un serveur, ou d'une sonde par exemple) et tu ne pourras rien y faire, hormis demander à "celui qui te fourni" la donnée de la corriger. Tu devras donc lancer une une exception pour garantir la sécurité de ton application

              4) je ne sait pas mais comment faire alors ?

               Allez, un exemple "simple":

              QAction * action=new QAction;
              QPushButton * button = new QPushButton("Ok");
              connect(action, &QAction::triggered, button, &QPushButton::clic);

              di20 a écrit:

              5) "j'ai crée le code sur windows est tout allez bien" donc si les signals existe bien .

              Je n'ai pas dit le contraire, j'ai dit qu'il n'apparaissaient pas dans le code que tu nous présentais

              A de très rares exceptions près, tu dois t'habituer à fournir ce que l'on appelle un "code minimum compilable" qui présente ton problème sur le forume, pour "aider les gens à t'aider".

              C'est à dire un code

              1. dont on a supprimé "tous les détails sans importance"
              2. mais que l'on peut -- malgré tout -- copier de notre coté afin de le compiler
              3. qui reproduit le problème auquel tu es confronté

              Tel qu'il est là, ton code ne respecte pas le (2), et ne peut donc pas respecter le (3)...

              Dis toi bien que nous n'étions pas au dessus de ton épaule lorsque tu as écrit le code.  Nous n'avons donc aucun moyen de savoir quelles étaient tes intentions lorsque tu l'as fait.  Et nous n'avons peut-être même jamais lu le cours ou le tutoriel sur lequel tu te base (ou il y a si longtemps que tu ne dois pas t'attendre à ce que nous nous souvenions du code présenté)

              La seule source d'informations fiable -- celle qui nous indique ce qui est fait et non ce que tu as voulu faire-- c'est donc le code.  Te rends tu compte de la situation dans laquelle tu nous mets lorsque ton code ne compile pas?

              di20 a écrit:

              5) "j'ai crée le code sur windows est tout allez bien" donc si les signals existe bien .

              Quand je lis cela, j'ai peur...

              Parce que le corollaire à "tout allait assez bien", c'est "mais ca plantait malgré tout parfois" ou "mais ca faisait parfois n'importe quoi"

              Or, un code qui "fonctionne seulement parfois", c'est un code incorrect "par nature", et donc, un code qui doit être corrigé

              di20 a écrit:

              6) sait pour simuler que le thread principal exécute autre chose .

              Ton thread principal n'a absolument rien à faire d'autre que de maintenir le serveur en place

              • Partager sur Facebook
              • Partager sur Twitter
              Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait

              QT + debian

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
              • Editeur
              • Markdown