Problème de gestion des threads après connexions multiples sur un serveur
Salut à tous! En ce moment je pars sur un projet de repartition de charge de plusieurs serveurs. J'essaie pour l'instant de simuler plusieurs connexions simultanées de clients sur un serveur en local grâce à des threads lancés en parallèle. Chaque thread se connecte sur le serveur, la dessus y'a aucun souci puisque le serveur reçoit bien le signal newConnection de chacun des threads. En revanche je n'arrive pas à ce que chaque thread transmette simultanément une info au serveur (signal ReadyRead) après avoir établit la connexion. Si par exemple, je lance 10 threads, il vont tous ce connecter sur le serveur mais un seul thread transmettra une information sur la socket. En telnet je n'ai pas ce souci la. Je vous laisse le codage.
//serveur.cpp
Code:
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
| #include "serveur.h"
#include "ui_serveur.h"
serveur::serveur(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::serveur)
{
ui->setupUi(this);
connect(ui->pushButtonEcouter, SIGNAL(clicked()),this, SLOT(ecouter()));
connect(ui->pushButtonNePlusEcouter,SIGNAL(clicked()),this, SLOT(nePlusEcouter()));
connect(ui->pushButtonRazCompteur,SIGNAL(clicked()),this,SLOT(razCompteur()));
connect(ui->pushButtonInfosClients,SIGNAL(clicked()),this,SLOT(effacerZoneClients()));
connect(ui->pushButtonMessagesClients,SIGNAL(clicked()),this,SLOT(effacerZoneMessages()));
ui->lineEditPort->setText("20001");
ui->pushButtonNePlusEcouter->setDisabled(true);
ui->lineEditNbClients->setText("0");
}
serveur::~serveur()
{
delete ui;
}
void serveur::changeEvent(QEvent *e)
{
QMainWindow::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}
void serveur::ecouter(){
//on recupere le numero de port du serveur
QString sPort = ui->lineEditPort->text();
//conversion de ce port en un entier
int port = sPort.toInt();
//initialisation d'une socket de type serveur
_socketServeurEcoute = new QTcpServer;
_socketClient = new QTcpSocket;
//on ecoute a present toutes adresses IP qui utilisent le port predefinit par le serveur
if(_socketServeurEcoute->listen(QHostAddress::Any, port)==true){
qDebug()<<" je suis a l'ecoute";
//on ouvre la socket d'ecoute afin d'attendre qu'un client puisse se connecter sur le serveur
connect(_socketServeurEcoute, SIGNAL(newConnection()),this, SLOT(nouvelleConnexion()));
ui->pushButtonEcouter->setDisabled(true);
ui->pushButtonNePlusEcouter->setDisabled(false);
}
else qDebug() << "probleme d'ecoute";
}
void serveur::nePlusEcouter(){
qDebug() << "ne plus ecouter";
ui->pushButtonNePlusEcouter->setDisabled(true);
ui->pushButtonEcouter->setDisabled(false);
_socketServeurEcoute->close();
//on detruit la socket d'ecoute
delete(_socketServeurEcoute);
this->razCompteur();
this->effacerZoneClients();
this->effacerZoneMessages();
}
void serveur::nouvelleConnexion(){
//le serveur ajoute un nouveau client
_socketClient = _socketServeurEcoute->nextPendingConnection();
//on recupere l'adresse IP de ce nouveau client
QHostAddress peer = _socketClient->peerAddress();
//on recupere le nombre de clients avant cette nouvelle connexion
QString sNbClientsAvant = ui->lineEditNbClients->text();
//conversion de ce port en un entier
int nbClientsActuel;
QString sNbClientsActuel;
nbClientsActuel = sNbClientsAvant.toInt() + 1;
sNbClientsActuel.setNum(nbClientsActuel);
ui->lineEditNbClients->setText(sNbClientsActuel);
ui->plainTextEditInfos->appendPlainText("IP : "+ peer.toString() + " | numero : " + sNbClientsActuel);
//ce slot va detecter que des donnees ont ete transmises de la part du client
connect(_socketClient,SIGNAL(readyRead()),this, SLOT(recevoir()));
}
void serveur::razCompteur(){
ui->lineEditNbClients->setText("0");
}
void serveur::effacerZoneClients(){
ui->plainTextEditInfos->setPlainText("");
}
void serveur::effacerZoneMessages(){
ui->plainTextEditMessagesClients->setPlainText("");
}
void serveur::recevoir(){
qDebug()<< " signal readyRead Recu";
//lecture de la socket du client
QByteArray reponse = _socketClient->readAll();
QString sRep(reponse);
if (sRep == ""){
ui->plainTextEditMessagesClients->appendPlainText("Erreur de reception");
}
else {
ui->plainTextEditMessagesClients->appendPlainText(sRep);
}
QString message = "reponse du serveur : ";
message += sRep;
QTextStream socketStream(_socketClient);
socketStream << message << endl;
} |
//serveur.h
Code:
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
|
#ifndef SERVEUR_H
#define SERVEUR_H
#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>
#include <QHostAddress>
#include <QDebug>
#include <QByteArray>
#include "QThread"
#include "threadServeur.h"
namespace Ui {
class serveur;
}
class serveur : public QMainWindow{
Q_OBJECT
public:
serveur(QWidget *parent = 0);
~serveur();
protected:
void changeEvent(QEvent *e);
private:
Ui::serveur *ui;
QTcpServer *_socketServeurEcoute;
QTcpSocket *_socketClient;
ThreadServeur * _threadServeur;
private slots:
void ecouter();
void nePlusEcouter();
void nouvelleConnexion();
void recevoir();
void effacerZoneClients();
void razCompteur();
void effacerZoneMessages();
};
#endif // SERVEUR_H |
//clients.cpp
Code:
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
| #include "clients.h"
#include "ui_clients.h"
clients::clients(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::clients)
{
ui->setupUi(this);
ui->lineEditHost->setText("127.0.0.1");
ui->lineEditPort->setText("20001");
connect(ui->pushButtonAjoutClients,SIGNAL(clicked()),this, SLOT(ajoutClients()));
}
clients::~clients()
{
delete ui;
}
void clients::changeEvent(QEvent *e)
{
QMainWindow::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}
void clients::ajoutClients(){
//recuperation de l'adresse IP dans l'IHM
host= ui->lineEditHost->text();
//recuperation du numero de port dans l'IHM
port= (ui->lineEditPort->text()).toInt();
//on se connecte a cette adresse IP ainsi que son numero de port grace a la socket
for(int i=0;i<10;i++){
_threadClients = new ThreadClients(host,port);
_threadClients->run();
usleep(10000);
}
} |
//clients.h
Code:
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
|
#ifndef CLIENTS_H
#define CLIENTS_H
#include <QMainWindow>
#include <QHostAddress>
#include <QDebug>
#include <QTextStream>
#include "threadClients.h"
namespace Ui {
class clients;
}
class clients : public QMainWindow{
Q_OBJECT
public:
clients(QWidget *parent = 0);
~clients();
protected:
void changeEvent(QEvent *e);
private:
Ui::clients *ui;
ThreadClients *_threadClients;
QString host;
int port;
private slots:
void ajoutClients();
};
#endif // CLIENTS_H |
//threadClients.cpp
Code:
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
| #include "threadClients.h"
ThreadClients::ThreadClients(QString host,int port){
_host = host;
_port = port;
}
ThreadClients::~ThreadClients(){
}
void ThreadClients::run()
{
_socket = new QTcpSocket;
_socket->connectToHost(_host,_port);
if(_socket->waitForConnected(1000))
{
QTextStream socketStream(_socket);
QString message = "messageClient";
qDebug() << message;
socketStream << message << endl;
}
else
{
qDebug() << "hs";
}
} |
//threadClients.h
Code:
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
| #ifndef THREADCLIENTS_H
#define THREADCLIENTS_H
#include <QThread>
#include <QDebug>
#include <QTcpServer>
#include <QTcpSocket>
#include <QTextStream>
class ThreadClients : public QThread
{
private:
QString _host;
int _port;
public:
ThreadClients(QString,int);
~ThreadClients();
void run();
QTcpSocket * _socket;
};
#endif // THREADCLIENTS_H |