source: trunk/src/network/qsocketdevice.cpp@ 8

Last change on this file since 8 was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 14.6 KB
Line 
1/****************************************************************************
2** $Id: qsocketdevice.cpp 2 2005-11-16 15:49:26Z dmik $
3**
4** Implementation of QSocketDevice class.
5**
6** Created : 970521
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the network module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition licenses may use this
22** file in accordance with the Qt Commercial License Agreement provided
23** with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qsocketdevice.h"
39#ifndef QT_NO_NETWORK
40
41#include "qwindowdefs.h"
42#include <string.h>
43
44
45//#define QSOCKETDEVICE_DEBUG
46
47
48class QSocketDevicePrivate
49{
50public:
51 QSocketDevicePrivate( QSocketDevice::Protocol p )
52 : protocol(p)
53 { }
54
55 QSocketDevice::Protocol protocol;
56};
57
58
59/*!
60 \class QSocketDevice qsocketdevice.h
61 \brief The QSocketDevice class provides a platform-independent low-level socket API.
62\if defined(commercial)
63 It is part of the <a href="commercialeditions.html">Qt Enterprise Edition</a>.
64\endif
65
66 \ingroup io
67 \module network
68
69 This class provides a low level API for working with sockets. Users of
70 this class are assumed to have networking experience. For most users the
71 QSocket class provides a much easier and high level alternative, but
72 certain things (like UDP) can't be done with QSocket and if you need a
73 platform-independent API for those, QSocketDevice is the right choice.
74
75 The essential purpose of the class is to provide a QIODevice that
76 works on sockets, wrapped in a platform-independent API.
77
78 When calling connect() or bind(), QSocketDevice detects the
79 protocol family (IPv4, IPv6) automatically. Passing the protocol
80 family to QSocketDevice's constructor or to setSocket() forces
81 creation of a socket device of a specific protocol. If not set, the
82 protocol will be detected at the first call to connect() or bind().
83
84 \sa QSocket, QSocketNotifier, QHostAddress
85*/
86
87
88/*!
89 \enum QSocketDevice::Protocol
90
91 This enum type describes the protocol family of the socket. Possible values
92 are:
93
94 \value IPv4 The socket is an IPv4 socket.
95 \value IPv6 The socket is an IPv6 socket.
96 \value Unknown The protocol family of the socket is not known. This can
97 happen if you use QSocketDevice with an already existing socket; it
98 tries to determine the protocol family, but this can fail if the
99 protocol family is not known to QSocketDevice.
100
101 \sa protocol() setSocket()
102*/
103
104/*!
105 \enum QSocketDevice::Error
106
107 This enum type describes the error states of QSocketDevice.
108
109 \value NoError No error has occurred.
110
111 \value AlreadyBound The device is already bound, according to bind().
112
113 \value Inaccessible The operating system or firewall prohibited
114 the action.
115
116 \value NoResources The operating system ran out of a resource.
117
118 \value InternalError An internal error occurred in QSocketDevice.
119
120 \value Impossible An attempt was made to do something which makes
121 no sense. For example:
122 \code
123 ::close( sd->socket() );
124 sd->writeBlock( someData, 42 );
125 \endcode
126 The libc ::close() closes the socket, but QSocketDevice is not aware
127 of this. So when you call writeBlock(), the impossible happens.
128
129 \value NoFiles The operating system will not let QSocketDevice open
130 another file.
131
132 \value ConnectionRefused A connection attempt was rejected by the
133 peer.
134
135 \value NetworkFailure There is a network failure.
136
137 \value UnknownError The operating system did something
138 unexpected.
139*/
140
141/*!
142 \enum QSocketDevice::Type
143
144 This enum type describes the type of the socket:
145 \value Stream a stream socket (TCP, usually)
146 \value Datagram a datagram socket (UDP, usually)
147*/
148
149
150/*!
151 Creates a QSocketDevice object for the existing socket \a socket.
152
153 The \a type argument must match the actual socket type; use \c
154 QSocketDevice::Stream for a reliable, connection-oriented TCP
155 socket, or \c QSocketDevice::Datagram for an unreliable,
156 connectionless UDP socket.
157*/
158QSocketDevice::QSocketDevice( int socket, Type type )
159 : fd( socket ), t( type ), p( 0 ), pp( 0 ), e( NoError ),
160 d(new QSocketDevicePrivate(Unknown))
161{
162#if defined(QSOCKETDEVICE_DEBUG)
163 qDebug( "QSocketDevice: Created QSocketDevice %p (socket %x, type %d)",
164 this, socket, type );
165#endif
166 init();
167 setSocket( socket, type );
168}
169
170/*!
171 Creates a QSocketDevice object for a stream or datagram socket.
172
173 The \a type argument must be either \c QSocketDevice::Stream for a
174 reliable, connection-oriented TCP socket, or \c
175 QSocketDevice::Datagram for an unreliable UDP socket.
176
177 The socket is created as an IPv4 socket.
178
179 \sa blocking() protocol()
180*/
181QSocketDevice::QSocketDevice( Type type )
182 : fd( -1 ), t( type ), p( 0 ), pp( 0 ), e( NoError ),
183 d(new QSocketDevicePrivate(IPv4))
184{
185#if defined(QSOCKETDEVICE_DEBUG)
186 qDebug( "QSocketDevice: Created QSocketDevice object %p, type %d",
187 this, type );
188#endif
189 init();
190 setSocket( createNewSocket(), type );
191}
192
193/*!
194 Creates a QSocketDevice object for a stream or datagram socket.
195
196 The \a type argument must be either \c QSocketDevice::Stream for a
197 reliable, connection-oriented TCP socket, or \c
198 QSocketDevice::Datagram for an unreliable UDP socket.
199
200 The \a protocol indicates whether the socket should be of type IPv4
201 or IPv6. Passing \c Unknown is not meaningful in this context and you
202 should avoid using (it creates an IPv4 socket, but your code is not easily
203 readable).
204
205 The argument \a dummy is necessary for compatibility with some
206 compilers.
207
208 \sa blocking() protocol()
209*/
210QSocketDevice::QSocketDevice( Type type, Protocol protocol, int )
211 : fd( -1 ), t( type ), p( 0 ), pp( 0 ), e( NoError ),
212 d(new QSocketDevicePrivate(protocol))
213{
214#if defined(QSOCKETDEVICE_DEBUG)
215 qDebug( "QSocketDevice: Created QSocketDevice object %p, type %d",
216 this, type );
217#endif
218 init();
219 setSocket( createNewSocket(), type );
220}
221
222/*!
223 Destroys the socket device and closes the socket if it is open.
224*/
225QSocketDevice::~QSocketDevice()
226{
227 close();
228 delete d;
229 d = 0;
230#if defined(QSOCKETDEVICE_DEBUG)
231 qDebug( "QSocketDevice: Destroyed QSocketDevice %p", this );
232#endif
233}
234
235
236/*!
237 Returns TRUE if this is a valid socket; otherwise returns FALSE.
238
239 \sa socket()
240*/
241bool QSocketDevice::isValid() const
242{
243 return fd != -1;
244}
245
246
247/*!
248 \fn Type QSocketDevice::type() const
249
250 Returns the socket type which is either \c QSocketDevice::Stream
251 or \c QSocketDevice::Datagram.
252
253 \sa socket()
254*/
255QSocketDevice::Type QSocketDevice::type() const
256{
257 return t;
258}
259
260/*!
261 Returns the socket's protocol family, which is one of \c Unknown, \c IPv4,
262 or \c IPv6.
263
264 QSocketDevice either creates a socket with a well known protocol family or
265 it uses an already existing socket. In the first case, this function
266 returns the protocol family it was constructed with. In the second case, it
267 tries to determine the protocol family of the socket; if this fails, it
268 returns \c Unknown.
269
270 \sa Protocol setSocket()
271*/
272QSocketDevice::Protocol QSocketDevice::protocol() const
273{
274 if ( d->protocol == Unknown )
275 d->protocol = getProtocol();
276 return d->protocol;
277}
278
279/*!
280 Returns the socket number, or -1 if it is an invalid socket.
281
282 \sa isValid(), type()
283*/
284int QSocketDevice::socket() const
285{
286 return fd;
287}
288
289
290/*!
291 Sets the socket device to operate on the existing socket \a
292 socket.
293
294 The \a type argument must match the actual socket type; use \c
295 QSocketDevice::Stream for a reliable, connection-oriented TCP
296 socket, or \c QSocketDevice::Datagram for an unreliable,
297 connectionless UDP socket.
298
299 Any existing socket is closed.
300
301 \sa isValid(), close()
302*/
303void QSocketDevice::setSocket( int socket, Type type )
304{
305 if ( fd != -1 ) // close any open socket
306 close();
307#if defined(QSOCKETDEVICE_DEBUG)
308 qDebug( "QSocketDevice::setSocket: socket %x, type %d", socket, type );
309#endif
310 t = type;
311 fd = socket;
312 d->protocol = Unknown;
313 e = NoError;
314 setFlags( IO_Sequential );
315 resetStatus();
316 open( IO_ReadWrite );
317 fetchConnectionParameters();
318}
319
320
321/*!
322 \reimp
323
324 Opens the socket using the specified QIODevice file \a mode. This
325 function is called from the QSocketDevice constructors and from
326 the setSocket() function. You should not call it yourself.
327
328 \sa close().
329*/
330bool QSocketDevice::open( int mode )
331{
332 if ( isOpen() || !isValid() )
333 return FALSE;
334#if defined(QSOCKETDEVICE_DEBUG)
335 qDebug( "QSocketDevice::open: mode %x", mode );
336#endif
337 setMode( mode & IO_ReadWrite );
338 setState( IO_Open );
339 return TRUE;
340}
341
342
343/*!
344 \reimp
345
346 The current QSocketDevice implementation does not buffer at all,
347 so this is a no-op.
348*/
349void QSocketDevice::flush()
350{
351}
352
353
354/*!
355 \reimp
356
357 The size is meaningless for a socket, therefore this function returns 0.
358*/
359QIODevice::Offset QSocketDevice::size() const
360{
361 return 0;
362}
363
364
365/*!
366 \reimp
367
368 The read/write index is meaningless for a socket, therefore this
369 function returns 0.
370*/
371QIODevice::Offset QSocketDevice::at() const
372{
373 return 0;
374}
375
376
377/*!
378 \reimp
379
380 The read/write index is meaningless for a socket, therefore this
381 function does nothing and returns TRUE.
382*/
383bool QSocketDevice::at( Offset )
384{
385 return TRUE;
386}
387
388
389/*!
390 \reimp
391
392 Returns TRUE if no data is currently available at the socket;
393 otherwise returns FALSE.
394*/
395bool QSocketDevice::atEnd() const
396{
397 return bytesAvailable() <= 0;
398}
399
400
401/*!
402 \reimp
403
404 \warning getch() is implemented as a one-byte readBlock(), so it
405 may be very slow if you call it more than a few times.
406
407 \sa putch() readBlock()
408*/
409int QSocketDevice::getch()
410{
411 char buf[2];
412 return readBlock(buf,1) == 1 ? buf[0] : -1;
413}
414
415
416/*!
417 \reimp
418
419 \warning putch() is implemented as a one-byte writeBlock(), so it
420 may be very slow if you call it more than a few times.
421
422 \sa getch()
423*/
424int QSocketDevice::putch( int ch )
425{
426 char buf[2];
427 buf[0] = ch;
428 return writeBlock(buf, 1) == 1 ? ch : -1;
429}
430
431
432/*!
433 \reimp
434
435 This implementation of ungetch returns -1 (error). A socket is a
436 sequential device and does not allow any ungetch operation.
437*/
438int QSocketDevice::ungetch( int )
439{
440 return -1;
441}
442
443
444/*!
445 Returns TRUE if the address of this socket can be used by other
446 sockets at the same time, and FALSE if this socket claims
447 exclusive ownership.
448
449 \sa setAddressReusable()
450*/
451bool QSocketDevice::addressReusable() const
452{
453 return option( ReuseAddress );
454}
455
456
457/*!
458 Sets the address of this socket to be usable by other sockets too
459 if \a enable is TRUE, and to be used exclusively by this socket if
460 \a enable is FALSE.
461
462 When a socket is reusable, other sockets can use the same port
463 number (and IP address), which is generally useful. Of course
464 other sockets cannot use the same
465 (address,port,peer-address,peer-port) 4-tuple as this socket, so
466 there is no risk of confusing the two TCP connections.
467
468 \sa addressReusable()
469*/
470void QSocketDevice::setAddressReusable( bool enable )
471{
472 setOption( ReuseAddress, enable );
473}
474
475
476/*!
477 Returns the size of the operating system receive buffer.
478
479 \sa setReceiveBufferSize()
480*/
481int QSocketDevice::receiveBufferSize() const
482{
483 return option( ReceiveBuffer );
484}
485
486
487/*!
488 Sets the size of the operating system receive buffer to \a size.
489
490 The operating system receive buffer size effectively limits two
491 things: how much data can be in transit at any one moment, and how
492 much data can be received in one iteration of the main event loop.
493
494 The default is operating system-dependent. A socket that receives
495 large amounts of data is probably best with a buffer size of
496 49152.
497*/
498void QSocketDevice::setReceiveBufferSize( uint size )
499{
500 setOption( ReceiveBuffer, size );
501}
502
503
504/*!
505 Returns the size of the operating system send buffer.
506
507 \sa setSendBufferSize()
508*/
509int QSocketDevice::sendBufferSize() const
510{
511 return option( SendBuffer );
512}
513
514
515/*!
516 Sets the size of the operating system send buffer to \a size.
517
518 The operating system send buffer size effectively limits how much
519 data can be in transit at any one moment.
520
521 The default is operating system-dependent. A socket that sends
522 large amounts of data is probably best with a buffer size of
523 49152.
524*/
525void QSocketDevice::setSendBufferSize( uint size )
526{
527 setOption( SendBuffer, size );
528}
529
530
531/*!
532 Returns the port number of this socket device. This may be 0 for a
533 while, but is set to something sensible as soon as a sensible
534 value is available.
535
536 Note that Qt always uses native byte order, i.e. 67 is 67 in Qt;
537 there is no need to call htons().
538*/
539Q_UINT16 QSocketDevice::port() const
540{
541 return p;
542}
543
544
545/*!
546 Returns the address of this socket device. This may be 0.0.0.0 for
547 a while, but is set to something sensible as soon as a sensible
548 value is available.
549*/
550QHostAddress QSocketDevice::address() const
551{
552 return a;
553}
554
555
556/*!
557 Returns the first error seen.
558*/
559QSocketDevice::Error QSocketDevice::error() const
560{
561 return e;
562}
563
564
565/*!
566 Allows subclasses to set the error state to \a err.
567*/
568void QSocketDevice::setError( Error err )
569{
570 e = err;
571}
572#endif //QT_NO_NETWORK
573
Note: See TracBrowser for help on using the repository browser.