Qt Network ModuleThe network module offers classes to make network programming easier and portable. Basically there are three sets of classes, first very basic classes like QSocket, QServerSocket, QDns, etc. which allow 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, namely QUrl and QUrlInfo which do URL parsing and similar
stuff.
The first set of classes (QSocket, QServerSocket, QDns, QFtp, etc.) are included in the "network" module of Qt. 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. E.g. the QFtp class (implementation of 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 no QSocket. Using QNetworkProtocols you can implement everything which fits into a hierarchical structure and can be accessed using URLs. This could be e.g. a protocol which can read pictures from a digital camera using a serial connection.
Working Network Protocol independent with QUrlOperator and QNetworkOperationTo just use existing network protocol implementations and operate on URLs using them is quite easy. E.g. 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 stuff like creating directories, removing files, renaming, etc. E.g. to create a folder on a private FTP account do
QUrlOperator op( "ftp://username:password@host.domain.no/home/username" ); op.mkdir( "New Directory" );
That's it again. To see all available operations, look at the
Now as everything works asynchronous, the function call for an operation returns
before the operation has been processed. So you don't get a return value which
tells you something about failure or success. The return value always is a pointer
to a
In this
Now, later you get signals emitted by the
Some of these operations send a
Now, a slot which you connected to the
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 before, some operations send other signals too. Let's take the list children operation as an example (e.g. read the directory of 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 explained now how to use the
Implementing your own Network Protocol
Limitation: As it is quite hard to design a base class for network protocols which satisfies 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
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 words about how to reimplement these methods: You always get a pointer to
a
If you reimplement such an operation method, it's also very important
to emit the correct signals at the correct time: In general always emit
at the end of an operation (when you either successfully finished processing
the operation or and error occurred) the
And remember, always emit the
For more details about the arguments of these signals take a look
at the
Now, as argument in such a method you get the
(To get the URL on which you should work, use the
So, to sum it up: If you reimplement such an operation method, you
have to emit some special signals and always at the end a
But it's unlikely that the network protocol you implement supports all these operations. So, just reimplement the operations, which are supported by the protocol. Additionally you have to specify which operations are supported then. This is done 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
enum Operation { OpListChildren = 1, OpMkdir = 2, OpRemove = 4, OpRename = 8, OpGet = 32, OpPut = 64 };
So, if your protocol e.g. supports listing children and renaming them, do
in your implementation of
return OpListChildren | OpRename; The last method you have to reimplement is
bool QNetworkProtocol::checkConnection( QNetworkOperation *op );
Here you have to return TRUE, if the connection is up and ok (this means
operations on the protocol can be done). If the connection is not ok,
return FALSE and start to try opening it. If you will not be able to open the
connection at all (e.g. because the host is not found), emit a
Now, you never need to check before doing an operation yourself,
if the connection is ok. The network architecture does this, this means
using Using this knowledge it should be possible to implement network protocols. Finally to be able to use it with a QUrlOperator (and so e.g. in the QFileDialog), you have to register the network protocol implementation. This can be done like this:
QNetworkProtocol::registerNetworkProtocol( "myprot", new QNetworkProtocolFactory<MyProtocol> );
In this case
QUrlOperator op( "myprot://host/path" ); op.listChildren(); Finally as example for a network protocol implementation you could look at the implementation of QLocalFs. The network extension will also contain an example implementation of a network protocol
Error Handling
Error handling is important for both, implementing new network protocols and using
them (through
As already mentioned quite some times after processing an operation has been finished
the network operation and so the QUrlOperator emits the
According to this information it should be possible to react on errors.
Now, if you implement your own network protocol, you will need to tell about errors
which occurred. First you always need to be able to access the Now if and error occurred and you need to handle it, do
if ( operationInProgress() ) { operationInProgress()->setErrorCode( error_code_of_your_error ); operationInProgress()->setProtocolDetails( detail ); // optional! emit finished( operationInProgress() ); return; }
That's all. The connection to the
Now, as error code you should use, if possible, one of the predefined error codes
of Documentation about the low-level classes like QSocket, QDns, etc. will be included in the seperate network extension.
|
Publicité
Best OfActualités les plus luesSemaine
Mois
Année
Le Qt Developer Network au hasardCompiler l'add-in Qt de Visual StudioLe Qt Developer Network est un réseau de développeurs Qt anglophone, où ils peuvent partager leur expérience sur le framework. Lire l'article.
CommunautéRessources
Liens utilesContact
Qt dans le magazine |
Cette page est une traduction d'une page de la documentation de Qt, écrite par Nokia Corporation and/or its subsidiary(-ies). Les éventuels problèmes résultant d'une mauvaise traduction ne sont pas imputables à Nokia. | Qt 2.3 | |
Copyright © 2012 Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon, vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est déposée à la SACD. | ||
Vous avez déniché une erreur ? Un bug ? Une redirection cassée ? Ou tout autre problème, quel qu'il soit ? Ou bien vous désirez participer à ce projet de traduction ? N'hésitez pas à nous contacter ou par MP ! |
Copyright © 2000-2012 - www.developpez.com