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);
}
} |