summaryrefslogtreecommitdiffstats
path: root/examples/network/doc/src/fortuneserver.qdoc
blob: 1973f372cef677c2ede37f513941b525064f71b8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only

/*!
    \example fortuneserver
    \title Fortune Server
    \examplecategory {Networking}
    \meta tags {tcp,network,server}
    \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_5_10 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}, {Threaded Fortune Server}
 */