Servidor de Threaded Fortune
El ejemplo Servidor de Fortune con Hilos muestra cómo crear un servidor para un servicio de red simple que utiliza hilos para manejar peticiones de diferentes clientes. Está pensado para ejecutarse junto con el ejemplo Cliente Fortune.

La implementación de este ejemplo es similar a la del ejemplo del Servidor Fortune, pero aquí implementaremos una subclase de QTcpServer que inicie cada conexión en un hilo diferente.
Para ello necesitamos dos clases: FortuneServer, una subclase de QTcpServer, y FortuneThread, que hereda de QThread.
class FortuneServer : public QTcpServer { Q_OBJECT public: FortuneServer(QObject *parent = nullptr); protected: void incomingConnection(qintptr socketDescriptor) override; private: QStringList fortunes; };
FortuneServer hereda QTcpServer y reimplementa QTcpServer::incomingConnection(). También lo utilizamos para almacenar la lista de fortunas aleatorias.
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."); }
Utilizamos el constructor de FortuneServer para generar simplemente la lista de fortunas.
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(); }
Nuestra implementación de QTcpServer::incomingConnection() crea un objeto FortuneThread, pasando el descriptor del socket entrante y una fortuna aleatoria al constructor de FortuneThread. Conectando la señal finished() de FortuneThread a QObject::deleteLater(), nos aseguramos de que el hilo se elimina una vez que ha terminado. Entonces podemos llamar a QThread::start(), que inicia el hilo.
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; };
Pasando a la clase FortuneThread, esta es una subclase de QThread cuyo trabajo es escribir la fortuna al socket conectado. La clase reimplementa QThread::run(), y tiene una señal para informar de errores.
FortuneThread::FortuneThread(qintptr socketDescriptor, const QString &fortune, QObject *parent) : QThread(parent), socketDescriptor(socketDescriptor), text(fortune) { }
El constructor de FortuneThread simplemente almacena el descriptor del socket y el texto de la fortuna, para que estén disponibles para run() más tarde.
void FortuneThread::run() { QTcpSocket tcpSocket;
Lo primero que hace nuestra función run() es crear un objeto QTcpSocket en la pila. Lo que vale la pena notar es que estamos creando este objeto dentro del hilo, lo que automáticamente asocia el socket al bucle de eventos del hilo. Esto asegura que Qt no intentará enviar eventos a nuestro socket desde el hilo principal mientras estamos accediendo a él desde FortuneThread::run().
if (!tcpSocket.setSocketDescriptor(socketDescriptor)) { emit error(tcpSocket.error()); return; }
El socket se inicializa llamando a QTcpSocket::setSocketDescriptor(), pasando nuestro descriptor de socket como argumento. Esperamos que esto tenga éxito, pero sólo para estar seguros, (aunque poco probable, el sistema puede quedarse sin recursos,) capturamos el valor de retorno e informamos de cualquier error.
QByteArray block; QDataStream out(&block, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_6_5); out << text;
Como en el ejemplo del Servidor de Fortunas, codificamos la fortuna en un QByteArray usando QDataStream.
tcpSocket.write(block); tcpSocket.disconnectFromHost(); tcpSocket.waitForDisconnected(); }
Pero a diferencia del ejemplo anterior, terminamos llamando a QTcpSocket::waitForDisconnected(), que bloquea el hilo llamante hasta que el socket se haya desconectado. Como estamos ejecutando en un hilo separado, la GUI seguirá respondiendo.
Vea también Servidor Fortune, Cliente Fortune y Cliente Fortune bloqueante.
© 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.