summaryrefslogtreecommitdiffstats
path: root/doc/html/network.html
blob: ba7be6d20989131420789afaf63f6be6d7e89cac (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
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
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- /home/espenr/tmp/qt-3.3.8-espenr-2499/qt-x11-free-3.3.8/doc/network.doc:41 -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Network Module</title>
<style type="text/css"><!--
fn { margin-left: 1cm; text-indent: -1cm; }
a:link { color: #004faf; text-decoration: none }
a:visited { color: #672967; text-decoration: none }
body { background: #ffffff; color: black; }
--></style>
</head>
<body>

<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr bgcolor="#E5E5E5">
<td valign=center>
 <a href="index.html">
<font color="#004faf">Home</font></a>
 | <a href="classes.html">
<font color="#004faf">All&nbsp;Classes</font></a>
 | <a href="mainclasses.html">
<font color="#004faf">Main&nbsp;Classes</font></a>
 | <a href="annotated.html">
<font color="#004faf">Annotated</font></a>
 | <a href="groups.html">
<font color="#004faf">Grouped&nbsp;Classes</font></a>
 | <a href="functions.html">
<font color="#004faf">Functions</font></a>
</td>
<td align="right" valign="center"><img src="logo32.png" align="right" width="64" height="32" border="0"></td></tr></table><h1 align=center>Network Module</h1>



<p> 
<p> <!-- toc -->
<ul>
<li><a href="#1"> Introduction
</a>
<li><a href="#2"> Working Network Protocol independently with QUrlOperator and QNetworkOperation
</a>
<ul>
<li><a href="#2-1"> Implementing your own Network Protocol
</a>
<li><a href="#2-2"> Error Handling
</a>
</ul>
</ul>
<!-- endtoc -->

<p> <h2> Introduction
</h2>
<a name="1"></a><p> The network module offers classes to make network programming easier
and portable. Essentially, there are three sets of classes, first low
level classes like <a href="qsocket.html">QSocket</a>, <a href="qserversocket.html">QServerSocket</a>, <a href="qdns.html">QDns</a>, etc. which
allow you to work in a portable way with TCP/IP sockets. In addition,
there are classes like <a href="qnetworkprotocol.html">QNetworkProtocol</a>, <a href="qnetworkoperation.html">QNetworkOperation</a> in
the Qt base library, which provide an abstract layer for implementing
network protocols and <a href="qurloperator.html">QUrlOperator</a> which operates on such network
protocols. Finally the third set of network classes are the passive
ones, specifically <a href="qurl.html">QUrl</a> and <a href="qurlinfo.html">QUrlInfo</a> which do URL parsing and
similar.
<p> The first set of classes (<a href="qsocket.html">QSocket</a>, <a href="qserversocket.html">QServerSocket</a>, <a href="qdns.html">QDns</a>, <a href="qftp.html">QFtp</a>, etc.) are included in Qt's "network" module.
<p> The <a href="qsocket.html">QSocket</a> classes are not directly related to the QNetwork classes,
but QSocket should and will be used for implementing network
protocols, which are directly related to the QNetwork classes. For
example, the <a href="qftp.html">QFtp</a> class (which implements the FTP protocol) uses
QSockets. But QSockets don't need to be used for protocol
implementations, e.g. <a href="qlocalfs.html">QLocalFs</a> (which is an implementation of the
local filesystem as network protocol) uses <a href="qdir.html">QDir</a> and doesn't use
QSocket. Using QNetworkProtocols you can implement everything which
fits into a hierarchical structure and can be accessed using URLs.
This could be, for example, a protocol which can read pictures from a
digital camera using a serial connection.
<p> <h2> Working Network Protocol independently with <a href="qurloperator.html">QUrlOperator</a> and <a href="qnetworkoperation.html">QNetworkOperation</a>
</h2>
<a name="2"></a><p> It is quite easy to just use existing network protocol implementations
and operate on URLs. For example, downloading a file from an FTP
server to the local filesystem can be done with following code:
<p> <pre>
    <a href="qurloperator.html">QUrlOperator</a> op;
    op.<a href="qurloperator.html#copy">copy</a>( "ftp://ftp.trolltech.com/qt/source/qt-2.1.0.tar.gz", "file:/tmp", FALSE );
</pre>
 
<p> And that's all! Of course an implementation of the FTP protocol has to
be available and registered for doing that. More information on that
later.
<p> You can also do things like creating directories, removing files,
renaming, etc. For example, to create a folder on a private FTP
account do
<p> <pre>
    <a href="qurloperator.html">QUrlOperator</a> op( "ftp://username:password@host.domain.no/home/username" );
    op.<a href="qurloperator.html#mkdir">mkdir</a>( "New Directory" );
</pre>
 
<p> To see all available operations, look at the <a href="qurloperator.html">QUrlOperator</a> class
documentation.
<p> Since networking works asynchronously, the function call for an
operation will normally return before the operation has been
completed. This means that the function cannot return a value
indicating failure or success. Instead, the return value always is a
pointer to a <a href="qnetworkoperation.html">QNetworkOperation</a>, and this object stores
all the information about the operation.
<p> For example, <a href="qnetworkoperation.html">QNetworkOperation</a> has a method which returns the state
of this operation. Using this you can find out the state of the
operation at any time. The object also makes available the arguments
you passed to the <a href="qurloperator.html">QUrlOperator</a> method, the type of the operation
and some more information. For more details see the class
documentation of <a href="qnetworkoperation.html">QNetworkOperation</a>.
<p> The <a href="qurloperator.html">QUrlOperator</a> emits signals to inform you about the progress of
the operations. As you can call many methods which operate on a <a href="qurloperator.html">QUrlOperator</a>'s URL, it queues up all the operations. So you can't know
which operation the <a href="qurloperator.html">QUrlOperator</a> just processed. Clearly you will
want to know which operation just took place, so each signal's last
argument is a pointer to the <a href="qnetworkoperation.html">QNetworkOperation</a> object which was
just processed and which caused the signal to be emitted.
<p> Some of these operations send a <tt>start()</tt> signal at the beginning (if
this makes sense), and some of them send some signals during
processing. All operations send a <tt>finished()</tt> signal after they are
done. To find that out if an operation finished successfully you can
use the <a href="qnetworkoperation.html">QNetworkOperation</a> pointer you got with the <tt>finished()</tt>
signal. If <a href="qnetworkoperation.html#state">QNetworkOperation::state</a>() equals <a href="qnetworkprotocol.html#State-enum">QNetworkProtocol::StDone</a> the operation finished successfully, if it is
<a href="qnetworkprotocol.html#State-enum">QNetworkProtocol::StFailed</a> the operation failed.
<p> Example: A slot which you might connect to the 
<tt>QUrlOperator::finished( QNetworkOperation * )</tt>
<pre>
void MyClass::slotOperationFinished( <a href="qnetworkoperation.html">QNetworkOperation</a> *op )
{
    switch ( op-&gt;<a href="qnetworkoperation.html#operation">operation</a>() ) {
    case QNetworkProtocol::OpMkDir: 
        if ( op-&gt;<a href="qnetworkoperation.html#state">state</a>() == QNetworkProtocol::StFailed )
            <a href="qapplication.html#qDebug">qDebug</a>( "Couldn't create directory %s", op-&gt;<a href="qnetworkoperation.html#arg">arg</a>( 0 ).latin1() );
        else
            <a href="qapplication.html#qDebug">qDebug</a>( "Successfully created directory %s", op-&gt;<a href="qnetworkoperation.html#arg">arg</a>( 0 ).latin1() );
        break;
    // ... and so on
    }
}
</pre>
 
<p> As mentioned earlier, some operations send other signals too. Let's
take the list children operation as an example (e.g. read a directory
on a FTP server):
<p> <pre>
QUrlOperator op;

MyClass::MyClass() : <a href="qobject.html">QObject</a>(), op( "ftp://ftp.trolltech.com" )
{
    connect( &amp;op, SIGNAL( newChildren( const <a href="qvaluelist.html">QValueList</a>&lt;QUrlInfo&gt; &amp;, QNetworkOperation * ) ),
             this, SLOT( slotInsertEntries( const <a href="qvaluelist.html">QValueList</a>&lt;QUrlInfo&gt; &amp;, QNetworkOperation * ) ) );
    connect( &amp;op, SIGNAL( start( <a href="qnetworkoperation.html">QNetworkOperation</a> * ) ),
             this, SLOT( slotStart( <a href="qnetworkoperation.html">QNetworkOperation</a> *) ) );
    connect( &amp;op, SIGNAL( finished( <a href="qnetworkoperation.html">QNetworkOperation</a> * ) ),
             this, SLOT( slotFinished( <a href="qnetworkoperation.html">QNetworkOperation</a> *) ) );
}

void MyClass::slotInsertEntries( const <a href="qvaluelist.html">QValueList</a>&lt;QUrlInfo&gt; &amp;info, QNetworkOperation * )
{
    QValueList&lt;QUrlInfo&gt;::ConstIterator it = info.<a href="qvaluelist.html#begin">begin</a>();
    for ( ; it != info.<a href="qvaluelist.html#end">end</a>(); ++it ) {
        const <a href="qurlinfo.html">QUrlInfo</a> &amp;inf = *it;
        <a href="qapplication.html#qDebug">qDebug</a>( "Name: %s, Size: %d, Last Modified: %s",
            inf.<a href="qurlinfo.html#name">name</a>().latin1(), inf.<a href="qurlinfo.html#size">size</a>(), inf.<a href="qurlinfo.html#lastModified">lastModified</a>().toString().latin1() );
    }
}

void MyClass::slotStart( <a href="qnetworkoperation.html">QNetworkOperation</a> * )
{
    <a href="qapplication.html#qDebug">qDebug</a>( "Start reading '%s'", op.toString().latin1() );
}

void MyClass::slotFinished( <a href="qnetworkoperation.html">QNetworkOperation</a> *operation )
{
    if ( operation-&gt;<a href="qnetworkoperation.html#operation">operation</a>() == QNetworkProtocol::OpListChildren ) {
        if ( operation-&gt;<a href="qnetworkoperation.html#state">state</a>() == QNetworkProtocol::StFailed )
            <a href="qapplication.html#qDebug">qDebug</a>( "Couldn't read '%s'! Following error occurred: %s",
                op.toString().latin1(), operation-&gt;<a href="qnetworkoperation.html#protocolDetail">protocolDetail</a>().latin1() );
        else
            <a href="qapplication.html#qDebug">qDebug</a>( "Finished reading '%s'!", op.toString().latin1() );
    }
}

</pre>
 
<p> These examples demonstrate now how to use the <a href="qurloperator.html">QUrlOperator</a> and <tt>QNetworkOperations</tt>. The network extension also contains useful example
code.
<p> <h3> Implementing your own Network Protocol
</h3>
<a name="2-1"></a><p> <a href="qnetworkprotocol.html">QNetworkProtocol</a> provides a base class for implementations
of network protocols and an architecture for the a dynamic
registration and de-registration of network protocols. If you use this
architecture you don't need to care about asynchronous programming, as
the architecture hides this and does all the work for you.
<p> <em>Note</em> It is difficult to design a base class for network protocols
which is useful for all network protocols. The architecture described
here is designed to work with all kinds of hierarchical structures,
like filesystems. So everything which can be interpreted as
hierarchical structure and accessed via URLs, can be implemented as
network protocol and easily used in Qt. This is not limited to
filesystems only!
<p> To implement a network protocol create a class derived from
<a href="qnetworkprotocol.html">QNetworkProtocol</a>.
<p> Other classes will use this network protocol implementation
to operate on it. So you should reimplement following protected members
<p> <pre>
    void QNetworkProtocol::operationListChildren( <a href="qnetworkoperation.html">QNetworkOperation</a> *op );
    void QNetworkProtocol::operationMkDir( <a href="qnetworkoperation.html">QNetworkOperation</a> *op );
    void QNetworkProtocol::operationRemove( <a href="qnetworkoperation.html">QNetworkOperation</a> *op );
    void QNetworkProtocol::operationRename( <a href="qnetworkoperation.html">QNetworkOperation</a> *op );
    void QNetworkProtocol::operationGet( <a href="qnetworkoperation.html">QNetworkOperation</a> *op );
    void QNetworkProtocol::operationPut( <a href="qnetworkoperation.html">QNetworkOperation</a> *op );
</pre>
 
<p> Some notes on reimplementing these methods: You always get a pointer
to a <a href="qnetworkoperation.html">QNetworkOperation</a> as argument. This pointer holds all the
information about the operation in the current state. If you start
processing such an operation, set the state to <a href="qnetworkprotocol.html#State-enum">QNetworkProtocol::StInProgress</a>. If you finished processing the
operation, set the state to <a href="qnetworkprotocol.html#State-enum">QNetworkProtocol::StDone</a> if it was
successful or <a href="qnetworkprotocol.html#State-enum">QNetworkProtocol::StFailed</a> if an error occurred. If
an error occurred you must set an error code (see
<a href="qnetworkoperation.html#setErrorCode">QNetworkOperation::setErrorCode</a>()) and if you know some details
(e.g. an error message) you can also set this message to the operation
pointer (see <a href="qnetworkoperation.html#setProtocolDetail">QNetworkOperation::setProtocolDetail</a>()). Also you get
all the relevant information (type, arguments, etc.) about the
operation from the <a href="qnetworkoperation.html">QNetworkOperation</a> pointer. For details about
which arguments you can get and set look at <a href="qnetworkoperation.html">QNetworkOperation</a>'s
class documentation.
<p> If you reimplement an operation function, it's very important to emit
the correct signals at the correct time: In general always emit <tt>finished()</tt> at the end of an operation (when you either successfully
finished processing the operation or an error occurred) with the
network operation as argument. The whole network architecture relies
on correctly emitted <tt>finished()</tt> signals! Then there are some more
specialized signals which are specific to operations:
<ul>
<li> Emit in <tt>operationListChildren</tt>:
<ul>
<li>  <tt>start()</tt> just before starting to list the children
<li>  <tt>newChildren()</tt> when new children are read
</ul>
<li> Emit in <tt>operationMkDir</tt>:
<ul>
<li>  <tt>createdDirectory()</tt> after the directory has been created
<li>  <tt>newChild()</tt> (or newChildren()) after the directory has been
created (since a new directory is a new child)
</ul>
<li> Emit in <tt>operationRemove</tt>:
<ul>
<li>  <tt>removed()</tt> after a child has been removed
</ul>
<li> Emit in <tt>operationRename</tt>:
<ul>
<li>  <tt>itemChanged()</tt> after a child has been renamed
</ul>
<li> Emit in <tt>operationGet</tt>:
<ul>
<li>  <tt>data()</tt> each time new data has been read
<li>  <tt>dataTransferProgress()</tt> each time new data has been read to
indicate how much of the data has been read now.
</ul>
<li> Emit in <tt>operationPut</tt>:
<ul>
<li>  <tt>dataTransferProgress()</tt> each time data has been written to
indicate how much of the data has been written. Although you
know the whole data when this operation is called, it's
suggested not to write the whole data at once, but to do it
step by step to avoid blocking the GUI. Doing things
incrementally also means that progress can be made visible
to the user.
</ul>
</ul>
<p> And remember, always emit the <tt>finished()</tt> signal at the end!
<p> For more details about these signals' arguments look at the <a href="qnetworkprotocol.html">QNetworkProtocol</a> class documentation.
<p> Here is a list of which <a href="qnetworkoperation.html">QNetworkOperation</a> arguments you can get and
which you must set in which function:
<p> (To get the URL on which you should work, use the <a href="qnetworkprotocol.html#url">QNetworkProtocol::url</a>() method which returns a pointer to the URL
operator. Using that you can get the path, host, name filter, etc.)
<p> <ul>
<li> In <tt>operationListChildren</tt>:
<ul>
<li>   Nothing.
</ul>
<li> In <tt>operationMkDir</tt>:
<ul>
<li>  <tt>QNetworkOperation::arg( 0 )</tt> contains the name of the directory which should be created
</ul>
<li> In <tt>operationRemove</tt>:
<ul>
<li>  <tt>QNetworkOperation::arg( 0 )</tt> contains the name of the file
which should be removed. Normally this is a relative name. But
it could be absolute. Use <a href="qurl.html">QUrl</a>( op->arg( 0 ) ).fileName()
to get the filename.
</ul>
<li> In <tt>operationRename</tt>:
<ul>
<li>  <tt>QNetworkOperation::arg( 0 )</tt> contains the name of the file
which should be renamed
<li>  <tt>QNetworkOperation::arg( 1 )</tt> contains the name to which it
should be renamed.
</ul>
<li> In <tt>operationGet</tt>:
<ul>
<li>  <tt>QNetworkOperation::arg( 0 )</tt> contains the full URL of the
file which should be retrieved.
</ul>
<li> In <tt>operationPut</tt>:
<ul>
<li>  <tt>QNetworkOperation::arg( 0 )</tt> contains the full URL of the
file in which the data should be stored.
<li>  <tt>QNetworkOperation::rawArg( 1 )</tt> contains the data which
should be stored in <tt>QNetworkOperation::arg( 0 )</tt>
</ul>
</ul>
<p> In summary: If you reimplement an operation function, you must emit
some special signals and at the end you must <em>always</em> emit a <tt>finished()</tt> signal, regardless of success or failure. Also you must
change the state of the <a href="qnetworkoperation.html">QNetworkOperation</a> during processing. You 
can also get and set <a href="qnetworkoperation.html">QNetworkOperation</a> arguments as the operation
progresses.
<p> It may occur that the network protocol you implement only requires a
subset of these operations. In such cases, simply reimplement the
operations which are supported by the protocol. Additionally you must
specify which operations you support. This is achieved by
reimplementing
<p> <pre>
    int QNetworkProtocol::supportedOperations() const;
</pre>
 
<p> In your implementation of this method return an <tt>int</tt> value
which is constructed by OR-ing together the correct values
(supported operations) of the following enum (of <a href="qnetworkprotocol.html">QNetworkProtocol</a>):
<p> <ul>
<li> <tt>OpListChildren</tt>
<li> <tt>OpMkDir</tt>
<li> <tt>OpRemove</tt>
<li> <tt>OpRename</tt>
<li> <tt>OpGet</tt>
<li> <tt>OpPut</tt>
</ul>
<p> For example, if your protocol supports listing children and renaming
them, your implementation of <tt>supportedOperations()</tt> should do this:
<p> <pre>
    return OpListChildren | OpRename;
</pre>
 
<p> The last method you must reimplement is
<p> <pre>
    bool QNetworkProtocol::checkConnection( <a href="qnetworkoperation.html">QNetworkOperation</a> *op );
</pre>
 
<p> Here you must return TRUE, if the connection is up and okay (this means
operations on the protocol can be done). If the connection is not okay,
return FALSE and start to try opening it. If you cannot open the
connection at all (e.g. because the host is not found), emit a <tt>finished()</tt>
signal and set an error code and the <a href="qnetworkprotocol.html#State-enum">QNetworkProtocol::StFailed</a> state to
the <a href="qnetworkoperation.html">QNetworkOperation</a> pointer you get here.
<p> Now, you never need to check before doing an operation yourself, if
the connection is okay. The network architecture does this, which
means it uses <tt>checkConnection()</tt> to see if an operation can be done
and if not, it tries it again and again for some time, only calling an
operation function if the connection is okay.
<p> To be able to use a network protocol with a <a href="qurloperator.html">QUrlOperator</a> (and so, for
example, in the <a href="qfiledialog.html">QFileDialog</a>), you must register the network
protocol implementation. This can be done like this:
<p> <pre>
    QNetworkProtocol::<a href="qnetworkprotocol.html#registerNetworkProtocol">registerNetworkProtocol</a>( "myprot", new QNetworkProtocolFactory&lt;MyProtocol&gt; );
</pre>
 
<p> In this case <tt>MyProtocol</tt> would be a class you implemented as
described here (derived from <a href="qnetworkprotocol.html">QNetworkProtocol</a>) and the name of the
protocol would be "myprot". So to use it, you would do something like
<p> <pre>
    <a href="qurloperator.html">QUrlOperator</a> op( "myprot://host/path" );
    op.<a href="qurloperator.html#listChildren">listChildren</a>();
</pre>
 
<p> Finally, as example of a network protocol implementation you could
look at the implementation of <a href="qlocalfs.html">QLocalFs</a>. The network extension also
contains an example implementation of a network protocol.
<p> <h3> Error Handling
</h3>
<a name="2-2"></a><p> Error handling is important for both implementing new network
protocols for and using them (through <a href="qurloperator.html">QUrlOperator</a>).
<p> After processing an operation has been finished the network operation
the <a href="qurloperator.html">QUrlOperator</a> emits the <tt>finished()</tt> signal. This has as argument
a pointer to the processed <a href="qnetworkoperation.html">QNetworkOperation</a>. If the state of this
operation is <a href="qnetworkprotocol.html#State-enum">QNetworkProtocol::StFailed</a>, the operation contains
some more information about this error. The following error codes are
defined in <a href="qnetworkprotocol.html">QNetworkProtocol</a>:
<p> <center><table cellpadding="4" cellspacing="2" border="0">
<tr bgcolor="#a2c511"> <th valign="top">Error <th valign="top">Meaning
<tr bgcolor="#f0f0f0"> <td valign="top"><a href="qnetworkprotocol.html#Error-enum">QNetworkProtocol::NoError</a> 
<td valign="top">No error occurred
<tr bgcolor="#d0d0d0"> <td valign="top"><a href="qnetworkprotocol.html#Error-enum">QNetworkProtocol::ErrValid</a> 
<td valign="top">The URL you are operating on is not valid
<tr bgcolor="#f0f0f0"> <td valign="top"><a href="qnetworkprotocol.html#Error-enum">QNetworkProtocol::ErrUnknownProtocol</a> 
<td valign="top">There is no protocol implementation available for the protocol
of the URL you are operating on (e.g. if the protocol is http
and no http implementation has been registered)
<tr bgcolor="#d0d0d0"> <td valign="top"><a href="qnetworkprotocol.html#Error-enum">QNetworkProtocol::ErrUnsupported</a> 
<td valign="top">The operation is not supported by the protocol
<tr bgcolor="#f0f0f0"> <td valign="top"><a href="qnetworkprotocol.html#Error-enum">QNetworkProtocol::ErrParse</a> 
<td valign="top">Parse error of the URL
<tr bgcolor="#d0d0d0"> <td valign="top"><a href="qnetworkprotocol.html#Error-enum">QNetworkProtocol::ErrLoginIncorrect</a> 
<td valign="top">You needed to login but the username or password are wrong
<tr bgcolor="#f0f0f0"> <td valign="top"><a href="qnetworkprotocol.html#Error-enum">QNetworkProtocol::ErrHostNotFound</a> 
<td valign="top">The specified host (in the URL) couldn't be found
<tr bgcolor="#d0d0d0"> <td valign="top"><a href="qnetworkprotocol.html#Error-enum">QNetworkProtocol::ErrListChildren</a> 
<td valign="top">An error occurred while listing the children
<tr bgcolor="#f0f0f0"> <td valign="top"><a href="qnetworkprotocol.html#Error-enum">QNetworkProtocol::ErrMkDir</a> 
<td valign="top">An error occurred when creating a directory
<tr bgcolor="#d0d0d0"> <td valign="top"><a href="qnetworkprotocol.html#Error-enum">QNetworkProtocol::ErrRemove</a> 
<td valign="top">An error occurred while removing a child
<tr bgcolor="#f0f0f0"> <td valign="top"><a href="qnetworkprotocol.html#Error-enum">QNetworkProtocol::ErrRename</a> 
<td valign="top">An error occurred while renaming a child
<tr bgcolor="#d0d0d0"> <td valign="top"><a href="qnetworkprotocol.html#Error-enum">QNetworkProtocol::ErrGet</a> 
<td valign="top">An error occurred while getting (retrieving) data
<tr bgcolor="#f0f0f0"> <td valign="top"><a href="qnetworkprotocol.html#Error-enum">QNetworkProtocol::ErrPut</a> 
<td valign="top">An error occurred while putting (uploading) data
<tr bgcolor="#d0d0d0"> <td valign="top"><a href="qnetworkprotocol.html#Error-enum">QNetworkProtocol::ErrFileNotExisting</a> 
<td valign="top">A file which is needed by the operation doesn't exist
<tr bgcolor="#f0f0f0"> <td valign="top"><a href="qnetworkprotocol.html#Error-enum">QNetworkProtocol::ErrPermissionDenied</a> 
<td valign="top">The permission for doing the operation has been denied
</table></center>
<p> <a href="qnetworkoperation.html#errorCode">QNetworkOperation::errorCode</a>() returns one of these codes or
perhaps a different one if you use your an own network protocol
implementation which defines additional error codes.
<p> <tt>QNetworkOperation::protocolDetails()</tt> may also return a string which
contains an error message then which might be suitable for display to
the user.
<p> If you implement your own network protocol, you must report any
errors which occurred. First you always need to be able to
access the <a href="qnetworkoperation.html">QNetworkOperation</a> which is being processed at the
moment. This is done using <tt>QNetworkOperation::operationInProgress()</tt>, which returns a pointer to
the current network operation or 0 if no operation is processed at the
moment.
<p> Now if an error occurred and you need to handle it, do this:
<pre>
    if ( operationInProgress() ) {
        operationInProgress()-&gt;setErrorCode( error_code_of_your_error );
        operationInProgress()-&gt;setProtocolDetails( detail ); // optional
        emit finished( operationInProgress() );
        return;
    }
</pre>
 
<p> That's all. The connection to the <a href="qurloperator.html">QUrlOperator</a> and so on is done
automatically. Additionally, if the error was really bad so that no
more operations can be done in the current state (e.g. if the host
couldn't be found), call <tt>QNetworkProtocol::clearOperationStack()</tt> <em>before</em> emitting <tt>finished()</tt>.
<p> Ideally you should use one of the predefined error codes of <a href="qnetworkprotocol.html">QNetworkProtocol</a>. If this is not possible, you can add own error codes
- they are just normal <tt>int</tt>s. Just be careful that the value of the
error code doesn't conflict with an existing one.
<p> An example to look at is in qt/examples/network/ftpclient.
This is the implementation of a fairly complete FTP client, which
supports uploading and downloading files, making directories, etc.,
all done using <tt>QUrlOperators</tt>.
<p> You might also like to look at <a href="qftp.html">QFtp</a> (in qt/src/network/qftp.cpp) or at
the example in qt/examples/network/networkprotocol/nntp.cpp.
<p> 
<!-- eof -->
<p><address><hr><div align=center>
<table width=100% cellspacing=0 border=0><tr>
<td>Copyright &copy; 2007
<a href="troll.html">Trolltech</a><td align=center><a href="trademarks.html">Trademarks</a>
<td align=right><div align=right>Qt 3.3.8</div>
</table></div></address></body>
</html>