~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/qt3support/network/q3serversocket.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
 
4
**
 
5
** This file is part of the Qt 3 compatibility classes of the Qt Toolkit.
 
6
**
 
7
** This file may be distributed under the terms of the Q Public License
 
8
** as defined by Trolltech AS of Norway and appearing in the file
 
9
** LICENSE.QPL included in the packaging of this file.
 
10
**
 
11
** This file may be distributed and/or modified under the terms of the
 
12
** GNU General Public License version 2 as published by the Free Software
 
13
** Foundation and appearing in the file LICENSE.GPL included in the
 
14
** packaging of this file.
 
15
**
 
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
 
17
**   information about Qt Commercial License Agreements.
 
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
 
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
 
20
**
 
21
** Contact info@trolltech.com if any conditions of this licensing are
 
22
** not clear to you.
 
23
**
 
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
26
**
 
27
****************************************************************************/
 
28
 
 
29
#include "q3serversocket.h"
 
30
 
 
31
#ifndef QT_NO_NETWORK
 
32
 
 
33
#include "qsocketnotifier.h"
 
34
 
 
35
class Q3ServerSocketPrivate {
 
36
public:
 
37
    Q3ServerSocketPrivate(): s(0), n(0) {}
 
38
    ~Q3ServerSocketPrivate() { delete n; delete s; }
 
39
    Q3SocketDevice *s;
 
40
    QSocketNotifier *n;
 
41
};
 
42
 
 
43
 
 
44
/*!
 
45
    \class Q3ServerSocket qserversocket.h
 
46
    \brief The Q3ServerSocket class provides a TCP-based server.
 
47
 
 
48
    \compat
 
49
 
 
50
    This class is a convenience class for accepting incoming TCP
 
51
    connections. You can specify the port or have Q3ServerSocket pick
 
52
    one, and listen on just one address or on all the machine's
 
53
    addresses.
 
54
 
 
55
    Using the API is very simple: subclass Q3ServerSocket, call the
 
56
    constructor of your choice, and implement newConnection() to
 
57
    handle new incoming connections. There is nothing more to do.
 
58
 
 
59
    (Note that due to lack of support in the underlying APIs,
 
60
    Q3ServerSocket cannot accept or reject connections conditionally.)
 
61
 
 
62
    \sa Q3Socket, Q3SocketDevice, QHostAddress, QSocketNotifier
 
63
*/
 
64
 
 
65
 
 
66
/*!
 
67
    Creates a server socket object, that will serve the given \a port
 
68
    on all the addresses of this host. If \a port is 0, Q3ServerSocket
 
69
    will pick a suitable port in a system-dependent manner. Use \a
 
70
    backlog to specify how many pending connections the server can
 
71
    have.
 
72
 
 
73
    The \a parent and \a name arguments are passed on to the QObject
 
74
    constructor.
 
75
 
 
76
    \warning On Tru64 Unix systems a value of 0 for \a backlog means
 
77
    that you don't accept any connections at all; you should specify a
 
78
    value larger than 0.
 
79
*/
 
80
 
 
81
Q3ServerSocket::Q3ServerSocket( Q_UINT16 port, int backlog,
 
82
                              QObject *parent, const char *name )
 
83
    : QObject( parent, name )
 
84
{
 
85
    d = new Q3ServerSocketPrivate;
 
86
    init( QHostAddress(), port, backlog );
 
87
}
 
88
 
 
89
 
 
90
/*!
 
91
    Creates a server socket object, that will serve the given \a port
 
92
    only on the given \a address. Use \a backlog to specify how many
 
93
    pending connections the server can have.
 
94
 
 
95
    The \a parent and \a name arguments are passed on to the QObject
 
96
    constructor.
 
97
 
 
98
    \warning On Tru64 Unix systems a value of 0 for \a backlog means
 
99
    that you don't accept any connections at all; you should specify a
 
100
    value larger than 0.
 
101
*/
 
102
 
 
103
Q3ServerSocket::Q3ServerSocket( const QHostAddress & address, Q_UINT16 port,
 
104
                              int backlog,
 
105
                              QObject *parent, const char *name )
 
106
    : QObject( parent, name )
 
107
{
 
108
    d = new Q3ServerSocketPrivate;
 
109
    init( address, port, backlog );
 
110
}
 
111
 
 
112
 
 
113
/*!
 
114
    Construct an empty server socket.
 
115
 
 
116
    This constructor, in combination with setSocket(), allows us to
 
117
    use the Q3ServerSocket class as a wrapper for other socket types
 
118
    (e.g. Unix Domain Sockets under Unix).
 
119
 
 
120
    The \a parent and \a name arguments are passed on to the QObject
 
121
    constructor.
 
122
 
 
123
    \sa setSocket()
 
124
*/
 
125
 
 
126
Q3ServerSocket::Q3ServerSocket( QObject *parent, const char *name )
 
127
    : QObject( parent, name )
 
128
{
 
129
    d = new Q3ServerSocketPrivate;
 
130
}
 
131
 
 
132
 
 
133
/*!
 
134
    Returns true if the construction succeeded; otherwise returns false.
 
135
*/
 
136
bool Q3ServerSocket::ok() const
 
137
{
 
138
    return !!d->s;
 
139
}
 
140
 
 
141
/*
 
142
  The common bit of the constructors.
 
143
 */
 
