From bd0f3345a938b35ce6a12f6150373b0955b8dd12 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Sun, 10 Jul 2011 15:24:15 -0500 Subject: Add Qt3 development HEAD version --- doc/html/network.html | 466 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 466 insertions(+) create mode 100644 doc/html/network.html (limited to 'doc/html/network.html') diff --git a/doc/html/network.html b/doc/html/network.html new file mode 100644 index 0000000..ba7be6d --- /dev/null +++ b/doc/html/network.html @@ -0,0 +1,466 @@ + + + + + +Network Module + + + + + + + +
+ +Home + | +All Classes + | +Main Classes + | +Annotated + | +Grouped Classes + | +Functions +

Network Module

+ + + +

+

+

+ + +

Introduction +

+

The network module offers classes to make network programming easier +and portable. Essentially, there are three sets of classes, first low +level classes like QSocket, QServerSocket, QDns, etc. which +allow you to work in a portable way with TCP/IP sockets. In addition, +there are classes like QNetworkProtocol, QNetworkOperation in +the Qt base library, which provide an abstract layer for implementing +network protocols and QUrlOperator which operates on such network +protocols. Finally the third set of network classes are the passive +ones, specifically QUrl and QUrlInfo which do URL parsing and +similar. +

The first set of classes (QSocket, QServerSocket, QDns, QFtp, etc.) are included in Qt's "network" module. +

The QSocket 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 QFtp class (which implements the FTP protocol) uses +QSockets. But QSockets don't need to be used for protocol +implementations, e.g. QLocalFs (which is an implementation of the +local filesystem as network protocol) uses QDir 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. +

Working Network Protocol independently with QUrlOperator and QNetworkOperation +

+

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: +

+    QUrlOperator op;
+    op.copy( "ftp://ftp.trolltech.com/qt/source/qt-2.1.0.tar.gz", "file:/tmp", FALSE );
+
+ +

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. +

You can also do things like creating directories, removing files, +renaming, etc. For example, to create a folder on a private FTP +account do +

+    QUrlOperator op( "ftp://username:password@host.domain.no/home/username" );
+    op.mkdir( "New Directory" );
+
+ +

To see all available operations, look at the QUrlOperator class +documentation. +

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 QNetworkOperation, and this object stores +all the information about the operation. +

For example, QNetworkOperation 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 QUrlOperator method, the type of the operation +and some more information. For more details see the class +documentation of QNetworkOperation. +

The QUrlOperator emits signals to inform you about the progress of +the operations. As you can call many methods which operate on a QUrlOperator's URL, it queues up all the operations. So you can't know +which operation the QUrlOperator just processed. Clearly you will +want to know which operation just took place, so each signal's last +argument is a pointer to the QNetworkOperation object which was +just processed and which caused the signal to be emitted. +

Some of these operations send a start() signal at the beginning (if +this makes sense), and some of them send some signals during +processing. All operations send a finished() signal after they are +done. To find that out if an operation finished successfully you can +use the QNetworkOperation pointer you got with the finished() +signal. If QNetworkOperation::state() equals QNetworkProtocol::StDone the operation finished successfully, if it is +QNetworkProtocol::StFailed the operation failed. +

Example: A slot which you might connect to the +QUrlOperator::finished( QNetworkOperation * ) +

+void MyClass::slotOperationFinished( QNetworkOperation *op )
+{
+    switch ( op->operation() ) {
+    case QNetworkProtocol::OpMkDir: 
+        if ( op->state() == QNetworkProtocol::StFailed )
+            qDebug( "Couldn't create directory %s", op->arg( 0 ).latin1() );
+        else
+            qDebug( "Successfully created directory %s", op->arg( 0 ).latin1() );
+        break;
+    // ... and so on
+    }
+}
+
+ +

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): +

