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

Multithreading Discussion :

Serveur multithread


Sujet :

Multithreading

  1. #1
    Membre averti
    Inscrit en
    Février 2008
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 42
    Par défaut Serveur multithread
    Je suis debutant en QT, Je veux réalisé un un serveur qui communique avec plusieurs clients.. alors j'ai pensé a crée a chaque nouvelle connexion de client un thread qui se charge de la communication avec ce client via les Qsoket..{il reste en execution jusqu'a la fin de communication)

    Le probleme est que je n'arrive pas a connecté le thread_serveur au GUI, pour afficher les information envoyées par le client.. comment je peut le faire avec signal/slot????
    ou y-a t'il un autre moyen???

    sachant que mon serveur est une instance d'une class Serveur qui hérite de QtcpServer..

    akors j'ai:

    un interface graphique,
    class Serveur: lance un thread serveur a chaque connexion
    class thread serveur ????????
    comment je peut realisé la communication entre eux???
    et merci d'avance...

  2. #2
    Membre Expert

    Avatar de IrmatDen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 727
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 727
    Par défaut
    Salut,

    Pas besoin de threading pour ça, à moins de devoir gérer des centaines de clients qui génère beaucoup de traffic. Les classes réseau de Qt fonctionne toutes de façon asynchrones, et ça marche très bien, donc tu peux très probablement simplifier en supprimant le threading

  3. #3
    Membre averti
    Inscrit en
    Février 2008
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 42
    Par défaut
    mai si les client veut tous modifier le meme element dans l'interface ,une image, comment le serveur peut géré ca?? qui va etre servi?? et normalement le dernier qui a modifier l'image sa demande sera exécuté.. et non déféré..
    ???

  4. #4
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Salut et bienvenue sur le forum
    Citation Envoyé par billy242 Voir le message
    mai si les client veut tous modifier le meme element dans l'interface ,une image, comment le serveur peut géré ca?? qui va etre servi?? et normalement le dernier qui a modifier l'image sa demande sera exécuté.. et non déféré..
    ???
    Peut expliquer un peu plus ce que tu veut faire? voir même un schémat?
    Quelles actions est sensées faire tes threads?

  5. #5
    Membre averti
    Inscrit en
    Février 2008
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 42
    Par défaut
    Salut,

    J'ai un interface graphique, avec 2 images superposé non visible au départ,
    normalement l'interface graphique fait une instance d'un objet serveur, qui se charge de l'ecoute sur un port des nouvelles connexions possibles, si un client donnée est connecté, il envoie une demande d'affichage d'une image parmis les deux.. elle reste visible pendant 5s(avec un Qtimer)
    le pb si un autre client fait une demande pendant ces 5s, sa demande ne s'execute pas..et je veux toujours que la demande la plus récente sera exécuté..

  6. #6
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par billy242 Voir le message
    le pb si un autre client fait une demande pendant ces 5s, sa demande ne s'execute pas..
    Pourquoi elle ne s'exécute pas? En quoi afficher une image va bloquer le reste?
    Vue ce que je comprend, je rejoins l'avis d'IrmatDen, pas vraiment besoin de thread ici.
    Mais j'ai pas vraiment compris ce que tu veut faire au final ...

  7. #7
    Membre averti
    Inscrit en
    Février 2008
    Messages
    42
    Détails du profil
    Informations forums :
    Inscription : Février 2008
    Messages : 42
    Par défaut
    j'ai éliminé pour le moment l'histoire des threads:
    alor j'ai un serveur qui traite tous:

    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
     
    #ifndef SERVEUR_H
    #define SERVEUR_H
     
    #include <QtGui/QMainWindow>
    #include <QtNetwork>
     
     
    namespace Ui
    {
        class serveurClass;
    }
     
    class serveur : public QMainWindow
    {
        Q_OBJECT
     
    public:
        serveur(QWidget *parent = 0);
        ~serveur();
        void envoyerOrdre(const QString &ordre);
        void eneEcoute();
     
    private slots:
            void on_stop_Button_clicked();
            void on_start_Button_clicked();
            void on_listen_Button_clicked();
     
           void nouvelleConnexion();
           void donneesRecues();
           void deconnexionClient();
     
    private:
        Ui::serveurClass *ui;
        QTcpServer *server;
        QList<QTcpSocket *> clients;
        quint16 tailleMessage;
    };
     
    #endif // SERVEUR_H
    srveur.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
     
    #include "serveur.h"
    #include "ui_serveur.h"
     
    serveur::serveur(QWidget *parent)
        : QMainWindow(parent), ui(new Ui::serveurClass)
    {
        ui->setupUi(this);
        // Creation du serveur
          server = new QTcpServer(this);
    }
     
    serveur::~serveur()
    {
        delete ui;
    }
     
    void serveur::on_listen_Button_clicked()
    {
      this->eneEcoute();
     
    }
     
     
    void serveur::on_start_Button_clicked()
    {
       envoyerOrdre(tr("START"));
    }
     
    void serveur::on_stop_Button_clicked()
    {
      envoyerOrdre(tr("STOP"));
    }
     
     
     
    void serveur::eneEcoute(){
     
     
        QString port;
        port=ui->port_Edit->text();
        tailleMessage = 0;
     
     
        if (!server->isListening()){
        // Démarrage du serveur sur toutes les IP disponibles et sur le port donné
        if(!server->listen(QHostAddress::Any,port.toInt()))
        {
            // Si le serveur n'a pas été démarré correctement
             ui->statusBar->showMessage(tr("Le serveur n'a pas pu etre demarre. Raison :") + server->errorString());
             close();
             return;
        }
        else
        {
            // Si le serveur a été démarré correctement
            ui->statusBar->showMessage(tr("Le serveur est a l'excoute sur le port ") + QString::number(server->serverPort()) + tr(".Des clients peuvent maintenant se connecter."));
            connect(server, SIGNAL(newConnection()), this, SLOT(nouvelleConnexion()));
     
        }
     }
        else
         ui->statusBar->showMessage(tr("Le serveur est deja mis a l'ecoute sur le port ") + QString::number(server->serverPort()) + tr(".Des clients peuvent maintenant se connecter."));
     
     
     
    }
     
    void serveur::nouvelleConnexion()
    {
     
        QTcpSocket *nouveauClient = server->nextPendingConnection();
        clients << nouveauClient;
     
        connect(nouveauClient, SIGNAL(readyRead()), this, SLOT(donneesRecues()));
        connect(nouveauClient, SIGNAL(disconnected()), this, SLOT(deconnexionClient()));
    }
    void serveur::donneesRecues()
    {
        // 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
        }
     
        // 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;
     
     
        // 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;
     
        /**************************************************/
        /* mise a jours d'etat de flech; ici le pb: si je veut que le flech(image) reste afficher 5s et pendant ces 5s si un autre client veut changer le fleche, sa demade doit etre executé .... avec un Qtimer sa demade ne sera pas vue?????*/
        /**************************************************/
     
        ui->statusBar->showMessage(message);
        if(message.contains("droit",Qt::CaseInsensitive)){
     
         ui->flech_d->setPixmap(QPixmap(QString::fromUtf8("images/fleche_d1.png")));
     
     
        }
        if(message.contains("gauche",Qt::CaseInsensitive)){
     
       ui->flech_g->setPixmap(QPixmap(QString::fromUtf8("images/fleche_g1.png")));
     
     
        }
     
     
     
        //  remise de la taille du message à 0 pour permettre la réception des futurs messages
        tailleMessage = 0;
    }
     
    void serveur::deconnexionClient()
    {
     
        // 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();
    }
     
    void serveur::envoyerOrdre(const QString &message)
    {
        // Préparation du paquet
        QByteArray paquet;
        QDataStream out(&paquet, QIODevice::WriteOnly);
     
        out << (quint16) 0; // On écrit 0 au début du paquet pour réserver la place pour écrire la taille
        out << message; // On ajoute le message à la suite
        out.device()->seek(0); // OdeconnexionClientn se replace au début du paquet
        out << (quint16) (paquet.size() - sizeof(quint16)); // On écrase le 0 qu'on avait réservé par la longueur du message
     
     
        // Envoi du paquet préparé à tous les clients connectés au serveur
        for (int i = 0; i < clients.size(); i++)
        {
            clients[i]->write(paquet);
        }
     
    }
    mise a jours d'etat de flech: si je veut que le flech(c'est une image dans une Label) reste afficher 5s et pendant ces 5s si un autre client veut changer le fleche, sa demade doit etre executé .... avec un Qtimer sa demade ne sera pas vue?????*/

Discussions similaires

  1. Arrêt d'un serveur multithread
    Par bambou dans le forum Entrée/Sortie
    Réponses: 7
    Dernier message: 07/07/2010, 16h04
  2. conception serveur multithread
    Par nivose110 dans le forum Réseau
    Réponses: 12
    Dernier message: 17/07/2006, 16h43
  3. Question Serveur Multithread
    Par Mr_Chut dans le forum Réseau
    Réponses: 10
    Dernier message: 09/06/2006, 17h27
  4. Réponses: 5
    Dernier message: 11/01/2006, 07h58

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