source: trunk/src/network/qserversocket.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: 8.4 KB
Line 
1/****************************************************************************
2** $Id: qserversocket.cpp 2 2005-11-16 15:49:26Z dmik $
3**
4** Implementation of QServerSocket 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 "qserversocket.h"
39
40#ifndef QT_NO_NETWORK
41
42#include "qsocketnotifier.h"
43
44class QServerSocketPrivate {
45public:
46 QServerSocketPrivate(): s(0), n(0) {}
47 ~QServerSocketPrivate() { delete n; delete s; }
48 QSocketDevice *s;
49 QSocketNotifier *n;
50};
51
52
53/*!
54 \class QServerSocket qserversocket.h
55 \brief The QServerSocket class provides a TCP-based server.
56\if defined(commercial)
57 It is part of the <a href="commercialeditions.html">Qt Enterprise Edition</a>.
58\endif
59
60 \ingroup io
61 \module network
62
63 This class is a convenience class for accepting incoming TCP
64 connections. You can specify the port or have QServerSocket pick
65 one, and listen on just one address or on all the machine's
66 addresses.
67
68 Using the API is very simple: subclass QServerSocket, call the
69 constructor of your choice, and implement newConnection() to
70 handle new incoming connections. There is nothing more to do.
71
72 (Note that due to lack of support in the underlying APIs,
73 QServerSocket cannot accept or reject connections conditionally.)
74
75 \sa QSocket, QSocketDevice, QHostAddress, QSocketNotifier
76*/
77
78
79/*!
80 Creates a server socket object, that will serve the given \a port
81 on all the addresses of this host. If \a port is 0, QServerSocket
82 will pick a suitable port in a system-dependent manner. Use \a
83 backlog to specify how many pending connections the server can
84 have.
85
86 The \a parent and \a name arguments are passed on to the QObject
87 constructor.
88
89 \warning On Tru64 Unix systems a value of 0 for \a backlog means
90 that you don't accept any connections at all; you should specify a
91 value larger than 0.
92*/
93
94QServerSocket::QServerSocket( Q_UINT16 port, int backlog,
95 QObject *parent, const char *name )
96 : QObject( parent, name )
97{
98 d = new QServerSocketPrivate;
99 init( QHostAddress(), port, backlog );
100}
101
102
103/*!
104 Creates a server socket object, that will serve the given \a port
105 only on the given \a address. Use \a backlog to specify how many
106 pending connections the server can have.
107
108 The \a parent and \a name arguments are passed on to the QObject
109 constructor.
110
111 \warning On Tru64 Unix systems a value of 0 for \a backlog means
112 that you don't accept any connections at all; you should specify a
113 value larger than 0.
114*/
115
116QServerSocket::QServerSocket( const QHostAddress & address, Q_UINT16 port,
117 int backlog,
118 QObject *parent, const char *name )
119 : QObject( parent, name )
120{
121 d = new QServerSocketPrivate;
122 init( address, port, backlog );
123}
124
125
126/*!
127 Construct an empty server socket.
128
129 This constructor, in combination with setSocket(), allows us to
130 use the QServerSocket class as a wrapper for other socket types
131 (e.g. Unix Domain Sockets under Unix).
132
133 The \a parent and \a name arguments are passed on to the QObject
134 constructor.
135
136 \sa setSocket()
137*/
138
139QServerSocket::QServerSocket( QObject *parent, const char *name )
140 : QObject( parent, name )
141{
142 d = new QServerSocketPrivate;
143}
144
145
146/*!
147 Returns TRUE if the construction succeeded; otherwise returns FALSE.
148*/
149bool QServerSocket::ok() const
150{
151 return !!d->s;
152}
153
154/*
155 The common bit of the constructors.
156 */
157void QServerSocket::init( const QHostAddress & address, Q_UINT16 port, int backlog )
158{
159 d->s = new QSocketDevice( QSocketDevice::Stream, address.isIPv4Address()
160 ? QSocketDevice::IPv4 : QSocketDevice::IPv6, 0 );
161#if !defined(Q_OS_WIN32)
162 // Under Unix, we want to be able to use the port, even if a socket on the
163 // same address-port is in TIME_WAIT. Under Windows this is possible anyway
164 // -- furthermore, the meaning of reusable is different: it means that you
165 // can use the same address-port for multiple listening sockets.
166 d->s->setAddressReusable( TRUE );
167#endif
168 if ( d->s->bind( address, port )
169 && d->s->listen( backlog ) )
170 {
171 d->n = new QSocketNotifier( d->s->socket(), QSocketNotifier::Read,
172 this, "accepting new connections" );
173 connect( d->n, SIGNAL(activated(int)),
174 this, SLOT(incomingConnection(int)) );
175 } else {
176 qWarning( "QServerSocket: failed to bind or listen to the socket" );
177 delete d->s;
178 d->s = 0;
179 }
180}
181
182
183/*!
184 Destroys the socket.
185
186 This causes any backlogged connections (connections that have
187 reached the host, but not yet been completely set up by calling
188 QSocketDevice::accept()) to be severed.
189
190 Existing connections continue to exist; this only affects the
191 acceptance of new connections.
192*/
193QServerSocket::~QServerSocket()
194{
195 delete d;
196}
197
198
199/*!
200 \fn void QServerSocket::newConnection( int socket )
201
202 This pure virtual function is responsible for setting up a new
203 incoming connection. \a socket is the fd (file descriptor) for the
204 newly accepted connection.
205*/
206
207
208void QServerSocket::incomingConnection( int )
209{
210 int fd = d->s->accept();
211 if ( fd >= 0 )
212 newConnection( fd );
213}
214
215
216/*!
217 Returns the port number on which this server socket listens. This
218 is always non-zero; if you specify 0 in the constructor,
219 QServerSocket will pick a non-zero port itself. ok() must be TRUE
220 before calling this function.
221
222 \sa address() QSocketDevice::port()
223*/
224Q_UINT16 QServerSocket::port() const
225{
226 if ( !d || !d->s )
227 return 0;
228 return d->s->port();
229}
230
231
232/*!
233 Returns the operating system socket.
234*/
235int QServerSocket::socket() const
236{
237 if ( !d || !d->s )
238 return -1;
239
240 return d->s->socket();
241}
242
243/*!
244 Returns the address on which this object listens, or 0.0.0.0 if
245 this object listens on more than one address. ok() must be TRUE
246 before calling this function.
247
248 \sa port() QSocketDevice::address()
249*/
250QHostAddress QServerSocket::address() const
251{
252 if ( !d || !d->s )
253 return QHostAddress();
254
255 return d->s->address();
256}
257
258
259/*!
260 Returns a pointer to the internal socket device. The returned
261 pointer is 0 if there is no connection or pending connection.
262
263 There is normally no need to manipulate the socket device directly
264 since this class does all the necessary setup for most client or
265 server socket applications.
266*/
267QSocketDevice *QServerSocket::socketDevice()
268{
269 if ( !d )
270 return 0;
271
272 return d->s;
273}
274
275
276/*!
277 Sets the socket to use \a socket. bind() and listen() should
278 already have been called for \a socket.
279
280 This allows us to use the QServerSocket class as a wrapper for
281 other socket types (e.g. Unix Domain Sockets).
282*/
283void QServerSocket::setSocket( int socket )
284{
285 delete d;
286 d = new QServerSocketPrivate;
287 d->s = new QSocketDevice( socket, QSocketDevice::Stream );
288 d->n = new QSocketNotifier( d->s->socket(), QSocketNotifier::Read,
289 this, "accepting new connections" );
290 connect( d->n, SIGNAL(activated(int)),
291 this, SLOT(incomingConnection(int)) );
292}
293
294#endif //QT_NO_NETWORK
Note: See TracBrowser for help on using the repository browser.