+QUrlOperator op;
+
+MyClass::MyClass() : QObject(), op( "ftp://ftp.trolltech.com" )
+{
+    connect( &op, SIGNAL( newChildren( const QValueList<QUrlInfo> &, QNetworkOperation * ) ),
+             this, SLOT( slotInsertEntries( const QValueList<QUrlInfo> &, QNetworkOperation * ) ) );
+    connect( &op, SIGNAL( start( QNetworkOperation * ) ),
+             this, SLOT( slotStart( QNetworkOperation *) ) );
+    connect( &op, SIGNAL( finished( QNetworkOperation * ) ),
+             this, SLOT( slotFinished( QNetworkOperation *) ) );
+}
+
+void MyClass::slotInsertEntries( const QValueList<QUrlInfo> &info, QNetworkOperation * )
+{
+    QValueList<QUrlInfo>::ConstIterator it = info.begin();
+    for ( ; it != info.end(); ++it ) {
+        const QUrlInfo &inf = *it;
+        qDebug( "Name: %s, Size: %d, Last Modified: %s",
+            inf.name().latin1(), inf.size(), inf.lastModified().toString().latin1() );
+    }
+}
+
+void MyClass::slotStart( QNetworkOperation * )
+{
+    qDebug( "Start reading '%s'", op.toString().latin1() );
+}
+
+void MyClass::slotFinished( QNetworkOperation *operation )
+{
+    if ( operation->operation() == QNetworkProtocol::OpListChildren ) {
+        if ( operation->state() == QNetworkProtocol::StFailed )
+            qDebug( "Couldn't read '%s'! Following error occurred: %s",
+                op.toString().latin1(), operation->protocolDetail().latin1() );
+        else
+            qDebug( "Finished reading '%s'!", op.toString().latin1() );
+    }
+}
+
+
+ +

These examples demonstrate now how to use the QUrlOperator and QNetworkOperations. The network extension also contains useful example +code. +

Implementing your own Network Protocol +

+

QNetworkProtocol 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. +

Note 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! +

To implement a network protocol create a class derived from +QNetworkProtocol. +

Other classes will use this network protocol implementation +to operate on it. So you should reimplement following protected members +

+    void QNetworkProtocol::operationListChildren( QNetworkOperation *op );
+    void QNetworkProtocol::operationMkDir( QNetworkOperation *op );
+    void QNetworkProtocol::operationRemove( QNetworkOperation *op );
+    void QNetworkProtocol::operationRename( QNetworkOperation *op );
+    void QNetworkProtocol::operationGet( QNetworkOperation *op );
+    void QNetworkProtocol::operationPut( QNetworkOperation *op );
+
+ +

Some notes on reimplementing these methods: You always get a pointer +to a QNetworkOperation 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 QNetworkProtocol::StInProgress. If you finished processing the +operation, set the state to QNetworkProtocol::StDone if it was +successful or QNetworkProtocol::StFailed if an error occurred. If +an error occurred you must set an error code (see +QNetworkOperation::setErrorCode()) and if you know some details +(e.g. an error message) you can also set this message to the operation +pointer (see QNetworkOperation::setProtocolDetail()). Also you get +all the relevant information (type, arguments, etc.) about the +operation from the QNetworkOperation pointer. For details about +which arguments you can get and set look at QNetworkOperation's +class documentation. +

If you reimplement an operation function, it's very important to emit +the correct signals at the correct time: In general always emit finished() 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 finished() signals! Then there are some more +specialized signals which are specific to operations: +

+

And remember, always emit the finished() signal at the end! +

For more details about these signals' arguments look at the QNetworkProtocol class documentation. +

Here is a list of which QNetworkOperation arguments you can get and +which you must set in which function: +

(To get the URL on which you should work, use the QNetworkProtocol::url() method which returns a pointer to the URL +operator. Using that you can get the path, host, name filter, etc.) +

+

In summary: If you reimplement an operation function, you must emit +some special signals and at the end you must always emit a finished() signal, regardless of success or failure. Also you must +change the state of the QNetworkOperation during processing. You +can also get and set QNetworkOperation arguments as the operation +progresses. +

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 +

+    int QNetworkProtocol::supportedOperations() const;
+
+ +

In your implementation of this method return an int value +which is constructed by OR-ing together the correct values +(supported operations) of the following enum (of QNetworkProtocol): +

+

For example, if your protocol supports listing children and renaming +them, your implementation of supportedOperations() should do this: +

