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

Last change on this file since 846 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 20.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 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 \section1 Symbian Platform Security Requirements
83
84 On Symbian, processes which use this class must have the
85 \c NetworkServices platform security capability. If the client
86 process lacks this capability, it will lead to a panic.
87
88 Platform security capabilities are added via the
89 \l{qmake-variable-reference.html#target-capability}{TARGET.CAPABILITY}
90 qmake variable.
91
92 \sa QTcpSocket, {Fortune Server Example}, {Threaded Fortune Server Example},
93 {Loopback Example}, {Torrent Example}
94*/
95
96/*! \fn void QTcpServer::newConnection()
97
98 This signal is emitted every time a new connection is available.
99
100 \sa hasPendingConnections(), nextPendingConnection()
101*/
102
103#include "private/qobject_p.h"
104#include "qalgorithms.h"
105#include "qhostaddress.h"
106#include "qlist.h"
107#include "qpointer.h"
108#include "qnativesocketengine_p.h"
109#include "qtcpserver.h"
110#include "qtcpsocket.h"
111#include "qnetworkproxy.h"
112
113QT_BEGIN_NAMESPACE
114
115#define Q_CHECK_SOCKETENGINE(returnValue) do { \
116 if (!d->socketEngine) { \
117 return returnValue; \
118 } } while (0)
119
120class QTcpServerPrivate : public QObjectPrivate, public QAbstractSocketEngineReceiver
121{
122 Q_DECLARE_PUBLIC(QTcpServer)
123public:
124 QTcpServerPrivate();
125 ~QTcpServerPrivate();
126
127 QList<QTcpSocket *> pendingConnections;
128
129 quint16 port;
130 QHostAddress address;
131
132 QAbstractSocket::SocketState state;
133 QAbstractSocketEngine *socketEngine;
134
135 QAbstractSocket::SocketError serverSocketError;
136 QString serverSocketErrorString;
137
138 int maxConnections;
139
140#ifndef QT_NO_NETWORKPROXY
141 QNetworkProxy proxy;
142 QNetworkProxy resolveProxy(const QHostAddress &address, quint16 port);
143#endif
144
145 // from QAbstractSocketEngineReceiver
146 void readNotification();
147 inline void writeNotification() {}
148 inline void exceptionNotification() {}
149 inline void connectionNotification() {}
150#ifndef QT_NO_NETWORKPROXY
151 inline void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *) {}
152#endif
153
154};
155
156/*! \internal
157*/
158QTcpServerPrivate::QTcpServerPrivate()
159 : port(0)
160 , state(QAbstractSocket::UnconnectedState)
161 , socketEngine(0)
162 , serverSocketError(QAbstractSocket::UnknownSocketError)
163 , maxConnections(30)
164{
165}
166
167/*! \internal
168*/
169QTcpServerPrivate::~QTcpServerPrivate()
170{
171}
172
173#ifndef QT_NO_NETWORKPROXY
174/*! \internal
175
176 Resolve the proxy to its final value.
177*/
178QNetworkProxy QTcpServerPrivate::resolveProxy(const QHostAddress &address, quint16 port)
179{
180 if (address == QHostAddress::LocalHost ||
181 address == QHostAddress::LocalHostIPv6)
182 return QNetworkProxy::NoProxy;
183
184 QList<QNetworkProxy> proxies;
185 if (proxy.type() != QNetworkProxy::DefaultProxy) {
186 // a non-default proxy was set with setProxy
187 proxies << proxy;
188 } else {
189 // try the application settings instead
190 QNetworkProxyQuery query(port, QString(), QNetworkProxyQuery::TcpServer);
191 proxies = QNetworkProxyFactory::proxyForQuery(query);
192 }
193
194 // return the first that we can use
195 foreach (const QNetworkProxy &p, proxies) {
196 if (p.capabilities() & QNetworkProxy::ListeningCapability)
197 return p;
198 }
199
200 // no proxy found
201 // DefaultProxy will raise an error
202 return QNetworkProxy(QNetworkProxy::DefaultProxy);
203}
204#endif
205
206/*! \internal
207*/
208void QTcpServerPrivate::readNotification()
209{
210 Q_Q(QTcpServer);
211 for (;;) {
212 if (pendingConnections.count() >= maxConnections) {
213#if defined (QTCPSERVER_DEBUG)
214 qDebug("QTcpServerPrivate::_q_processIncomingConnection() too many connections");
215#endif
216 if (socketEngine->isReadNotificationEnabled())
217 socketEngine->setReadNotificationEnabled(false);
218 return;
219 }
220
221 int descriptor = socketEngine->accept();
222 if (descriptor == -1)
223 break;
224#if defined (QTCPSERVER_DEBUG)
225 qDebug("QTcpServerPrivate::_q_processIncomingConnection() accepted socket %i", descriptor);
226#endif
227 q->incomingConnection(descriptor);
228
229 QPointer<QTcpServer> that = q;
230 emit q->newConnection();
231 if (!that || !q->isListening())
232 return;
233 }
234}
235
236/*!
237 Constructs a QTcpServer object.
238
239 \a parent is passed to the QObject constructor.
240
241 \sa listen(), setSocketDescriptor()
242*/
243QTcpServer::QTcpServer(QObject *parent)
244 : QObject(*new QTcpServerPrivate, parent)
245{
246}
247
248/*!
249 Destroys the QTcpServer object. If the server is listening for
250 connections, the socket is automatically closed.
251
252 Any client \l{QTcpSocket}s that are still connected must either
253 disconnect or be reparented before the server is deleted.
254
255 \sa close()
256*/
257QTcpServer::~QTcpServer()
258{
259 close();
260}
261
262/*!
263 Tells the server to listen for incoming connections on address \a
264 address and port \a port. If \a port is 0, a port is chosen
265 automatically. If \a address is QHostAddress::Any, the server
266 will listen on all network interfaces.
267
268 Returns true on success; otherwise returns false.
269
270 \sa isListening()
271*/
272bool QTcpServer::listen(const QHostAddress &address, quint16 port)
273{
274 Q_D(QTcpServer);
275 if (d->state == QAbstractSocket::ListeningState) {
276 qWarning("QTcpServer::listen() called when already listening");
277 return false;
278 }
279
280 QAbstractSocket::NetworkLayerProtocol proto = address.protocol();
281
282#ifdef QT_NO_NETWORKPROXY
283 static const QNetworkProxy &proxy = *(QNetworkProxy *)0;
284#else
285 QNetworkProxy proxy = d->resolveProxy(address, port);
286#endif
287
288 delete d->socketEngine;
289 d->socketEngine = QAbstractSocketEngine::createSocketEngine(QAbstractSocket::TcpSocket, proxy, this);
290 if (!d->socketEngine) {
291 d->serverSocketError = QAbstractSocket::UnsupportedSocketOperationError;
292 d->serverSocketErrorString = tr("Operation on socket is not supported");
293 return false;
294 }
295 if (!d->socketEngine->initialize(QAbstractSocket::TcpSocket, proto)) {
296 d->serverSocketError = d->socketEngine->error();
297 d->serverSocketErrorString = d->socketEngine->errorString();
298 return false;
299 }
300
301#if defined(Q_OS_UNIX)
302 // Under Unix, we want to be able to bind to the port, even if a socket on
303 // the same address-port is in TIME_WAIT. Under Windows this is possible
304 // anyway -- furthermore, the meaning of reusable on Windows is different:
305 // it means that you can use the same address-port for multiple listening
306 // sockets.
307 // Don't abort though if we can't set that option. For example the socks
308 // engine doesn't support that option, but that shouldn't prevent us from
309 // trying to bind/listen.
310 d->socketEngine->setOption(QAbstractSocketEngine::AddressReusable, 1);
311#endif
312
313 if (!d->socketEngine->bind(address, port)) {
314 d->serverSocketError = d->socketEngine->error();
315 d->serverSocketErrorString = d->socketEngine->errorString();
316 return false;
317 }
318
319 if (!d->socketEngine->listen()) {
320 d->serverSocketError = d->socketEngine->error();
321 d->serverSocketErrorString = d->socketEngine->errorString();
322 return false;
323 }
324
325 d->socketEngine->setReceiver(d);
326 d->socketEngine->setReadNotificationEnabled(true);
327
328 d->state = QAbstractSocket::ListeningState;
329 d->address = d->socketEngine->localAddress();
330 d->port = d->socketEngine->localPort();
331
332#if defined (QTCPSERVER_DEBUG)
333 qDebug("QTcpServer::listen(%i, \"%s\") == true (listening on port %i)", port,
334 address.toString().toLatin1().constData(), d->socketEngine->localPort());
335#endif
336 return true;
337}
338
339/*!
340 Returns true if the server is currently listening for incoming
341 connections; otherwise returns false.
342
343 \sa listen()
344*/
345bool QTcpServer::isListening() const
346{
347 Q_D(const QTcpServer);
348 Q_CHECK_SOCKETENGINE(false);
349 return d->socketEngine->state() == QAbstractSocket::ListeningState;
350}
351
352/*!
353 Closes the server. The server will no longer listen for incoming
354 connections.
355
356 \sa listen()
357*/
358void QTcpServer::close()
359{
360 Q_D(QTcpServer);
361
362 qDeleteAll(d->pendingConnections);
363 d->pendingConnections.clear();
364
365 if (d->socketEngine) {
366 d->socketEngine->close();
367 QT_TRY {
368 d->socketEngine->deleteLater();
369 } QT_CATCH(const std::bad_alloc &) {
370 // in out of memory situations, the socketEngine
371 // will be deleted in ~QTcpServer (it's a child-object of this)
372 }
373 d->socketEngine = 0;
374 }
375
376 d->state = QAbstractSocket::UnconnectedState;
377}
378
379/*!
380 Returns the native socket descriptor the server uses to listen
381 for incoming instructions, or -1 if the server is not listening.
382
383 If the server is using QNetworkProxy, the returned descriptor may
384 not be usable with native socket functions.
385
386 \sa setSocketDescriptor(), isListening()
387*/
388int QTcpServer::socketDescriptor() const
389{
390 Q_D(const QTcpServer);
391 Q_CHECK_SOCKETENGINE(-1);
392 return d->socketEngine->socketDescriptor();
393}
394
395/*!
396 Sets the socket descriptor this server should use when listening
397 for incoming connections to \a socketDescriptor. Returns true if
398 the socket is set successfully; otherwise returns false.
399
400 The socket is assumed to be in listening state.
401
402 \sa socketDescriptor(), isListening()
403*/
404bool QTcpServer::setSocketDescriptor(int socketDescriptor)
405{
406 Q_D(QTcpServer);
407 if (isListening()) {
408 qWarning("QTcpServer::setSocketDescriptor() called when already listening");
409 return false;
410 }
411
412 if (d->socketEngine)
413 delete d->socketEngine;
414 d->socketEngine = QAbstractSocketEngine::createSocketEngine(socketDescriptor, this);
415 if (!d->socketEngine->initialize(socketDescriptor, QAbstractSocket::ListeningState)) {
416 d->serverSocketError = d->socketEngine->error();
417 d->serverSocketErrorString = d->socketEngine->errorString();
418#if defined (QTCPSERVER_DEBUG)
419 qDebug("QTcpServer::setSocketDescriptor(%i) failed (%s)", socketDescriptor,
420 d->serverSocketErrorString.toLatin1().constData());
421#endif
422 return false;
423 }
424
425 d->socketEngine->setReceiver(d);
426 d->socketEngine->setReadNotificationEnabled(true);
427
428 d->state = d->socketEngine->state();
429 d->address = d->socketEngine->localAddress();
430 d->port = d->socketEngine->localPort();
431
432#if defined (QTCPSERVER_DEBUG)
433 qDebug("QTcpServer::setSocketDescriptor(%i) succeeded.", socketDescriptor);
434#endif
435 return true;
436}
437
438/*!
439 Returns the server's port if the server is listening for
440 connections; otherwise returns 0.
441
442 \sa serverAddress(), listen()
443*/
444quint16 QTcpServer::serverPort() const
445{
446 Q_D(const QTcpServer);
447 Q_CHECK_SOCKETENGINE(0);
448 return d->socketEngine->localPort();
449}
450
451/*!
452 Returns the server's address if the server is listening for
453 connections; otherwise returns QHostAddress::Null.
454
455 \sa serverPort(), listen()
456*/
457QHostAddress QTcpServer::serverAddress() const
458{
459 Q_D(const QTcpServer);
460 Q_CHECK_SOCKETENGINE(QHostAddress(QHostAddress::Null));
461 return d->socketEngine->localAddress();
462}
463
464/*!
465 Waits for at most \a msec milliseconds or until an incoming
466 connection is available. Returns true if a connection is
467 available; otherwise returns false. If the operation timed out
468 and \a timedOut is not 0, *\a timedOut will be set to true.
469
470 This is a blocking function call. Its use is disadvised in a
471 single-threaded GUI application, since the whole application will
472 stop responding until the function returns.
473 waitForNewConnection() is mostly useful when there is no event
474 loop available.
475
476 The non-blocking alternative is to connect to the newConnection()
477 signal.
478
479 If msec is -1, this function will not time out.
480
481 \sa hasPendingConnections(), nextPendingConnection()
482*/
483bool QTcpServer::waitForNewConnection(int msec, bool *timedOut)
484{
485 Q_D(QTcpServer);
486 if (d->state != QAbstractSocket::ListeningState)
487 return false;
488
489 if (!d->socketEngine->waitForRead(msec, timedOut)) {
490 d->serverSocketError = d->socketEngine->error();
491 d->serverSocketErrorString = d->socketEngine->errorString();
492 return false;
493 }
494
495 if (timedOut && *timedOut)
496 return false;
497
498 d->readNotification();
499
500 return true;
501}
502
503/*!
504 Returns true if the server has a pending connection; otherwise
505 returns false.
506
507 \sa nextPendingConnection(), setMaxPendingConnections()
508*/
509bool QTcpServer::hasPendingConnections() const
510{
511 return !d_func()->pendingConnections.isEmpty();
512}
513
514/*!
515 Returns the next pending connection as a connected QTcpSocket
516 object.
517
518 The socket is created as a child of the server, which means that
519 it is automatically deleted when the QTcpServer object is
520 destroyed. It is still a good idea to delete the object
521 explicitly when you are done with it, to avoid wasting memory.
522
523 0 is returned if this function is called when there are no pending
524 connections.
525
526 \note The returned QTcpSocket object cannot be used from another
527 thread. If you want to use an incoming connection from another thread,
528 you need to override incomingConnection().
529
530 \sa hasPendingConnections()
531*/
532QTcpSocket *QTcpServer::nextPendingConnection()
533{
534 Q_D(QTcpServer);
535 if (d->pendingConnections.isEmpty())
536 return 0;
537
538 if (!d->socketEngine->isReadNotificationEnabled())
539 d->socketEngine->setReadNotificationEnabled(true);
540
541 return d->pendingConnections.takeFirst();
542}
543
544/*!
545 This virtual function is called by QTcpServer when a new
546 connection is available. The \a socketDescriptor argument is the
547 native socket descriptor for the accepted connection.
548
549 The base implementation creates a QTcpSocket, sets the socket
550 descriptor and then stores the QTcpSocket in an internal list of
551 pending connections. Finally newConnection() is emitted.
552
553 Reimplement this function to alter the server's behavior when a
554 connection is available.
555
556 If this server is using QNetworkProxy then the \a socketDescriptor
557 may not be usable with native socket functions, and should only be
558 used with QTcpSocket::setSocketDescriptor().
559
560 \note If you want to handle an incoming connection as a new QTcpSocket
561 object in another thread you have to pass the socketDescriptor
562 to the other thread and create the QTcpSocket object there and
563 use its setSocketDescriptor() method.
564
565 \sa newConnection(), nextPendingConnection(), addPendingConnection()
566*/
567void QTcpServer::incomingConnection(int socketDescriptor)
568{
569#if defined (QTCPSERVER_DEBUG)
570 qDebug("QTcpServer::incomingConnection(%i)", socketDescriptor);
571#endif
572
573 QTcpSocket *socket = new QTcpSocket(this);
574 socket->setSocketDescriptor(socketDescriptor);
575 addPendingConnection(socket);
576}
577
578/*!
579 This function is called by QTcpServer::incomingConnection()
580 to add the \a socket to the list of pending incoming connections.
581
582 \note Don't forget to call this member from reimplemented
583 incomingConnection() if you do not want to break the
584 Pending Connections mechanism.
585
586 \sa incomingConnection()
587 \since 4.7
588*/
589void QTcpServer::addPendingConnection(QTcpSocket* socket)
590{
591 d_func()->pendingConnections.append(socket);
592}
593
594/*!
595 Sets the maximum number of pending accepted connections to \a
596 numConnections. QTcpServer will accept no more than \a
597 numConnections incoming connections before
598 nextPendingConnection() is called. By default, the limit is 30
599 pending connections.
600
601 Clients may still able to connect after the server has reached
602 its maximum number of pending connections (i.e., QTcpSocket can
603 still emit the connected() signal). QTcpServer will stop
604 accepting the new connections, but the operating system may
605 still keep them in queue.
606
607 \sa maxPendingConnections(), hasPendingConnections()
608*/
609void QTcpServer::setMaxPendingConnections(int numConnections)
610{
611 d_func()->maxConnections = numConnections;
612}
613
614/*!
615 Returns the maximum number of pending accepted connections. The
616 default is 30.
617
618 \sa setMaxPendingConnections(), hasPendingConnections()
619*/
620int QTcpServer::maxPendingConnections() const
621{
622 return d_func()->maxConnections;
623}
624
625/*!
626 Returns an error code for the last error that occurred.
627
628 \sa errorString()
629*/
630QAbstractSocket::SocketError QTcpServer::serverError() const
631{
632 return d_func()->serverSocketError;
633}
634
635/*!
636 Returns a human readable description of the last error that
637 occurred.
638
639 \sa serverError()
640*/
641QString QTcpServer::errorString() const
642{
643 return d_func()->serverSocketErrorString;
644}
645
646#ifndef QT_NO_NETWORKPROXY
647/*!
648 \since 4.1
649
650 Sets the explicit network proxy for this socket to \a networkProxy.
651
652 To disable the use of a proxy for this socket, use the
653 QNetworkProxy::NoProxy proxy type:
654
655 \snippet doc/src/snippets/code/src_network_socket_qtcpserver.cpp 0
656
657 \sa proxy(), QNetworkProxy
658*/
659void QTcpServer::setProxy(const QNetworkProxy &networkProxy)
660{
661 Q_D(QTcpServer);
662 d->proxy = networkProxy;
663}
664
665/*!
666 \since 4.1
667
668 Returns the network proxy for this socket.
669 By default QNetworkProxy::DefaultProxy is used.
670
671 \sa setProxy(), QNetworkProxy
672*/
673QNetworkProxy QTcpServer::proxy() const
674{
675 Q_D(const QTcpServer);
676 return d->proxy;
677}
678#endif // QT_NO_NETWORKPROXY
679
680QT_END_NAMESPACE
681
682#include "moc_qtcpserver.cpp"
683
Note: See TracBrowser for help on using the repository browser.