144
void Q3ServerSocket::init( const QHostAddress & address, Q_UINT16 port, int backlog )
 
145
{
 
146
    d->s = new Q3SocketDevice( Q3SocketDevice::Stream, address.isIPv4Address()
 
147
                              ? Q3SocketDevice::IPv4 : Q3SocketDevice::IPv6, 0 );
 
148
#if !defined(Q_OS_WIN32)
 
149
    // Under Unix, we want to be able to use the port, even if a socket on the
 
150
    // same address-port is in TIME_WAIT. Under Windows this is possible anyway
 
151
    // -- furthermore, the meaning of reusable is different: it means that you
 
152
    // can use the same address-port for multiple listening sockets.
 
153
    d->s->setAddressReusable( true );
 
154
#endif
 
155
    if ( d->s->bind( address, port )
 
156
      && d->s->listen( backlog ) )
 
157
    {
 
158
        d->n = new QSocketNotifier( d->s->socket(), QSocketNotifier::Read,
 
159
                                    this, "accepting new connections" );
 
160
        connect( d->n, SIGNAL(activated(int)),
 
161
                 this, SLOT(incomingConnection(int)) );
 
162
    } else {
 
163
        qWarning( "Q3ServerSocket: failed to bind or listen to the socket" );
 
164
        delete d->s;
 
165
        d->s = 0;
 
166
    }
 
167
}
 
168
 
 
169
 
 
170
/*!
 
171
    Destroys the socket.
 
172
 
 
173
    This causes any backlogged connections (connections that have
 
174
    reached the host, but not yet been completely set up by calling
 
175
    Q3SocketDevice::accept()) to be severed.
 
176
 
 
177
    Existing connections continue to exist; this only affects the
 
178
    acceptance of new connections.
 
179
*/
 
180
Q3ServerSocket::~Q3ServerSocket()
 
181
{
 
182
    delete d;
 
183
}
 
184
 
 
185
 
 
186
/*!
 
187
    \fn void Q3ServerSocket::newConnection( int socket )
 
188
 
 
189
    This pure virtual function is responsible for setting up a new
 
190
    incoming connection. \a socket is the fd (file descriptor) for the
 
191
    newly accepted connection.
 
192
*/
 
193
 
 
194
 
 
195
void Q3ServerSocket::incomingConnection( int )
 
196
{
 
197
    int fd = d->s->accept();
 
198
    if ( fd >= 0 )
 
199
        newConnection( fd );
 
200
}
 
201
 
 
202
 
 
203
/*!
 
204
    Returns the port number on which this server socket listens. This
 
205
    is always non-zero; if you specify 0 in the constructor,
 
206
    Q3ServerSocket will pick a non-zero port itself. ok() must be true
 
207
    before calling this function.
 
208
 
 
209
    \sa address() Q3SocketDevice::port()
 
210
*/
 
211
Q_UINT16 Q3ServerSocket::port() const
 
212
{
 
213
    if ( !d || !d->s )
 
214
        return 0;
 
215
    return d->s->port();
 
216
}
 
217
 
 
218
 
 
219
/*!
 
220
    Returns the operating system socket.
 
221
*/
 
222
int Q3ServerSocket::socket() const
 
223
{
 
224
    if ( !d || !d->s )
 
225
        return -1;
 
226
 
 
227
    return d->s->socket();
 
228
}
 
229
 
 
230
/*!
 
231
    Returns the address on which this object listens, or 0.0.0.0 if
 
232
    this object listens on more than one address. ok() must be true
 
233
    before calling this function.
 
234
 
 
235
    \sa port() Q3SocketDevice::address()
 
236
*/
 
237
QHostAddress Q3ServerSocket::address() const
 
238
{
 
239
    if ( !d || !d->s )
 
240
        return QHostAddress();
 
241
 
 
242
    return d->s->address();
 
243
}
 
244
 
 
245
 
 
246
/*!
 
247
    Returns a pointer to the internal socket device. The returned
 
248
    pointer is 0 if there is no connection or pending connection.
 
249
 
 
250
    There is normally no need to manipulate the socket device directly
 
251
    since this class does all the necessary setup for most client or
 
252
    server socket applications.
 
253
*/
 
254
Q3SocketDevice *Q3ServerSocket::socketDevice()
 
255
{
 
256
    if ( !d )
 
257
        return 0;
 
258
 
 
259
    return d->s;
 
260
}
 
261
 
 
262
 
 
263
/*!
 
264
    Sets the socket to use \a socket. bind() and listen() should
 
265
    already have been called for \a socket.
 
266
 
 
267
    This allows us to use the Q3ServerSocket class as a wrapper for
 
268
    other socket types (e.g. Unix Domain Sockets).
 
269
*/
 
270
void Q3ServerSocket::setSocket( int socket )
 
271
{
 
272
    delete d;
 
273
    d = new Q3ServerSocketPrivate;
 
274
    d->s = new Q3SocketDevice( socket, Q3SocketDevice::Stream );
 
275
    d->n = new QSocketNotifier( d->s->socket(), QSocketNotifier::Read,
 
276
               this, "accepting new connections" );
 
277
    connect( d->n, SIGNAL(activated(int)),
 
278
             this, SLOT(incomingConnection(int)) );
 
279
}
 
280
 
 
281
#endif //QT_NO_NETWORK