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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
|
/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** 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 either Technology Preview License Agreement or the
** Beta Release License Agreement.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\module QtNetwork
\title QtNetwork Module
\contentspage Qt's Modules
\previouspage QtGui
\nextpage QtOpenGL
\ingroup modules
\brief The QtNetwork module offers classes that allow you to
write TCP/IP clients and servers.
The network module provides classes to make network programming
easier and portable. It offers classes such as QHttp and QFtp that
implement specific application-level protocols, lower-level classes
such as QTcpSocket, QTcpServer and QUdpSocket that represent low
level network concepts, and high level classes such as QNetworkRequest,
QNetworkReply and QNetworkAccessManager to perform network operations using common protocols.
The QtNetwork module is part of the \l{Qt Full Framework Edition} and the
\l{Open Source Versions of Qt}.
Topics:
\tableofcontents
\section1 Configuring the Build Process
Applications that use Qt's networking classes need to
be configured to be built against the QtNetwork module.
The following declaration in a \c qmake project file ensures that
an application is compiled and linked appropriately:
\snippet doc/src/snippets/code/doc_src_qtnetwork.qdoc 0
This line is necessary because only the QtCore and QtGui modules
are used in the default build process.
To include the definitions of the module's classes, use the
following directive:
\snippet doc/src/snippets/code/doc_src_qtnetwork.qdoc 1
\section1 High Level Network Operations
The Network Access API is a collection of classes for performing
common network operations. The API provides an abstraction layer
over the specific operations and protocols used (for example,
getting and posting data over HTTP), and only exposes classes,
functions, and signals for general or high level concepts.
Network requests are represented by the QNetworkRequest class,
which also acts as a general container for information associated
with a request, such as any header information and the encryption
used. The URL specified when a request object is constructed
determines the protocol used for a request.
The coordination of network operations is performed by the
QNetworkAccessManager class. Once a request has been created,
this class is used to dispatch it and emit signals to report on
its progress. The manager also coordinates the use of
\l{QNetworkCookieJar}{cookies} to store data on the client,
authentication requests, and the use of proxies.
Replies to network requests are represented by the QNetworkReply
class; these are created by QNetworkAccessManager when a request
is dispatched. The signals provided by QNetworkReply can be used
to monitor each reply individually, or developers may choose to
use the manager's signals for this purpose instead and discard
references to replies. Since QNetworkReply is a subclass of
QIODevice, replies can be handled synchronously or asynchronously;
i.e., as blocking or non-blocking operations.
Each application or library can create one or more instances of
QNetworkAccessManager to handle network communication.
\section1 Writing HTTP and FTP Clients with QHttp and QFtp
HTTP (Hypertext Transfer Protocol) is an application-level
network protocol used mainly for downloading HTML and XML files,
but it is also used as a high-level transport protocol for many
other types of data, from images and movies to purchase orders
and banking transactions. In contrast, FTP (File Transfer
Protocol) is a protocol used almost exclusively for browsing
remote directories and for transferring files.
\image httpstack.png HTTP Client and Server
HTTP is a simpler protocol than FTP in many ways. It uses only
one network connection, while FTP uses two (one for sending
commands, and one for transferring data). HTTP is a stateless
protocol; requests and responses are always self-contained. The
FTP protocol has a state and requires the client to send several
commands before a file transfer takes place.
In practice, HTTP clients often use separate connections for
separate requests, whereas FTP clients establish one connection
and keep it open throughout the session.
The QHttp and QFtp classes provide client-side support for HTTP
and FTP. Since the two protocols are used to solve the same
problems, the QHttp and QFtp classes have many features in
common:
\list
\o \e{Non-blocking behavior.} QHttp and QFtp are asynchronous.
You can schedule a series of commands (also called "requests" for
HTTP). The commands are executed later, when control returns to
Qt's event loop.
\o \e{Command IDs.} Each command has a unique ID number that you
can use to follow the execution of the command. For example, QFtp
emits the \l{QFtp::commandStarted()}{commandStarted()} and
\l{QFtp::commandFinished()}{commandFinished()} signal with the
command ID for each command that is executed. QHttp has a
\l{QHttp::requestStarted()}{requestStarted()} and a
\l{QHttp::requestFinished()}{requestFinished()} signal that work
the same way.
\o \e{Data transfer progress indicators.} QHttp and QFtp emit
signals whenever data is transferred
(QFtp::dataTransferProgress(), QHttp::dataReadProgress(), and
QHttp::dataSendProgress()). You could connect these signals to
QProgressBar::setProgress() or QProgressDialog::setProgress(),
for example.
\o \e{QIODevice support.} Both classes support convenient
uploading from and downloading to \l{QIODevice}s, in addition to a
QByteArray-based API.
\endlist
There are two main ways of using QHttp and QFtp. The most common
approach is to keep track of the command IDs and follow the
execution of every command by connecting to the appropriate
signals. The other approach is to schedule all commands at once
and only connect to the done() signal, which is emitted when all
scheduled commands have been executed. The first approach
requires more work, but it gives you more control over the
execution of individual commands and allows you to initiate new
commands based on the result of a previous command. It also
enables you to provide detailed feedback to the user.
The \l{network/http}{HTTP} and \l{network/ftp}{FTP} examples
illustrate how to write an HTTP and an FTP client.
Writing your own HTTP or FTP server is possible using the
lower-level classes QTcpSocket and QTcpServer.
\section1 Using TCP with QTcpSocket and QTcpServer
TCP (Transmission Control Protocol) is a low-level network
protocol used by most Internet protocols, including HTTP and FTP,
for data transfer. It is a reliable, stream-oriented,
connection-oriented transport protocol. It is particularly well
suited to the continuous transmission of data.
\image tcpstream.png A TCP Stream
The QTcpSocket class provides an interface for TCP. You can use
QTcpSocket to implement standard network protocols such as POP3,
SMTP, and NNTP, as well as custom protocols.
A TCP connection must be established to a remote host and port
before any data transfer can begin. Once the connection has been
established, the IP address and port of the peer are available
through QTcpSocket::peerAddress() and QTcpSocket::peerPort(). At
any time, the peer can close the connection, and data transfer
will then stop immediately.
QTcpSocket works asynchronously and emits signals to report status
changes and errors, just like QHttp and QFtp. It relies on the
event loop to detect incoming data and to automatically flush
outgoing data. You can write data to the socket using
QTcpSocket::write(), and read data using
QTcpSocket::read(). QTcpSocket represents two independent streams
of data: one for reading and one for writing.
Since QTcpSocket inherits QIODevice, you can use it with
QTextStream and QDataStream. When reading from a QTcpSocket, you
must make sure that enough data is available by calling
QTcpSocket::bytesAvailable() beforehand.
If you need to handle incoming TCP connections (e.g., in a server
application), use the QTcpServer class. Call QTcpServer::listen()
to set up the server, and connect to the
QTcpServer::newConnection() signal, which is emitted once for
every client that connects. In your slot, call
QTcpServer::nextPendingConnection() to accept the connection and
use the returned QTcpSocket to communicate with the client.
Although most of its functions work asynchronously, it's possible
to use QTcpSocket synchronously (i.e., blocking). To get blocking
behavior, call QTcpSocket's waitFor...() functions; these suspend
the calling thread until a signal has been emitted. For example,
after calling the non-blocking QTcpSocket::connectToHost()
function, call QTcpSocket::waitForConnected() to block the thread
until the \l{QTcpSocket::connected()}{connected()} signal has
been emitted.
Synchronous sockets often lead to code with a simpler flow of
control. The main disadvantage of the waitFor...() approach is
that events won't be processed while a waitFor...() function is
blocking. If used in the GUI thread, this might freeze the
application's user interface. For this reason, we recommend that
you use synchronous sockets only in non-GUI threads. When used
synchronously, QTcpSocket doesn't require an event loop.
The \l{network/fortuneclient}{Fortune Client} and
\l{network/fortuneserver}{Fortune Server} examples show how to use
QTcpSocket and QTcpServer to write TCP client-server
applications. See also \l{network/blockingfortuneclient}{Blocking
Fortune Client} for an example on how to use a synchronous
QTcpSocket in a separate thread (without using an event loop),
and \l{network/threadedfortuneserver}{Threaded Fortune Server}
for an example of a multithreaded TCP server with one thread per
active client.
\section1 Using UDP with QUdpSocket
UDP (User Datagram Protocol) is a lightweight, unreliable,
datagram-oriented, connectionless protocol. It can be used when
reliability isn't important. For example, a server that reports
the time of day could choose UDP. If a datagram with the time of
day is lost, the client can simply make another request.
\image udppackets.png UDP Packets
The QUdpSocket class allows you to send and receive UDP
datagrams. It inherits QAbstractSocket, and it therefore shares
most of QTcpSocket's interface. The main difference is that
QUdpSocket transfers data as datagrams instead of as a continuous
stream of data. In short, a datagram is a data packet of limited
size (normally smaller than 512 bytes), containing the IP address
and port of the datagram's sender and receiver in addition to the
data being transferred.
QUdpSocket supports IPv4 broadcasting. Broadcasting is often used
to implement network discovery protocols, such as finding which
host on the network has the most free hard disk space. One host
broadcasts a datagram to the network that all other hosts
receive. Each host that receives a request then sends a reply
back to the sender with its current amount of free disk space.
The originator waits until it has received replies from all
hosts, and can then choose the server with most free space to
store data. To broadcast a datagram, simply send it to the
special address QHostAddress::Broadcast (255.255.255.255), or
to your local network's broadcast address.
QUdpSocket::bind() prepares the socket for accepting incoming
datagrams, much like QTcpServer::listen() for TCP servers.
Whenever one or more datagrams arrive, QUdpSocket emits the
\l{QUdpSocket::readyRead()}{readyRead()} signal. Call
QUdpSocket::readDatagram() to read the datagram.
The \l{network/broadcastsender}{Broadcast Sender} and
\l{network/broadcastreceiver}{Broadcast Receiver} examples show
how to write a UDP sender and a UDP receiver using Qt.
\section1 Resolving Host Names using QHostInfo
Before establishing a network connection, QTcpSocket and
QUdpSocket perform a name lookup, translating the host name
you're connecting to into an IP address. This operation is
usually performed using the DNS (Domain Name Service) protocol.
QHostInfo provides a static function that lets you perform such a
lookup yourself. By calling QHostInfo::lookupHost() with a host
name, a QObject pointer, and a slot signature, QHostInfo will
perform the name lookup and invoke the given slot when the
results are ready. The actual lookup is done in a separate
thread, making use of the operating system's own methods for
performing name lookups.
QHostInfo also provides a static function called
QHostInfo::fromName() that takes the host name as argument and
returns the results. In this case, the name lookup is performed
in the same thread as the caller. This overload is useful for
non-GUI applications or for doing name lookups in a separate,
non-GUI thread. (Calling this function in a GUI thread may cause
your user interface to freeze while the function blocks as
it performs the lookup.)
\section1 Support for Network Proxies
Network communication with Qt can be performed through proxies,
which direct or filter network traffic between local and remote
connections.
Individual proxies are represented by the QNetworkProxy class,
which is used to describe and configure the connection to a proxy.
Proxy types which operate on different levels of network communication
are supported, with SOCKS 5 support allowing proxying of network
traffic at a low level, and HTTP and FTP proxying working at the
protocol level. See QNetworkProxy::ProxyType for more information.
Proxying can be enabled on a per-socket basis or for all network
communication in an application. A newly opened socket can be
made to use a proxy by calling its QAbstractSocket::setProxy()
function before it is connected. Application-wide proxying can
be enabled for all subsequent socket connections through the use
of the QNetworkProxy::setApplicationProxy() function.
Proxy factories are used to create policies for proxy use.
QNetworkProxyFactory supplies proxies based on queries for specific
proxy types. The queries themselves are encoded in QNetworkProxyQuery
objects which enable proxies to be selected based on key criteria,
such as the purpose of the proxy (TCP, UDP, TCP server, URL request),
local port, remote host and port, and the protocol in use (HTTP, FTP,
etc.).
QNetworkProxyFactory::proxyForQuery() is used to query the factory
directly. An application-wide policy for proxying can be implemented
by passing a factory to QNetworkProxyFactory::setApplicationProxyFactory()
and a custom proxying policy can be created by subclassing
QNetworkProxyFactory; see the class documentation for details.
*/
|