Serveur Threaded Fortune
L'exemple Threaded Fortune Server montre comment créer un serveur pour un service réseau simple qui utilise des threads pour traiter les demandes de différents clients. Il est destiné à être exécuté en même temps que l'exemple Fortune Client.

L'implémentation de cet exemple est similaire à celle de l'exemple Fortune Server, mais ici nous allons implémenter une sous-classe de QTcpServer qui démarre chaque connexion dans un thread différent.
Pour ce faire, nous avons besoin de deux classes : FortuneServer, une sous-classe de QTcpServer, et FortuneThread, qui hérite de QThread.
class FortuneServer : public QTcpServer { Q_OBJECT public: FortuneServer(QObject *parent = nullptr); protected: void incomingConnection(qintptr socketDescriptor) override; private: QStringList fortunes; };
FortuneServer hérite de QTcpServer et réimplémente QTcpServer::incomingConnection(). Nous l'utilisons également pour stocker la liste des fortunes aléatoires.
FortuneServer::FortuneServer(QObject *parent) : QTcpServer(parent) { fortunes << tr("You've been leading a dog's life. Stay off the furniture.") << tr("You've got to think about tomorrow.") << tr("You will be surprised by a loud noise.") << tr("You will feel hungry again in another hour.") << tr("You might have mail.") << tr("You cannot kill time without injuring eternity.") << tr("Computers are not intelligent. They only think they are."); }
Nous utilisons le constructeur de FortuneServer pour générer simplement la liste des fortunes.
void FortuneServer::incomingConnection(qintptr socketDescriptor) { QString fortune = fortunes.at(QRandomGenerator::global()->bounded(fortunes.size())); FortuneThread *thread = new FortuneThread(socketDescriptor, fortune, this); connect(thread, &FortuneThread::finished, thread, &FortuneThread::deleteLater); thread->start(); }
Notre implémentation de QTcpServer::incomingConnection() crée un objet FortuneThread, en transmettant le descripteur de socket entrant et une fortune aléatoire au constructeur de FortuneThread. En connectant le signal finished() de FortuneThread à QObject::deleteLater(), nous nous assurons que le thread est supprimé une fois qu'il est terminé. Nous pouvons alors appeler QThread::start(), qui démarre le thread.
class FortuneThread : public QThread { Q_OBJECT public: FortuneThread(qintptr socketDescriptor, const QString &fortune, QObject *parent); void run() override; signals: void error(QTcpSocket::SocketError socketError); private: qintptr socketDescriptor; QString text; };
Passons maintenant à la classe FortuneThread, une sous-classe de QThread dont le rôle est d'écrire la fortune sur le socket connecté. La classe réimplémente QThread::run() et dispose d'un signal pour signaler les erreurs.
FortuneThread::FortuneThread(qintptr socketDescriptor, const QString &fortune, QObject *parent) : QThread(parent), socketDescriptor(socketDescriptor), text(fortune) { }
Le constructeur de FortuneThread stocke simplement le descripteur de socket et le texte de la fortune, afin qu'ils soient disponibles pour la fonction run() plus tard.
void FortuneThread::run() { QTcpSocket tcpSocket;
La première chose que fait notre fonction run() est de créer un objet QTcpSocket sur la pile. Il est intéressant de noter que nous créons cet objet à l'intérieur du thread, ce qui associe automatiquement la socket à la boucle d'événements du thread. Cela garantit que Qt n'essaiera pas de fournir des événements à notre socket à partir du thread principal alors que nous y accédons à partir de FortuneThread::run().
if (!tcpSocket.setSocketDescriptor(socketDescriptor)) { emit error(tcpSocket.error()); return; }
La socket est initialisée en appelant QTcpSocket::setSocketDescriptor(), en passant notre descripteur de socket comme argument. Nous nous attendons à ce que l'opération réussisse, mais pour être sûrs (bien que cela soit peu probable, le système peut manquer de ressources), nous enregistrons la valeur de retour et signalons toute erreur.
QByteArray block; QDataStream out(&block, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_6_5); out << text;
Comme dans l'exemple du serveur de fortune, nous encodons la fortune dans un QByteArray à l'aide de QDataStream.
tcpSocket.write(block); tcpSocket.disconnectFromHost(); tcpSocket.waitForDisconnected(); }
Mais contrairement à l'exemple précédent, nous terminons en appelant QTcpSocket::waitForDisconnected(), qui bloque le thread appelant jusqu'à ce que le socket soit déconnecté. Comme nous fonctionnons dans un thread séparé, l'interface graphique reste réactive.
Voir aussi Serveur Fortune, Client Fortune, et Client Fortune bloquant.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.