Threaded Fortune Server Example▲

The implementation of this example is similar to that of the Fortune Server example, but here we will implement a subclass of QTcpServer that starts each connection in a different thread.
For this we need two classes: FortuneServer, a QTcpServer subclass, and FortuneThread, which inherits QThread.
class
FortuneServer : public
QTcpServer
{
Q_OBJECT
public
:
FortuneServer(QObject *
parent =
0
);
protected
:
void
incomingConnection(qintptr socketDescriptor) override
;
private
:
QStringList fortunes;
}
;
FortuneServer inherits QTcpServer and reimplements QTcpServer::incomingConnection(). We also use it for storing the list of random fortunes.
FortuneServer::
FortuneServer(QObject *
parent)
:
QTcpServer(parent)
{
fortunes &
lt;&
lt; tr("You've been leading a dog's life. Stay off the furniture."
)
&
lt;&
lt; tr("You've got to think about tomorrow."
)
&
lt;&
lt; tr("You will be surprised by a loud noise."
)
&
lt;&
lt; tr("You will feel hungry again in another hour."
)
&
lt;&
lt; tr("You might have mail."
)
&
lt;&
lt; tr("You cannot kill time without injuring eternity."
)
&
lt;&
lt; tr("Computers are not intelligent. They only think they are."
);
}
We use FortuneServer's constructor to simply generate the list of fortunes.
void
FortuneServer::
incomingConnection(qintptr socketDescriptor)
{
QString fortune =
fortunes.at(QRandomGenerator::
global()-&
gt;bounded(fortunes.size()));
FortuneThread *
thread =
new
FortuneThread(socketDescriptor, fortune, this
);
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread-&
gt;start();
}
Our implementation of QTcpServer::incomingConnection() creates a FortuneThread object, passing the incoming socket descriptor and a random fortune to FortuneThread's constructor. By connecting FortuneThread's finished() signal to QObject::deleteLater(), we ensure that the thread gets deleted once it has finished. We can then call QThread::start(), which starts the thread.
class
FortuneThread : public
QThread
{
Q_OBJECT
public
:
FortuneThread(int
socketDescriptor, const
QString &
amp;fortune, QObject *
parent);
void
run() override
;
signals
:
void
error(QTcpSocket::
SocketError socketError);
private
:
int
socketDescriptor;
QString text;
}
;
Moving on to the FortuneThread class, this is a QThread subclass whose job is to write the fortune to the connected socket. The class reimplements QThread::run(), and it has a signal for reporting errors.
FortuneThread::
FortuneThread(int
socketDescriptor, const
QString &
amp;fortune, QObject *
parent)