+    return OpListChildren | OpRename;
+
+ +

The last method you must reimplement is +

+    bool QNetworkProtocol::checkConnection( QNetworkOperation *op );
+
+ +

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 finished() +signal and set an error code and the QNetworkProtocol::StFailed state to +the QNetworkOperation pointer you get here. +

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 checkConnection() 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. +

To be able to use a network protocol with a QUrlOperator (and so, for +example, in the QFileDialog), you must register the network +protocol implementation. This can be done like this: +

+    QNetworkProtocol::registerNetworkProtocol( "myprot", new QNetworkProtocolFactory<MyProtocol> );
+
+ +

In this case MyProtocol would be a class you implemented as +described here (derived from QNetworkProtocol) and the name of the +protocol would be "myprot". So to use it, you would do something like +

+    QUrlOperator op( "myprot://host/path" );
+    op.listChildren();
+
+ +

Finally, as example of a network protocol implementation you could +look at the implementation of QLocalFs. The network extension also +contains an example implementation of a network protocol. +

Error Handling +

+

Error handling is important for both implementing new network +protocols for and using them (through QUrlOperator). +

After processing an operation has been finished the network operation +the QUrlOperator emits the finished() signal. This has as argument +a pointer to the processed QNetworkOperation. If the state of this +operation is QNetworkProtocol::StFailed, the operation contains +some more information about this error. The following error codes are +defined in QNetworkProtocol: +

+
Error Meaning +
QNetworkProtocol::NoError +No error occurred +
QNetworkProtocol::ErrValid +The URL you are operating on is not valid +
QNetworkProtocol::ErrUnknownProtocol +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) +
QNetworkProtocol::ErrUnsupported +The operation is not supported by the protocol +
QNetworkProtocol::ErrParse +Parse error of the URL +
QNetworkProtocol::ErrLoginIncorrect +You needed to login but the username or password are wrong +
QNetworkProtocol::ErrHostNotFound +The specified host (in the URL) couldn't be found +
QNetworkProtocol::ErrListChildren +An error occurred while listing the children +
QNetworkProtocol::ErrMkDir +An error occurred when creating a directory +
QNetworkProtocol::ErrRemove +An error occurred while removing a child +
QNetworkProtocol::ErrRename +An error occurred while renaming a child +
QNetworkProtocol::ErrGet +An error occurred while getting (retrieving) data +
QNetworkProtocol::ErrPut +An error occurred while putting (uploading) data +
QNetworkProtocol::ErrFileNotExisting +A file which is needed by the operation doesn't exist +
QNetworkProtocol::ErrPermissionDenied +The permission for doing the operation has been denied +
+

QNetworkOperation::errorCode() returns one of these codes or +perhaps a different one if you use your an own network protocol +implementation which defines additional error codes. +

QNetworkOperation::protocolDetails() may also return a string which +contains an error message then which might be suitable for display to +the user. +

If you implement your own network protocol, you must report any +errors which occurred. First you always need to be able to +access the QNetworkOperation which is being processed at the +moment. This is done using QNetworkOperation::operationInProgress(), which returns a pointer to +the current network operation or 0 if no operation is processed at the +moment. +

Now if an error occurred and you need to handle it, do this: +

+    if ( operationInProgress() ) {
+        operationInProgress()->setErrorCode( error_code_of_your_error );
+        operationInProgress()->setProtocolDetails( detail ); // optional
+        emit finished( operationInProgress() );
+        return;
+    }
+
+ +

That's all. The connection to the QUrlOperator 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 QNetworkProtocol::clearOperationStack() before emitting finished(). +

Ideally you should use one of the predefined error codes of QNetworkProtocol. If this is not possible, you can add own error codes +- they are just normal ints. Just be careful that the value of the +error code doesn't conflict with an existing one. +

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 QUrlOperators. +

You might also like to look at QFtp (in qt/src/network/qftp.cpp) or at +the example in qt/examples/network/networkprotocol/nntp.cpp. +

+ +


+ +
Copyright © 2007 +TrolltechTrademarks +
Qt 3.3.8
+
+ -- cgit v1.2.1