/****************************************************************************
**
** Copyright (C) 2004-2008 Trolltech ASA. All rights reserved.
**
** This file is part of the documentation of the Qt Toolkit.
**
** This file may be used under the terms of the GNU General Public
** License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file.  Alternatively you may (at
** your option) use any later version of the GNU General Public
** License if such license has been publicly approved by Trolltech ASA
** (or its successors, if any) and the KDE Free Qt Foundation. In
** addition, as a special exception, Trolltech gives you certain
** additional rights. These rights are described in the Trolltech GPL
** Exception version 1.2, which can be found at
** http://www.trolltech.com/products/qt/gplexception/ and in the file
** GPL_EXCEPTION.txt in this package.
**
** Please review the following information to ensure GNU General
** Public Licensing requirements will be met:
** http://trolltech.com/products/qt/licenses/licensing/opensource/. If
** you are unsure which license is appropriate for your use, please
** review the following information:
** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
** or contact the sales department at sales@trolltech.com.
**
** In addition, as a special exception, Trolltech, as the sole
** copyright holder for Qt Designer, grants users of the Qt/Eclipse
** Integration plug-in the right for the Qt/Eclipse Integration to
** link to functionality provided by Qt Designer and its related
** libraries.
**
** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly
** granted herein.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/

/*!
    \example network/fortuneclient
    \title Fortune Client Example

    The Fortune Client example shows how to create a client for a simple
    network service using QTcpSocket. It is intended to be run alongside the
    \l{network/fortuneserver}{Fortune Server} example or
    the \l{network/threadedfortuneserver}{Threaded Fortune Server} example.

    \image fortuneclient-example.png Screenshot of the Fortune Client example

    This example uses a simple QDataStream-based data transfer protocol to
    request a line of text from a fortune server (from the
    \l{network/fortuneserver}{Fortune Server} example). The client requests a
    fortune by simply connecting to the server. The server then responds with
    a 16-bit (quint16) integer containing the length of the fortune text,
    followed by a QString.

    QTcpSocket supports two general approaches to network programming:

    \list

    \o \e{The asynchronous (non-blocking) approach.} Operations are scheduled
    and performed when control returns to Qt's event loop. When the operation
    is finished, QTcpSocket emits a signal. For example,
    QTcpSocket::connectToHost() returns immediately, and when the connection
    has been established, QTcpSocket emits
    \l{QTcpSocket::connected()}{connected()}.

    \o \e{The synchronous (blocking) approach.} In non-GUI and multithreaded
    applications, you can call the \c waitFor...() functions (e.g.,
    QTcpSocket::waitForConnected()) to suspend the calling thread until the
    operation has completed, instead of connecting to signals.

    \endlist

    In this example, we will demonstrate the asynchronous approach. The
    \l{network/blockingfortuneclient}{Blocking Fortune Client} example
    illustrates the synchronous approach.

    Our class contains some data and a few private slots:

    \snippet examples/network/fortuneclient/client.h 0

    Other than the widgets that make up the GUI, the data members include a
    QTcpSocket pointer, a copy of the fortune text currently displayed, and
    the size of the packet we are currently reading (more on this later).

    The socket is initialized in the Client constructor. We'll pass the main
    widget as parent, so that we won't have to worry about deleting the
    socket:

    \snippet examples/network/fortuneclient/client.cpp 0
    \dots
    \snippet examples/network/fortuneclient/client.cpp 1

    The only QTcpSocket signals we need in this example are
    QTcpSocket::readyRead(), signifying that data has been received, and
    QTcpSocket::error(), which we will use to catch any connection errors:

    \dots
    \snippet examples/network/fortuneclient/client.cpp 3
    \dots
    \snippet examples/network/fortuneclient/client.cpp 5

    Clicking the \gui{Get Fortune} button will invoke the \c
    requestNewFortune() slot:

    \snippet examples/network/fortuneclient/client.cpp 6

    In this slot, we initialize \c blockSize to 0, preparing to read a new block
    of data.  Because we allow the user to click \gui{Get Fortune} before the
    previous connection finished closing, we start off by aborting the
    previous connection by calling QTcpSocket::abort(). (On an unconnected
    socket, this function does nothing.) We then proceed to connecting to the
    fortune server by calling QTcpSocket::connectToHost(), passing the
    hostname and port from the user interface as arguments.

    As a result of calling \l{QTcpSocket::connectToHost()}{connectToHost()},
    one of two things can happen:

    \list
    \o \e{The connection is established.} In this case, the server will send us a
    fortune. QTcpSocket will emit \l{QTcpSocket::readyRead()}{readyRead()}
    every time it receives a block of data.

    \o \e{An error occurs.} We need to inform the user if the connection
    failed or was broken. In this case, QTcpSocket will emit
    \l{QTcpSocket::error()}{error()}, and \c Client::displayError() will be
    called.
    \endlist

    Let's go through the \l{QTcpSocket::error()}{error()} case first:

    \snippet examples/network/fortuneclient/client.cpp 13

    We pop up all errors in a dialog using
    QMessageBox::information(). QTcpSocket::RemoteHostClosedError is silently
    ignored, because the fortune server protocol ends with the server closing
    the connection.

    Now for the \l{QTcpSocket::readyRead()}{readyRead()} alternative. This
    signal is connected to \c Client::readFortune():

    \snippet examples/network/fortuneclient/client.cpp 8
    \codeline
    \snippet examples/network/fortuneclient/client.cpp 10

    The protocol is based on QDataStream, so we start by creating a stream
    object, passing the socket to QDataStream's constructor. We then
    explicitly set the protocol version of the stream to QDataStream::Qt_4_0
    to ensure that we're using the same version as the fortune server, no
    matter which version of Qt the client and server use.

    Now, TCP is based on sending a stream of data, so we cannot expect to get
    the entire fortune in one go. Especially on a slow network, the data can
    be received in several small fragments. QTcpSocket buffers up all incoming
    data and emits \l{QTcpSocket::readyRead()}{readyRead()} for every new
    block that arrives, and it is our job to ensure that we have received all
    the data we need before we start parsing. The server's response starts
    with the size of the packet, so first we need to ensure that we can read
    the size, then we will wait until QTcpSocket has received the full packet.

    \snippet examples/network/fortuneclient/client.cpp 11
    \codeline
    \snippet examples/network/fortuneclient/client.cpp 12

    We proceed by using QDataStream's streaming operator to read the fortune
    from the socket into a QString. Once read, we can call QLabel::setText()
    to display the fortune.

    \sa {Fortune Server Example}, {Blocking Fortune Client Example}
*/
