| /**************************************************************************** |
| ** |
| ** 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 fortuneserver |
| \title Fortune Server Example |
| \ingroup examples-network |
| \brief Demonstrates how to create a server for a network service. |
| |
| This example is intended to be run alongside the |
| \l{fortuneclient}{Fortune Client} example or the |
| \l{blockingfortuneclient}{Blocking Fortune Client Example}. |
| |
| \image fortuneserver-example.png Screenshot of the Fortune Server example |
| |
| It uses QTcpServer to accept incoming TCP connections, and a |
| simple QDataStream based data transfer protocol to write a fortune to the |
| connecting client (from the \l{fortuneclient}{Fortune Client} |
| example), before closing the connection. |
| |
| \snippet fortuneserver/server.h 0 |
| |
| The server is implemented using a simple class with only one slot, for |
| handling incoming connections. |
| |
| \snippet fortuneserver/server.cpp 1 |
| |
| In its constructor, our Server object calls QTcpServer::listen() to set up |
| a QTcpServer to listen on all addresses, on an arbitrary port. In then |
| displays the port QTcpServer picked in a label, so that user knows which |
| port the fortune client should connect to. |
| |
| \snippet fortuneserver/server.cpp 2 |
| |
| Our server generates a list of random fortunes that it can send to |
| connecting clients. |
| |
| \snippet fortuneserver/server.cpp 3 |
| |
| When a client connects to our server, QTcpServer will emit |
| QTcpServer::newConnection(). In turn, this will invoke our |
| sendFortune() slot: |
| |
| \snippet fortuneserver/server.cpp 4 |
| |
| The purpose of this slot is to select a random line from our list of |
| fortunes, encode it into a QByteArray using QDataStream, and then write it |
| to the connecting socket. This is a common way to transfer binary data |
| using QTcpSocket. First we create a QByteArray and a QDataStream object, |
| passing the bytearray to QDataStream's constructor. We then explicitly set |
| the protocol version of QDataStream to QDataStream::Qt_4_0 to ensure that |
| we can communicate with clients from future versions of Qt (see |
| QDataStream::setVersion()). We continue by streaming in a random fortune. |
| |
| \snippet fortuneserver/server.cpp 7 |
| |
| We then call QTcpServer::nextPendingConnection(), which returns the |
| QTcpSocket representing the server side of the connection. By connecting |
| QTcpSocket::disconnected() to QObject::deleteLater(), we ensure that the |
| socket will be deleted after disconnecting. |
| |
| \snippet fortuneserver/server.cpp 8 |
| |
| The encoded fortune is written using QTcpSocket::write(), and we finally |
| call QTcpSocket::disconnectFromHost(), which will close the connection |
| after QTcpSocket has finished writing the fortune to the network. Because |
| QTcpSocket works asynchronously, the data will be written after this |
| function returns, and control goes back to Qt's event loop. The socket |
| will then close, which in turn will cause QObject::deleteLater() to delete |
| it. |
| |
| \sa {Fortune Client Example}, {Threaded Fortune Server Example} |
| */ |