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 :

Bonne utilisation de QTcpServer et QTcpSocket pour plusieurs ports


Sujet :

Réseau

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2012
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2012
    Messages : 25
    Points : 24
    Points
    24
    Par défaut Bonne utilisation de QTcpServer et QTcpSocket pour plusieurs ports
    Bonjour,
    J'ai quelques doutes à propos de la bonne utilisation de QTcpServer:
    J'ai besoin d'écouter les connexions entrantes sur deux ports différents.
    Le meilleur moyen d'y parvenir est il d'instancier deux QTcpServer?

    Concernant les QTcpSocket, voici mon code:

    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
     
    void CapIniFileHandler::handleReceptionConnection(){
        if(mp_tcpSocket != NULL) {
            qDebug() << "Une connexion est deja en cours";
            return;
        }
        mp_tcpSocket = mp_tcpReceptionServer.nextPendingConnection();
        if(mp_tcpSocket == NULL) {
            qDebug() << "*** pas de connexion";
            return;
        }
        connect(mp_tcpSocket, SIGNAL(disconnected()),
                this, SLOT(closeSocket()));
        connect(mp_tcpSocket, SIGNAL(readyRead()),
                this, SLOT(getConfigFile()));
    }
    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
     
    bool CapIniFileHandler::getConfigFile(){
        char *l_rawData = new char[MAX_PACKET_SIZE];
        qDebug() << "*** get connection file";
        if(!mp_configFile.open(QIODevice::WriteOnly)) {return false;}
     
        qint64 l_size = mp_tcpSocket->read(l_rawData, MAX_PACKET_SIZE);
        while(l_size != 0){
            if(l_size == -1) {return false;}
            qDebug() << l_rawData;
            if(mp_configFile.write(l_rawData, l_size) != l_size) {return false;}
            l_size = mp_tcpSocket->read(l_rawData, MAX_PACKET_SIZE);
        }
        mp_configFile.flush();
        mp_configFile.close();
        delete l_rawData;
     
        return true;
    }
    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 CapIniFileHandler::closeSocket(){
        if(mp_tcpSocket != NULL){
            qDebug() << "closing the socket";
            mp_tcpSocket->flush();
            this->disconnect(mp_tcpSocket);
            disconnect(mp_tcpSocket, SIGNAL(disconnected()),
                    this, SLOT(closeSocket()));
            disconnect(mp_tcpSocket, SIGNAL(readyRead()),
                    this, SLOT(getConfigFile()));
            mp_tcpSocket->close();
            delete mp_tcpSocket;
            mp_tcpSocket = NULL;
        }
    }
    Ce code fonctionne bien pour une connexion, je peux envoyer mes données, les enregistrer dans un fichier, puis déconnecter le socket.
    Mais j'ai une erreur de segmentation si j'essaie de répéter la manœuvre.
    Impossible de choper l'erreur au debugger, j'ai l'impression qu'elle survient avec des résidus de connexion signaux/slots.
    Est ce que c'est une bête erreur de programmation, ou alors la manière d'utiliser les sockets n'est pas la bonne?
    Merci pour l'aide!

  2. #2
    Responsable Qt & Livres


    Avatar de dourouc05
    Homme Profil pro
    Ingénieur de recherche
    Inscrit en
    Août 2008
    Messages
    26 619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur de recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2008
    Messages : 26 619
    Points : 188 594
    Points
    188 594
    Par défaut


    Une instance serveur ne peut écouter que sur un seul port (et tenter de faire autre chose donne rapidement des erreurs de segmentation, avec une petite recherche Google). La seule option est de créer une instance de QTcpServer par port à écouter.
    Vous souhaitez participer aux rubriques Qt (tutoriels, FAQ, traductions) ou HPC ? Contactez-moi par MP.

    Créer des applications graphiques en Python avec PyQt5
    Créer des applications avec Qt 5.

    Pas de question d'ordre technique par MP !

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2012
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2012
    Messages : 25
    Points : 24
    Points
    24
    Par défaut
    Merci pour ta réponse rapide!

    Est-il possible d'utiliser une seule boucle d'événement pour deux instances? Ou je dois les placer dans des threads différents?

    Ma seconde question concernant les sockets reste valable, j'obtiens ce bug en écoutant sur un seul port.
    Quelques précisions sur le problème:
    Si je modifie ma méthode closeSocket() de cette façon:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    void CapIniFileHandler::closeSocket(){
            mp_tcpSocket = NULL;
    }
    Je peux répéter la réception de fichier autant de fois que je le souhaite (évidement j'ai bien conscience que la mémoire n'est pas libérée).

    En revanche si j'écris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    void CapIniFileHandler::closeSocket(){
            delete mp_tcpSocket;
    }
    J'obtiens une erreur de segmentation lors de la deuxième tentative de connexion au serveur.
    Il y aurait donc des mécanismes qui me sont inconnus qui utilisent le pointeur vers le mp_tcpSocket, même après sa suppression?
    Ou alors le delete a d'autres effets que simplement la libération de la mémoire?

    Toute aide sera la bienvenue

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2012
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2012
    Messages : 25
    Points : 24
    Points
    24
    Par défaut
    Ouch, j'ai enfin trouvé la solution.
    Si ça peut intéresser quelqu'un: il ne faut pas utiliser delete pour supprimer un objet dans un slot appelé directement ou indirectement par cet objet.
    Il faut utiliser deleteLater() à la place:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    mp_tcpSocket->deleteLater();

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

Discussions similaires

  1. Utiliser une animation en Resources pour plusieurs TargetName
    Par marcusien dans le forum Windows Presentation Foundation
    Réponses: 0
    Dernier message: 27/03/2012, 10h29
  2. Réponses: 2
    Dernier message: 04/05/2011, 14h55
  3. Réponses: 3
    Dernier message: 12/02/2009, 15h44
  4. Réponses: 4
    Dernier message: 27/02/2008, 12h48
  5. Comment utiliser la meme table pour plusieurs formulaires
    Par pacodelareunion dans le forum Access
    Réponses: 5
    Dernier message: 26/10/2005, 15h17

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