source: trunk/src/network/socket/qtcpserver.cpp@ 564

Last change on this file since 564 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 19.0 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtNetwork module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42//#define QTCPSERVER_DEBUG
43
44/*! \class QTcpServer
45
46 \brief The QTcpServer class provides a TCP-based server.
47
48 \reentrant
49 \ingroup network
50 \inmodule QtNetwork
51
52 This class makes it possible to accept incoming TCP connections.
53 You can specify the port or have QTcpServer pick one
54 automatically. You can listen on a specific address or on all the
55 machine's addresses.
56
57 Call listen() to have the server listen for incoming connections.
58 The newConnection() signal is then emitted each time a client
59 connects to the server.
60
61 Call nextPendingConnection() to accept the pending connection as
62 a connected QTcpSocket. The function returns a pointer to a
63 QTcpSocket in QAbstractSocket::ConnectedState that you can use for
64 communicating with the client.
65
66 If an error occurs, serverError() returns the type of error, and
67 errorString() can be called to get a human readable description of
68 what happened.
69
70 When listening for connections, the address and port on which the
71 server is listening are available as serverAddress() and
72 serverPort().
73
74 Calling close() makes QTcpServer stop listening for incoming
75 connections.
76
77 Although QTcpServer is mostly designed for use with an event
78 loop, it's possible to use it without one. In that case, you must
79 use waitForNewConnection(), which blocks until either a
80 connection is available or a timeout expires.
81
82 \sa QTcpSocket, {Fortune Server Example}, {Threaded Fortune Server Example},
83 {Loopback Example}, {Torrent Example}
84*/
85
86/*! \fn void QTcpServer::newConnection()
87
88 This signal is emitted every time a new connection is available.
89
90 \sa hasPendingConnections(), nextPendingConnection()
91*/
92
93#include "private/qobject_p.h"
94#include "qalgorithms.h"
95#include "qhostaddress.h"
96#include "qlist.h"
97#include "qpointer.h"
98#include "qnativesocketengine_p.h"
99#include "qtcpserver.h"
100#include "qtcpsocket.h"
101#include "qnetworkproxy.h"
102
103QT_BEGIN_NAMESPACE
104
105#define Q_CHECK_SOCKETENGINE(returnValue) do { \
106 if (!d->socketEngine) { \
107 return returnValue; \
108 } } while (0)
109
110class QTcpServerPrivate : public QObjectPrivate, public QAbstractSocketEngineReceiver
111{
112 Q_DECLARE_PUBLIC(QTcpServer)
113public:
114 QTcpServerPrivate();
115 ~QTcpServerPrivate();
116
117 QList<QTcpSocket *> pendingConnections;
118
119 quint16 port;
120 QHostAddress address;
121
122 QAbstractSocket::SocketState state;
123 QAbstractSocketEngine *socketEngine;
124
125 QAbstractSocket::SocketError serverSocketError;
126 QString serverSocketErrorString;
127
128 int maxConnections;
129
130#ifndef QT_NO_NETWORKPROXY
131 QNetworkProxy proxy;
132 QNetworkProxy resolveProxy(const QHostAddress &address, quint16 port);
133#endif
134
135 // from QAbstractSocketEngineReceiver
136 void readNotification();
137 inline void writeNotification() {}
138 inline void exceptionNotification() {}
139 inline void connectionNotification() {}
140#ifndef QT_NO_NETWORKPROXY
141 inline void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *) {}
142#endif
143
144};
145
146/*! \internal
147*/
148QTcpServerPrivate::QTcpServerPrivate()
149 : port(0)
150 , state(QAbstractSocket::UnconnectedState)
151 , socketEngine(0)
152 , serverSocketError(QAbstractSocket::UnknownSocketError)
153 , maxConnections(30)
154{
155}
156
157/*! \internal
158*/
159QTcpServerPrivate::~QTcpServerPrivate()
160{
161}
162
163#ifndef QT_NO_NETWORKPROXY
164/*! \internal
165
166 Resolve the proxy to its final value.
167*/
168QNetworkProxy QTcpServerPrivate::resolveProxy(const QHostAddress &address, quint16 port)
169{
170 if (address == QHostAddress::LocalHost ||
171 address == QHostAddress::LocalHostIPv6)
172 return QNetworkProxy::NoProxy;
173
174 QList<QNetworkProxy> proxies;
175 if (proxy.type() != QNetworkProxy::DefaultProxy) {
176 // a non-default proxy was set with setProxy
177 proxies << proxy;
178 } else {
179 // try the application settings instead
180 QNetworkProxyQuery query(port, QString(), QNetworkProxyQuery::TcpServer);
181 proxies = QNetworkProxyFactory::proxyForQuery(query);
182 }
183
184 // return the first that we can use
185 foreach (const QNetworkProxy &p, proxies) {
186 if (p.capabilities() & QNetworkProxy::ListeningCapability)
187 return p;
188 }
189
190 // no proxy found
191 // DefaultProxy will raise an error
192 return QNetworkProxy(QNetworkProxy::DefaultProxy);
193}
194#endif
195
196/*! \internal
197*/
198void QTcpServerPrivate::readNotification()
199{
200 Q_Q(QTcpServer);
201 for (;;) {
202 if (pendingConnections.count() >= maxConnections) {
203#if defined (QTCPSERVER_DEBUG)
204 qDebug("QTcpServerPrivate::_q_processIncomingConnection() too many connections");
205#endif
206 if (socketEngine->isReadNotificationEnabled())
207 socketEngine->setReadNotificationEnabled(false);
208 return;
209 }
210
211 int descriptor = socketEngine->accept();
212 if (descriptor == -1)
213 break;
214#if defined (QTCPSERVER_DEBUG)
215 qDebug("QTcpServerPrivate::_q_processIncomingConnection() accepted socket %i", descriptor);
216#endif
217 q->incomingConnection(descriptor);
218
219 QPointer<QTcpServer> that = q;
220 emit q->newConnection();
221 if (!that || !q->isListening())
222 return;
223 }
224}
225
226/*!
227 Constructs a QTcpServer object.
228
229 \a parent is passed to the QObject constructor.
230
231 \sa listen(), setSocketDescriptor()
232*/
233QTcpServer::QTcpServer(QObject *parent)
234 : QObject(*new QTcpServerPrivate, parent)
235{
236}
237
238/*!
239 Destroys the QTcpServer object. If the server is listening for
240 connections, the socket is automatically closed.
241
242 Any client \l{QTcpSocket}s that are still connected must either
243 disconnect or be reparented before the server is deleted.
244
245 \sa close()
246*/
247QTcpServer::~QTcpServer()
248{
249 close();
250}
251
252/*!
253 Tells the server to listen for incoming connections on address \a
254 address and port \a port. If \a port is 0, a port is chosen
255 automatically. If \a address is QHostAddress::Any, the server
256 will listen on all network interfaces.
257
258 Returns true on success; otherwise returns false.
259
260 \sa isListening()
261*/
262bool QTcpServer::listen(const QHostAddress &address, quint16 port)
263{
264 Q_D(QTcpServer);
265 if (d->state == QAbstractSocket::ListeningState) {
266 qWarning("QTcpServer::listen() called when already listening");
267 return false;
268 }
269
270 QAbstractSocket::NetworkLayerProtocol proto = address.protocol();
271
272#ifdef QT_NO_NETWORKPROXY
273 static const QNetworkProxy &proxy = *(QNetworkProxy *)0;
274#else
275 QNetworkProxy proxy = d->resolveProxy(address, port);
276#endif
277
278 delete d->socketEngine;
279 d->socketEngine = QAbstractSocketEngine::createSocketEngine(QAbstractSocket::TcpSocket, proxy, this);
280 if (!d->socketEngine) {
281 d->serverSocketError = QAbstractSocket::UnsupportedSocketOperationError;
282 d->serverSocketErrorString = tr("Operation on socket is not supported");
283 return false;
284 }
285 if (!d->socketEngine->initialize(QAbstractSocket::TcpSocket, proto)) {
286 d->serverSocketError = d->socketEngine->error();
287 d->serverSocketErrorString = d->socketEngine->errorString();
288 return false;
289 }
290
291#if defined(Q_OS_UNIX)
292 // Under Unix, we want to be able to bind to the port, even if a socket on
293 // the same address-port is in TIME_WAIT. Under Windows this is possible
294 // anyway -- furthermore, the meaning of reusable on Windows is different:
295 // it means that you can use the same address-port for multiple listening
296 // sockets.
297 // Don't abort though if we can't set that option. For example the socks
298 // engine doesn't support that option, but that shouldn't prevent us from
299 // trying to bind/listen.
300 d->socketEngine->setOption(QAbstractSocketEngine::AddressReusable, 1);
301#endif
302
303 if (!d->socketEngine->bind(address, port)) {
304 d->serverSocketError = d->socketEngine->error();
305 d->serverSocketErrorString = d->socketEngine->errorString();
306 return false;
307 }
308
309 if (!d->socketEngine->listen()) {
310 d->serverSocketError = d->socketEngine->error();
311 d->serverSocketErrorString = d->socketEngine->errorString();
312 return false;
313 }
314
315 d->socketEngine->setReceiver(d);
316 d->socketEngine->setReadNotificationEnabled(true);
317
318 d->state = QAbstractSocket::ListeningState;
319 d->address = d->socketEngine->localAddress();
320 d->port = d->socketEngine->localPort();
321
322#if defined (QTCPSERVER_DEBUG)
323 qDebug("QTcpServer::listen(%i, \"%s\") == true (listening on port %i)", port,
324 address.toString().toLatin1().constData(), d->socketEngine->localPort());
325#endif
326 return true;
327}
328
329/*!
330 Returns true if the server is currently listening for incoming
331 connections; otherwise returns false.
332
333 \sa listen()
334*/
335bool QTcpServer::isListening() const
336{
337 Q_D(const QTcpServer);
338 Q_CHECK_SOCKETENGINE(false);
339 return d->socketEngine->state() == QAbstractSocket::ListeningState;
340}
341
342/*!
343 Closes the server. The server will no longer listen for incoming
344 connections.
345
346 \sa listen()
347*/
348void QTcpServer::close()
349{
350 Q_D(QTcpServer);
351
352 qDeleteAll(d->pendingConnections);
353 d->pendingConnections.clear();
354
355 if (d->socketEngine) {
356 d->socketEngine->close();
357 QT_TRY {
358 d->socketEngine->deleteLater();
359 } QT_CATCH(const std::bad_alloc &) {
360 // in out of memory situations, the socketEngine
361 // will be deleted in ~QTcpServer (it's a child-object of this)
362 }
363 d->socketEngine = 0;
364 }
365
366 d->state = QAbstractSocket::UnconnectedState;
367}
368
369/*!
370 Returns the native socket descriptor the server uses to listen
371 for incoming instructions, or -1 if the server is not listening.
372
373 If the server is using QNetworkProxy, the returned descriptor may
374 not be usable with native socket functions.
375
376 \sa setSocketDescriptor(), isListening()
377*/
378int QTcpServer::socketDescriptor() const
379{
380 Q_D(const QTcpServer);
381 Q_CHECK_SOCKETENGINE(-1);
382 return d->socketEngine->socketDescriptor();
383}
384
385/*!
386 Sets the socket descriptor this server should use when listening
387 for incoming connections to \a socketDescriptor. Returns true if
388 the socket is set successfully; otherwise returns false.
389
390 The socket is assumed to be in listening state.
391
392 \sa socketDescriptor(), isListening()
393*/
394bool QTcpServer::setSocketDescriptor(int socketDescriptor)
395{
396 Q_D(QTcpServer);
397 if (isListening()) {
398 qWarning("QTcpServer::setSocketDescriptor() called when already listening");
399 return false;
400 }
401
402 if (d->socketEngine)
403 delete d->socketEngine;
404 d->socketEngine = QAbstractSocketEngine::createSocketEngine(socketDescriptor, this);
405 if (!d->socketEngine->initialize(socketDescriptor, QAbstractSocket::ListeningState)) {
406 d->serverSocketError = d->socketEngine->error();
407 d->serverSocketErrorString = d->socketEngine->errorString();
408#if defined (QTCPSERVER_DEBUG)
409 qDebug("QTcpServer::setSocketDescriptor(%i) failed (%s)", socketDescriptor,
410 d->serverSocketErrorString.toLatin1().constData());
411#endif
412 return false;
413 }
414
415 d->socketEngine->setReceiver(d);
416 d->socketEngine->setReadNotificationEnabled(true);
417
418 d->state = d->socketEngine->state();
419 d->address = d->socketEngine->localAddress();
420 d->port = d->socketEngine->localPort();
421
422#if defined (QTCPSERVER_DEBUG)
423 qDebug("QTcpServer::setSocketDescriptor(%i) succeeded.", socketDescriptor);
424#endif
425 return true;
426}
427
428/*!
429 Returns the server's port if the server is listening for
430 connections; otherwise returns 0.
431
432 \sa serverAddress(), listen()
433*/
434quint16 QTcpServer::serverPort() const
435{
436 Q_D(const QTcpServer);
437 Q_CHECK_SOCKETENGINE(0);
438 return d->socketEngine->localPort();
439}
440
441/*!
442 Returns the server's address if the server is listening for
443 connections; otherwise returns QHostAddress::Null.
444
445 \sa serverPort(), listen()
446*/
447QHostAddress QTcpServer::serverAddress() const
448{
449 Q_D(const QTcpServer);
450 Q_CHECK_SOCKETENGINE(QHostAddress(QHostAddress::Null));
451 return d->socketEngine->localAddress();
452}
453
454/*!
455 Waits for at most \a msec milliseconds or until an incoming
456 connection is available. Returns true if a connection is
457 available; otherwise returns false. If the operation timed out
458 and \a timedOut is not 0, *\a timedOut will be set to true.
459
460 This is a blocking function call. Its use is disadvised in a
461 single-threaded GUI application, since the whole application will
462 stop responding until the function returns.
463 waitForNewConnection() is mostly useful when there is no event
464 loop available.
465
466 The non-blocking alternative is to connect to the newConnection()
467 signal.
468
469 If msec is -1, this function will not time out.
470
471 \sa hasPendingConnections(), nextPendingConnection()
472*/
473bool QTcpServer::waitForNewConnection(int msec, bool *timedOut)
474{
475 Q_D(QTcpServer);
476 if (d->state != QAbstractSocket::ListeningState)
477 return false;
478
479 if (!d->socketEngine->waitForRead(msec, timedOut)) {
480 d->serverSocketError = d->socketEngine->error();
481 d->serverSocketErrorString = d->socketEngine->errorString();
482 return false;
483 }
484
485 if (timedOut && *timedOut)
486 return false;
487
488 d->readNotification();
489
490 return true;
491}
492
493/*!
494 Returns true if the server has a pending connection; otherwise
495 returns false.
496
497 \sa nextPendingConnection(), setMaxPendingConnections()
498*/
499bool QTcpServer::hasPendingConnections() const
500{
501 return !d_func()->pendingConnections.isEmpty();
502}
503
504/*!
505 Returns the next pending connection as a connected QTcpSocket
506 object.
507
508 The socket is created as a child of the server, which means that
509 it is automatically deleted when the QTcpServer object is
510 destroyed. It is still a good idea to delete the object
511 explicitly when you are done with it, to avoid wasting memory.
512
513 0 is returned if this function is called when there are no pending
514 connections.
515
516 \sa hasPendingConnections()
517*/
518QTcpSocket *QTcpServer::nextPendingConnection()
519{
520 Q_D(QTcpServer);
521 if (d->pendingConnections.isEmpty())
522 return 0;
523
524 if (!d->socketEngine->isReadNotificationEnabled())
525 d->socketEngine->setReadNotificationEnabled(true);
526
527 return d->pendingConnections.takeFirst();
528}
529
530/*!
531 This virtual function is called by QTcpServer when a new
532 connection is available. The \a socketDescriptor argument is the
533 native socket descriptor for the accepted connection.
534
535 The base implementation creates a QTcpSocket, sets the socket
536 descriptor and then stores the QTcpSocket in an internal list of
537 pending connections. Finally newConnection() is emitted.
538
539 Reimplement this function to alter the server's behavior when a
540 connection is available.
541
542 If this server is using QNetworkProxy then the \a socketDescriptor
543 may not be usable with native socket functions, and should only be
544 used with QTcpSocket::setSocketDescriptor().
545
546 \sa newConnection(), nextPendingConnection()
547*/
548void QTcpServer::incomingConnection(int socketDescriptor)
549{
550#if defined (QTCPSERVER_DEBUG)
551 qDebug("QTcpServer::incomingConnection(%i)", socketDescriptor);
552#endif
553
554 QTcpSocket *socket = new QTcpSocket(this);
555 socket->setSocketDescriptor(socketDescriptor);
556 d_func()->pendingConnections.append(socket);
557}
558
559/*!
560 Sets the maximum number of pending accepted connections to \a
561 numConnections. QTcpServer will accept no more than \a
562 numConnections incoming connections before
563 nextPendingConnection() is called. By default, the limit is 30
564 pending connections.
565
566 Clients may still able to connect after the server has reached
567 its maximum number of pending connections (i.e., QTcpSocket can
568 still emit the connected() signal). QTcpServer will stop
569 accepting the new connections, but the operating system may
570 still keep them in queue.
571
572 \sa maxPendingConnections(), hasPendingConnections()
573*/
574void QTcpServer::setMaxPendingConnections(int numConnections)
575{
576 d_func()->maxConnections = numConnections;
577}
578
579/*!
580 Returns the maximum number of pending accepted connections. The
581 default is 30.
582
583 \sa setMaxPendingConnections(), hasPendingConnections()
584*/
585int QTcpServer::maxPendingConnections() const
586{
587 return d_func()->maxConnections;
588}
589
590/*!
591 Returns an error code for the last error that occurred.
592
593 \sa errorString()
594*/
595QAbstractSocket::SocketError QTcpServer::serverError() const
596{
597 return d_func()->serverSocketError;
598}
599
600/*!
601 Returns a human readable description of the last error that
602 occurred.
603
604 \sa serverError()
605*/
606QString QTcpServer::errorString() const
607{
608 return d_func()->serverSocketErrorString;
609}
610
611#ifndef QT_NO_NETWORKPROXY
612/*!
613 \since 4.1
614
615 Sets the explicit network proxy for this socket to \a networkProxy.
616
617 To disable the use of a proxy for this socket, use the
618 QNetworkProxy::NoProxy proxy type:
619
620 \snippet doc/src/snippets/code/src_network_socket_qtcpserver.cpp 0
621
622 \sa proxy(), QNetworkProxy
623*/
624void QTcpServer::setProxy(const QNetworkProxy &networkProxy)
625{
626 Q_D(QTcpServer);
627 d->proxy = networkProxy;
628}
629
630/*!
631 \since 4.1
632
633 Returns the network proxy for this socket.
634 By default QNetworkProxy::DefaultProxy is used.
635
636 \sa setProxy(), QNetworkProxy
637*/
638QNetworkProxy QTcpServer::proxy() const
639{
640 Q_D(const QTcpServer);
641 return d->proxy;
642}
643#endif // QT_NO_NETWORKPROXY
644
645QT_END_NAMESPACE
646
647#include "moc_qtcpserver.cpp"
648
Note: See TracBrowser for help on using the repository browser.