| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the documentation of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:FDL$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU Free Documentation License Usage |
| ** Alternatively, this file may be used under the terms of the GNU Free |
| ** Documentation License version 1.3 as published by the Free Software |
| ** Foundation and appearing in the file included in the packaging of |
| ** this file. Please review the following information to ensure |
| ** the GNU Free Documentation License version 1.3 requirements |
| ** will be met: https://www.gnu.org/licenses/fdl-1.3.html. |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| /*! |
| \example threadedfortuneserver |
| \title Threaded Fortune Server Example |
| \ingroup examples-network |
| |
| \brief The Threaded Fortune Server example shows how to create a server for a |
| simple network service that uses threads to handle requests from different |
| clients. It is intended to be run alongside the Fortune Client example. |
| |
| \image threadedfortuneserver-example.png |
| |
| The implementation of this example is similar to that of the |
| \l{fortuneserver}{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. |
| |
| \snippet threadedfortuneserver/fortuneserver.h 0 |
| |
| FortuneServer inherits QTcpServer and reimplements |
| QTcpServer::incomingConnection(). We also use it for storing the list of |
| random fortunes. |
| |
| \snippet threadedfortuneserver/fortuneserver.cpp 0 |
| |
| We use FortuneServer's constructor to simply generate the list of |
| fortunes. |
| |
| \snippet threadedfortuneserver/fortuneserver.cpp 1 |
| |
| 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. |
| |
| \snippet threadedfortuneserver/fortunethread.h 0 |
| |
| 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. |
| |
| \snippet threadedfortuneserver/fortunethread.cpp 0 |
| |
| FortuneThread's constructor simply stores the socket descriptor and |
| fortune text, so that they are available for run() later on. |
| |
| \snippet threadedfortuneserver/fortunethread.cpp 1 |
| |
| The first thing our run() function does is to create a QTcpSocket object |
| on the stack. What's worth noticing is that we are creating this object |
| inside the thread, which automatically associates the socket to the |
| thread's event loop. This ensures that Qt will not try to deliver events |
| to our socket from the main thread while we are accessing it from |
| FortuneThread::run(). |
| |
| \snippet threadedfortuneserver/fortunethread.cpp 2 |
| |
| The socket is initialized by calling QTcpSocket::setSocketDescriptor(), |
| passing our socket descriptor as an argument. We expect this to succeed, |
| but just to be sure, (although unlikely, the system may run out of |
| resources,) we catch the return value and report any error. |
| |
| \snippet threadedfortuneserver/fortunethread.cpp 3 |
| |
| As with the \l{fortuneserver}{Fortune Server} example, we encode |
| the fortune into a QByteArray using QDataStream. |
| |
| \snippet threadedfortuneserver/fortunethread.cpp 4 |
| |
| But unlike the previous example, we finish off by calling |
| QTcpSocket::waitForDisconnected(), which blocks the calling thread until |
| the socket has disconnected. Because we are running in a separate thread, |
| the GUI will remain responsive. |
| |
| \sa {Fortune Server Example}, {Fortune Client Example}, {Blocking Fortune |
| Client Example} |
| */ |