summaryrefslogtreecommitdiffstats
path: root/doc/src/examples/fortuneclient.qdoc
diff options
context:
space:
mode:
authorQt by Nokia <qt-info@nokia.com>2011-04-27 12:05:43 +0200
committeraxis <qt-info@nokia.com>2011-04-27 12:05:43 +0200
commit38be0d13830efd2d98281c645c3a60afe05ffece (patch)
tree6ea73f3ec77f7d153333779883e8120f82820abe /doc/src/examples/fortuneclient.qdoc
Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you want to look at revision history older than this, please refer to the Qt Git wiki for how to use Git history grafting. At the time of writing, this wiki is located here: http://qt.gitorious.org/qt/pages/GitIntroductionWithQt If you have already performed the grafting and you don't see any history beyond this commit, try running "git log" with the "--follow" argument. Branched from the monolithic repo, Qt master branch, at commit 896db169ea224deb96c59ce8af800d019de63f12
Diffstat (limited to 'doc/src/examples/fortuneclient.qdoc')
-rw-r--r--doc/src/examples/fortuneclient.qdoc160
1 files changed, 160 insertions, 0 deletions
diff --git a/doc/src/examples/fortuneclient.qdoc b/doc/src/examples/fortuneclient.qdoc
new file mode 100644
index 0000000000..1c8b504f43
--- /dev/null
+++ b/doc/src/examples/fortuneclient.qdoc
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Free Documentation License
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \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}
+*/