source: trunk/doc/html/networkprotocol-example.html@ 190

Last change on this file since 190 was 190, checked in by rudi, 14 years ago

reference documentation added

File size: 16.7 KB
Line 
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
2<!-- /home/espenr/tmp/qt-3.3.8-espenr-2499/qt-x11-free-3.3.8/examples/network/networkprotocol/networkprotocol.doc:5 -->
3<html>
4<head>
5<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
6<title>A simple NNTP implementation</title>
7<style type="text/css"><!--
8fn { margin-left: 1cm; text-indent: -1cm; }
9a:link { color: #004faf; text-decoration: none }
10a:visited { color: #672967; text-decoration: none }
11body { background: #ffffff; color: black; }
12--></style>
13</head>
14<body>
15
16<table border="0" cellpadding="0" cellspacing="0" width="100%">
17<tr bgcolor="#E5E5E5">
18<td valign=center>
19 <a href="index.html">
20<font color="#004faf">Home</font></a>
21 | <a href="classes.html">
22<font color="#004faf">All&nbsp;Classes</font></a>
23 | <a href="mainclasses.html">
24<font color="#004faf">Main&nbsp;Classes</font></a>
25 | <a href="annotated.html">
26<font color="#004faf">Annotated</font></a>
27 | <a href="groups.html">
28<font color="#004faf">Grouped&nbsp;Classes</font></a>
29 | <a href="functions.html">
30<font color="#004faf">Functions</font></a>
31</td>
32<td align="right" valign="center"><img src="logo32.png" align="right" width="64" height="32" border="0"></td></tr></table><h1 align=center>A simple NNTP implementation</h1>
33
34
35<p>
36<p> This example shows how to implement your own <a href="qnetworkprotocol.html">QNetworkProtocol</a>. The
37protocol that was chosen for this example is NTTP. Please note that this
38implementation is very simple since it is designed to be an example. It
39should not be used as a real NNTP implemention.
40<p> <hr>
41<p> Header file (nntp.h):
42<p> <pre>/****************************************************************************
43** $Id: networkprotocol-example.html 2051 2007-02-21 10:04:20Z chehrlic $
44**
45** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.
46**
47** This file is part of an example program for Qt. This example
48** program may be used, distributed and modified without limitation.
49**
50*****************************************************************************/
51
52#ifndef NNTP_H
53#define NNTP_H
54
55#include &lt;<a href="qsocket-h.html">qsocket.h</a>&gt;
56#include &lt;<a href="qnetworkprotocol-h.html">qnetworkprotocol.h</a>&gt;
57
58class Nntp : public <a href="qnetworkprotocol.html">QNetworkProtocol</a>
59{
60 <a href="metaobjects.html#Q_OBJECT">Q_OBJECT</a>
61
62public:
63 Nntp();
64 virtual ~Nntp();
65 virtual int supportedOperations() const;
66
67protected:
68 virtual void operationListChildren( <a href="qnetworkoperation.html">QNetworkOperation</a> *op );
69 virtual void operationGet( <a href="qnetworkoperation.html">QNetworkOperation</a> *op );
70
71 <a href="qsocket.html">QSocket</a> *commandSocket;
72 bool connectionReady;
73 bool readGroups;
74 bool readArticle;
75
76private:
77 bool checkConnection( <a href="qnetworkoperation.html">QNetworkOperation</a> *op );
78 void close();
79 void parseGroups();
80 void parseArticle();
81
82protected slots:
83 void hostFound();
84 void connected();
85 void closed();
86 void readyRead();
87 void error( int );
88
89};
90
91#endif
92</pre>
93
94<p> <hr>
95<p> Implementation (nntp.cpp):
96<p> <pre>/****************************************************************************
97** $Id: networkprotocol-example.html 2051 2007-02-21 10:04:20Z chehrlic $
98**
99** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.
100**
101** This file is part of an example program for Qt. This example
102** program may be used, distributed and modified without limitation.
103**
104*****************************************************************************/
105
106#include "nntp.h"
107#include &lt;<a href="qurlinfo-h.html">qurlinfo.h</a>&gt;
108#include &lt;stdlib.h&gt;
109#include &lt;<a href="qurloperator-h.html">qurloperator.h</a>&gt;
110#include &lt;<a href="qstringlist-h.html">qstringlist.h</a>&gt;
111#include &lt;<a href="qregexp-h.html">qregexp.h</a>&gt;
112
113<a name="f288"></a>Nntp::Nntp()
114 : <a href="qnetworkprotocol.html">QNetworkProtocol</a>(), connectionReady( FALSE ),
115 readGroups( FALSE ), readArticle( FALSE )
116{
117 // create the command socket and connect to its signals
118 commandSocket = new <a href="qsocket.html">QSocket</a>( this );
119<a name="x684"></a> <a href="qobject.html#connect">connect</a>( commandSocket, SIGNAL( <a href="qsocket.html#hostFound">hostFound</a>() ),
120 this, SLOT( hostFound() ) );
121<a name="x681"></a> <a href="qobject.html#connect">connect</a>( commandSocket, SIGNAL( <a href="qsocket.html#connected">connected</a>() ),
122 this, SLOT( connected() ) );
123<a name="x682"></a> <a href="qobject.html#connect">connect</a>( commandSocket, SIGNAL( <a href="qsocket.html#connectionClosed">connectionClosed</a>() ),
124 this, SLOT( closed() ) );
125<a name="x687"></a> <a href="qobject.html#connect">connect</a>( commandSocket, SIGNAL( <a href="qsocket.html#readyRead">readyRead</a>() ),
126 this, SLOT( readyRead() ) );
127<a name="x683"></a> <a href="qobject.html#connect">connect</a>( commandSocket, SIGNAL( <a href="qsocket.html#error">error</a>( int ) ),
128 this, SLOT( error( int ) ) );
129}
130
131Nntp::~Nntp()
132{
133 close();
134 delete commandSocket;
135}
136
137<a name="x675"></a>void Nntp::<a href="qnetworkprotocol.html#operationListChildren">operationListChildren</a>( <a href="qnetworkoperation.html">QNetworkOperation</a> * )
138{
139 // create a command
140 <a href="qstring.html">QString</a> path = <a href="qnetworkprotocol.html#url">url</a>()-&gt;path(), cmd;
141<a name="x691"></a> if ( path.<a href="qstring.html#isEmpty">isEmpty</a>() || path == "/" ) {
142 // if the path is empty or we are in the root dir,
143 // we want to read the list of available newsgroups
144 cmd = "list newsgroups\r\n";
145 } else if ( <a href="qnetworkprotocol.html#url">url</a>()-&gt;isDir() ) {
146 // if the path is a directory (in our case a news group)
147 // we want to list the articles of this group
148<a name="x694"></a> path = path.<a href="qstring.html#replace">replace</a>( "/", "" );
149 cmd = "listgroup " + path + "\r\n";
150 } else
151 return;
152
153 // write the command to the socket
154<a name="x693"></a><a name="x692"></a><a name="x689"></a> commandSocket-&gt;<a href="qsocket.html#writeBlock">writeBlock</a>( cmd.<a href="qstring.html#latin1">latin1</a>(), cmd.<a href="qstring.html#length">length</a>() );
155 readGroups = TRUE;
156}
157
158<a name="x674"></a>void Nntp::<a href="qnetworkprotocol.html#operationGet">operationGet</a>( <a href="qnetworkoperation.html">QNetworkOperation</a> *op )
159{
160 // get the dirPath of the URL (this is our news group)
161 // and the filename (which is the article we want to read)
162<a name="x672"></a> <a href="qurl.html">QUrl</a> u( op-&gt;<a href="qnetworkoperation.html#arg">arg</a>( 0 ) );
163<a name="x696"></a><a name="x695"></a> <a href="qstring.html">QString</a> dirPath = u.<a href="qurl.html#dirPath">dirPath</a>(), file = u.<a href="qurl.html#fileName">fileName</a>();
164 dirPath = dirPath.<a href="qstring.html#replace">replace</a>( "/", "" );
165
166 // go to the group in which the article is
167 <a href="qstring.html">QString</a> cmd;
168 cmd = "group " + dirPath + "\r\n";
169 commandSocket-&gt;<a href="qsocket.html#writeBlock">writeBlock</a>( cmd.<a href="qstring.html#latin1">latin1</a>(), cmd.<a href="qstring.html#length">length</a>() );
170
171 // read the head of the article
172 cmd = "article " + file + "\r\n";
173 commandSocket-&gt;<a href="qsocket.html#writeBlock">writeBlock</a>( cmd.<a href="qstring.html#latin1">latin1</a>(), cmd.<a href="qstring.html#length">length</a>() );
174 readArticle = TRUE;
175}
176
177<a name="x673"></a>bool Nntp::<a href="qnetworkprotocol.html#checkConnection">checkConnection</a>( <a href="qnetworkoperation.html">QNetworkOperation</a> * )
178{
179 // we are connected, return TRUE
180<a name="x670"></a> if ( commandSocket-&gt;<a href="qiodevice.html#isOpen">isOpen</a>() &amp;&amp; connectionReady )
181 return TRUE;
182
183 // seems that there is no chance to connect
184 if ( commandSocket-&gt;<a href="qiodevice.html#isOpen">isOpen</a>() )
185 return FALSE;
186
187 // don't call connectToHost() if we are already trying to connect
188<a name="x688"></a> if ( commandSocket-&gt;<a href="qsocket.html#state">state</a>() == QSocket::Connecting )
189 return FALSE;
190
191 // start connecting
192 connectionReady = FALSE;
193<a name="x680"></a> commandSocket-&gt;<a href="qsocket.html#connectToHost">connectToHost</a>( <a href="qnetworkprotocol.html#url">url</a>()-&gt;host(),
194 <a href="qnetworkprotocol.html#url">url</a>()-&gt;port() != -1 ? url()-&gt;port() : 119 );
195 return FALSE;
196}
197
198void <a name="f289"></a>Nntp::close()
199{
200 // close the command socket
201 if ( commandSocket-&gt;<a href="qiodevice.html#isOpen">isOpen</a>() ) {
202 commandSocket-&gt;<a href="qsocket.html#writeBlock">writeBlock</a>( "quit\r\n", strlen( "quit\r\n" ) );
203<a name="x679"></a> commandSocket-&gt;<a href="qsocket.html#close">close</a>();
204 }
205}
206
207<a name="x676"></a>int Nntp::<a href="qnetworkprotocol.html#supportedOperations">supportedOperations</a>() const
208{
209 // we only support listing children and getting data
210 return OpListChildren | OpGet;
211}
212
213void <a name="f290"></a>Nntp::hostFound()
214{
215 if ( <a href="qnetworkprotocol.html#url">url</a>() )
216 emit connectionStateChanged( ConHostFound, tr( "Host %1 found" ).arg( <a href="qnetworkprotocol.html#url">url</a>()-&gt;host() ) );
217 else
218 emit connectionStateChanged( ConHostFound, tr( "Host found" ) );
219}
220
221void <a name="f291"></a>Nntp::connected()
222{
223 if ( <a href="qnetworkprotocol.html#url">url</a>() )
224 emit connectionStateChanged( ConConnected, tr( "Connected to host %1" ).arg( <a href="qnetworkprotocol.html#url">url</a>()-&gt;host() ) );
225 else
226 emit connectionStateChanged( ConConnected, tr( "Connected to host" ) );
227}
228
229void <a name="f292"></a>Nntp::closed()
230{
231 if ( <a href="qnetworkprotocol.html#url">url</a>() )
232 emit connectionStateChanged( ConClosed, tr( "Connection to %1 closed" ).arg( <a href="qnetworkprotocol.html#url">url</a>()-&gt;host() ) );
233 else
234 emit connectionStateChanged( ConClosed, tr( "Connection closed" ) );
235}
236
237void <a name="f293"></a>Nntp::readyRead()
238{
239 // new data arrived on the command socket
240
241 // of we should read the list of available groups, let's do so
242 if ( readGroups ) {
243 parseGroups();
244 return;
245 }
246
247 // of we should read an article, let's do so
248 if ( readArticle ) {
249 parseArticle();
250 return;
251 }
252
253 // read the new data from the socket
254 <a href="qcstring.html">QCString</a> s;
255<a name="x677"></a><a name="x668"></a> s.<a href="qcstring.html#resize">resize</a>( commandSocket-&gt;<a href="qsocket.html#bytesAvailable">bytesAvailable</a>() + 1 );
256<a name="x685"></a><a name="x671"></a> commandSocket-&gt;<a href="qsocket.html#readBlock">readBlock</a>( s.<a href="qmemarray.html#data">data</a>(), commandSocket-&gt;<a href="qsocket.html#bytesAvailable">bytesAvailable</a>() );
257
258 if ( !url() )
259 return;
260
261 // of the code of the server response was 200, we know that the
262 // server is ready to get commands from us now
263<a name="x664"></a> if ( s.<a href="qcstring.html#left">left</a>( 3 ) == "200" )
264 connectionReady = TRUE;
265}
266
267void <a name="f294"></a>Nntp::parseGroups()
268{
269<a name="x678"></a> if ( !commandSocket-&gt;<a href="qsocket.html#canReadLine">canReadLine</a>() )
270 return;
271
272 // read one line after the other
273 while ( commandSocket-&gt;<a href="qsocket.html#canReadLine">canReadLine</a>() ) {
274<a name="x686"></a> <a href="qstring.html">QString</a> s = commandSocket-&gt;<a href="qsocket.html#readLine">readLine</a>();
275
276 // if the line starts with a dot, all groups or articles have been listed,
277 // so we finished processing the listChildren() command
278 if ( s[ 0 ] == '.' ) {
279 readGroups = FALSE;
280 <a href="qnetworkprotocol.html#operationInProgress">operationInProgress</a>()-&gt;setState( StDone );
281 emit finished( <a href="qnetworkprotocol.html#operationInProgress">operationInProgress</a>() );
282 return;
283 }
284
285 // if the code of the server response is 215 or 211
286 // the next line will be the first group or article (depending on what we read).
287 // So let others know that we start reading now...
288 if ( s.<a href="qcstring.html#left">left</a>( 3 ) == "215" || s.<a href="qcstring.html#left">left</a>( 3 ) == "211" ) {
289 <a href="qnetworkprotocol.html#operationInProgress">operationInProgress</a>()-&gt;setState( StInProgress );
290 emit start( <a href="qnetworkprotocol.html#operationInProgress">operationInProgress</a>() );
291 continue;
292 }
293
294 // parse the line and create a QUrlInfo object
295 // which describes the child (group or article)
296<a name="x663"></a> bool tab = s.<a href="qcstring.html#find">find</a>( '\t' ) != -1;
297<a name="x666"></a> <a href="qstring.html">QString</a> group = s.<a href="qcstring.html#mid">mid</a>( 0, s.<a href="qcstring.html#find">find</a>( tab ? '\t' : ' ' ) );
298 <a href="qurlinfo.html">QUrlInfo</a> inf;
299<a name="x700"></a> inf.<a href="qurlinfo.html#setName">setName</a>( group );
300 <a href="qstring.html">QString</a> path = <a href="qnetworkprotocol.html#url">url</a>()-&gt;path();
301<a name="x698"></a> inf.<a href="qurlinfo.html#setDir">setDir</a>( path.<a href="qstring.html#isEmpty">isEmpty</a>() || path == "/" );
302<a name="x702"></a> inf.<a href="qurlinfo.html#setSymLink">setSymLink</a>( FALSE );
303<a name="x699"></a><a name="x697"></a> inf.<a href="qurlinfo.html#setFile">setFile</a>( !inf.<a href="qurlinfo.html#isDir">isDir</a>() );
304<a name="x703"></a> inf.<a href="qurlinfo.html#setWritable">setWritable</a>( FALSE );
305<a name="x701"></a> inf.<a href="qurlinfo.html#setReadable">setReadable</a>( TRUE );
306
307 // let others know about our new child
308 emit newChild( inf, operationInProgress() );
309 }
310
311}
312
313void <a name="f295"></a>Nntp::parseArticle()
314{
315 if ( !commandSocket-&gt;<a href="qsocket.html#canReadLine">canReadLine</a>() )
316 return;
317
318 // read an article one line after the other
319 while ( commandSocket-&gt;<a href="qsocket.html#canReadLine">canReadLine</a>() ) {
320 <a href="qstring.html">QString</a> s = commandSocket-&gt;<a href="qsocket.html#readLine">readLine</a>();
321
322 // if the line starts with a dot, we finished reading something
323 if ( s[ 0 ] == '.' ) {
324 readArticle = FALSE;
325 <a href="qnetworkprotocol.html#operationInProgress">operationInProgress</a>()-&gt;setState( StDone );
326 emit finished( <a href="qnetworkprotocol.html#operationInProgress">operationInProgress</a>() );
327 return;
328 }
329
330<a name="x669"></a> if ( s.<a href="qcstring.html#right">right</a>( 1 ) == "\n" )
331<a name="x667"></a><a name="x665"></a> s.<a href="qcstring.html#remove">remove</a>( s.<a href="qcstring.html#length">length</a>() - 1, 1 );
332
333 // emit the new data of the article which we read
334<a name="x690"></a> emit data( QCString( s.<a href="qstring.html#ascii">ascii</a>() ), operationInProgress() );
335 }
336}
337
338void <a name="f296"></a>Nntp::error( int code )
339{
340 if ( code == QSocket::ErrHostNotFound ||
341 code == QSocket::ErrConnectionRefused ) {
342 // this signal is called if connecting to the server failed
343 if ( <a href="qnetworkprotocol.html#operationInProgress">operationInProgress</a>() ) {
344 <a href="qstring.html">QString</a> msg = <a href="qobject.html#tr">tr</a>( "Host not found or couldn't connect to: \n" + url()-&gt;host() );
345 <a href="qnetworkprotocol.html#operationInProgress">operationInProgress</a>()-&gt;setState( StFailed );
346 <a href="qnetworkprotocol.html#operationInProgress">operationInProgress</a>()-&gt;setProtocolDetail( msg );
347 <a href="qnetworkprotocol.html#operationInProgress">operationInProgress</a>()-&gt;setErrorCode( (int)ErrHostNotFound );
348 <a href="qnetworkprotocol.html#clearOperationQueue">clearOperationQueue</a>();
349 emit finished( <a href="qnetworkprotocol.html#operationInProgress">operationInProgress</a>() );
350 }
351 }
352}
353</pre>
354
355<p>See also <a href="network-examples.html">Network Examples</a>.
356
357<!-- eof -->
358<p><address><hr><div align=center>
359<table width=100% cellspacing=0 border=0><tr>
360<td>Copyright &copy; 2007
361<a href="troll.html">Trolltech</a><td align=center><a href="trademarks.html">Trademarks</a>
362<td align=right><div align=right>Qt 3.3.8</div>
363</table></div></address></body>
364</html>
Note: See TracBrowser for help on using the repository browser.