Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qtcpserver.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5//#define QTCPSERVER_DEBUG
6
7/*! \class QTcpServer
8
9 \brief The QTcpServer class provides a TCP-based server.
10
11 \reentrant
12 \ingroup network
13 \inmodule QtNetwork
14
15 This class makes it possible to accept incoming TCP connections.
16 You can specify the port or have QTcpServer pick one
17 automatically. You can listen on a specific address or on all the
18 machine's addresses.
19
20 Call listen() to have the server listen for incoming connections.
21 The newConnection() signal is then emitted each time a client
22 connects to the server. When the client connection has been added
23 to the pending connection queue using the addPendingConnection()
24 function, the pendingConnectionAvailable() signal is emitted.
25
26 Call nextPendingConnection() to accept the pending connection as
27 a connected QTcpSocket. The function returns a pointer to a
28 QTcpSocket in QAbstractSocket::ConnectedState that you can use for
29 communicating with the client.
30
31 If an error occurs, serverError() returns the type of error, and
32 errorString() can be called to get a human readable description of
33 what happened.
34
35 When listening for connections, the address and port on which the
36 server is listening are available as serverAddress() and
37 serverPort().
38
39 Calling close() makes QTcpServer stop listening for incoming
40 connections.
41
42 Although QTcpServer is mostly designed for use with an event
43 loop, it's possible to use it without one. In that case, you must
44 use waitForNewConnection(), which blocks until either a
45 connection is available or a timeout expires.
46
47 \sa QTcpSocket, {Fortune Server}, {Threaded Fortune Server},
48 {Torrent Example}
49*/
50
51/*! \fn void QTcpServer::newConnection()
52
53 This signal is emitted every time a new connection is available, regardless
54 of whether it has been added to the pending connections queue or not.
55
56 \sa hasPendingConnections(), nextPendingConnection()
57*/
58
59/*! \fn void QTcpServer::pendingConnectionAvailable()
60
61 This signal is emitted every time a new connection has been added to the
62 pending connections queue.
63
64 \sa hasPendingConnections(), nextPendingConnection()
65 \since 6.4
66*/
67
68/*! \fn void QTcpServer::acceptError(QAbstractSocket::SocketError socketError)
69 \since 5.0
70
71 This signal is emitted when accepting a new connection results in an error.
72 The \a socketError parameter describes the type of error that occurred.
73
74 \sa pauseAccepting(), resumeAccepting()
75*/
76
77#include "qtcpserver.h"
78#include "qtcpserver_p.h"
79
80#include "qalgorithms.h"
81#include "qhostaddress.h"
82#include "qlist.h"
83#include "qpointer.h"
85#include "qtcpsocket.h"
86#include "qnetworkproxy.h"
87
89
90#define Q_CHECK_SOCKETENGINE(returnValue) do {
91 if (!d->socketEngine) {
92 return returnValue;
93 } } while (0)
94
95/*! \internal
96*/
97QTcpServerPrivate::QTcpServerPrivate()
98 : port(0)
99 , socketType(QAbstractSocket::UnknownSocketType)
100 , state(QAbstractSocket::UnconnectedState)
101 , socketEngine(nullptr)
102 , serverSocketError(QAbstractSocket::UnknownSocketError)
103 , maxConnections(30)
104{
105}
106
107/*! \internal
108*/
109QTcpServerPrivate::~QTcpServerPrivate()
110{
111}
112
113#ifndef QT_NO_NETWORKPROXY
114/*! \internal
115
116 Resolve the proxy to its final value.
117*/
118QNetworkProxy QTcpServerPrivate::resolveProxy(const QHostAddress &address, quint16 port)
119{
120 if (address.isLoopback())
121 return QNetworkProxy::NoProxy;
122
123 QList<QNetworkProxy> proxies;
124 if (proxy.type() != QNetworkProxy::DefaultProxy) {
125 // a non-default proxy was set with setProxy
126 proxies << proxy;
127 } else {
128 // try the application settings instead
129 QNetworkProxyQuery query(port, QString(),
130 socketType == QAbstractSocket::SctpSocket ?
131 QNetworkProxyQuery::SctpServer :
132 QNetworkProxyQuery::TcpServer);
133 proxies = QNetworkProxyFactory::proxyForQuery(query);
134 }
135
136 // return the first that we can use
137 for (const QNetworkProxy &p : std::as_const(proxies)) {
138 if (socketType == QAbstractSocket::TcpSocket &&
139 (p.capabilities() & QNetworkProxy::ListeningCapability) != 0)
140 return p;
141
142 if (socketType == QAbstractSocket::SctpSocket &&
143 (p.capabilities() & QNetworkProxy::SctpListeningCapability) != 0)
144 return p;
145 }
146
147 // no proxy found
148 // DefaultProxy will raise an error
149 return QNetworkProxy(QNetworkProxy::DefaultProxy);
150}
151#endif
152
153/*! \internal
154*/
155void QTcpServerPrivate::configureCreatedSocket()
156{
157#if defined(Q_OS_UNIX)
158 // Under Unix, we want to be able to bind to the port, even if a socket on
159 // the same address-port is in TIME_WAIT. Under Windows this is possible
160 // anyway -- furthermore, the meaning of reusable on Windows is different:
161 // it means that you can use the same address-port for multiple listening
162 // sockets.
163 // Don't abort though if we can't set that option. For example the socks
164 // engine doesn't support that option, but that shouldn't prevent us from
165 // trying to bind/listen.
166 socketEngine->setOption(QAbstractSocketEngine::AddressReusable, 1);
167#endif
168}
169
170/*! \internal
171*/
172void QTcpServerPrivate::readNotification()
173{
174 Q_Q(QTcpServer);
175 for (;;) {
176 if (totalPendingConnections() >= maxConnections) {
177#if defined (QTCPSERVER_DEBUG)
178 qDebug("QTcpServerPrivate::_q_processIncomingConnection() too many connections");
179#endif
180 if (socketEngine->isReadNotificationEnabled())
181 socketEngine->setReadNotificationEnabled(false);
182 return;
183 }
184
185 qintptr descriptor = socketEngine->accept();
186 if (descriptor == -1) {
187 if (socketEngine->error() != QAbstractSocket::TemporaryError) {
188 q->pauseAccepting();
189 serverSocketError = socketEngine->error();
190 serverSocketErrorString = socketEngine->errorString();
191 emit q->acceptError(serverSocketError);
192 }
193 break;
194 }
195#if defined (QTCPSERVER_DEBUG)
196 qDebug("QTcpServerPrivate::_q_processIncomingConnection() accepted socket %i", descriptor);
197#endif
198 QPointer<QTcpServer> that = q;
199 q->incomingConnection(descriptor);
200
201 if (that)
202 emit q->newConnection();
203
204 if (!that || !q->isListening())
205 return;
206 }
207}
208
209/*!
210 \internal
211 Return the amount of sockets currently in queue for the server.
212 This is to make maxPendingConnections work properly with servers that don't
213 necessarily have 'ready-to-go' sockets as soon as they connect,
214 e.g. QSslServer.
215 By default we just return pendingConnections.size(), which is equivalent to
216 what it did before.
217*/
218int QTcpServerPrivate::totalPendingConnections() const
219{
220 return int(pendingConnections.size());
221}
222
223/*!
224 Constructs a QTcpServer object.
225
226 \a parent is passed to the QObject constructor.
227
228 \sa listen(), setSocketDescriptor()
229*/
230QTcpServer::QTcpServer(QObject *parent)
231 : QObject(*new QTcpServerPrivate, parent)
232{
233 Q_D(QTcpServer);
234#if defined(QTCPSERVER_DEBUG)
235 qDebug("QTcpServer::QTcpServer(%p)", parent);
236#endif
237 d->socketType = QAbstractSocket::TcpSocket;
238}
239
240/*!
241 Destroys the QTcpServer object. If the server is listening for
242 connections, the socket is automatically closed.
243
244 Any client \l{QTcpSocket}s that are still connected must either
245 disconnect or be reparented before the server is deleted.
246
247 \sa close()
248*/
249QTcpServer::~QTcpServer()
250{
251#if defined(QTCPSERVER_DEBUG)
252 qDebug("QTcpServer::~QTcpServer()");
253#endif
254 close();
255}
256
257/*! \internal
258
259 Constructs a new server object with socket of type \a socketType. The \a
260 parent argument is passed to QObject's constructor.
261*/
262QTcpServer::QTcpServer(QAbstractSocket::SocketType socketType, QTcpServerPrivate &dd,
263 QObject *parent) : QObject(dd, parent)
264{
265 Q_D(QTcpServer);
266#if defined(QTCPSERVER_DEBUG)
267 qDebug("QTcpServer::QTcpServer(%sSocket, QTcpServerPrivate == %p, parent == %p)",
268 socketType == QAbstractSocket::TcpSocket ? "Tcp"
269 : socketType == QAbstractSocket::UdpSocket ? "Udp"
270 : socketType == QAbstractSocket::SctpSocket ? "Sctp"
271 : "Unknown", &dd, parent);
272#endif
273 d->socketType = socketType;
274}
275
276/*!
277 Tells the server to listen for incoming connections on address \a
278 address and port \a port. If \a port is 0, a port is chosen
279 automatically. If \a address is QHostAddress::Any, the server
280 will listen on all network interfaces.
281
282 Returns \c true on success; otherwise returns \c false.
283
284 \sa isListening()
285*/
286bool QTcpServer::listen(const QHostAddress &address, quint16 port)
287{
288 Q_D(QTcpServer);
289 if (d->state == QAbstractSocket::ListeningState) {
290 qWarning("QTcpServer::listen() called when already listening");
291 return false;
292 }
293
294 QAbstractSocket::NetworkLayerProtocol proto = address.protocol();
295 QHostAddress addr = address;
296
297#ifdef QT_NO_NETWORKPROXY
298 static const QNetworkProxy &proxy = *(QNetworkProxy *)0;
299#else
300 QNetworkProxy proxy = d->resolveProxy(addr, port);
301#endif
302
303 delete d->socketEngine;
304 d->socketEngine = QAbstractSocketEngine::createSocketEngine(d->socketType, proxy, this);
305 if (!d->socketEngine) {
306 d->serverSocketError = QAbstractSocket::UnsupportedSocketOperationError;
307 d->serverSocketErrorString = tr("Operation on socket is not supported");
308 return false;
309 }
310 if (!d->socketEngine->initialize(d->socketType, proto)) {
311 d->serverSocketError = d->socketEngine->error();
312 d->serverSocketErrorString = d->socketEngine->errorString();
313 return false;
314 }
315 proto = d->socketEngine->protocol();
316 if (addr.protocol() == QAbstractSocket::AnyIPProtocol && proto == QAbstractSocket::IPv4Protocol)
317 addr = QHostAddress::AnyIPv4;
318
319 d->configureCreatedSocket();
320
321 if (!d->socketEngine->bind(addr, port)) {
322 d->serverSocketError = d->socketEngine->error();
323 d->serverSocketErrorString = d->socketEngine->errorString();
324 return false;
325 }
326
327 if (!d->socketEngine->listen(d->listenBacklog)) {
328 d->serverSocketError = d->socketEngine->error();
329 d->serverSocketErrorString = d->socketEngine->errorString();
330 return false;
331 }
332
333 d->socketEngine->setReceiver(d);
334 d->socketEngine->setReadNotificationEnabled(true);
335
336 d->state = QAbstractSocket::ListeningState;
337 d->address = d->socketEngine->localAddress();
338 d->port = d->socketEngine->localPort();
339
340#if defined (QTCPSERVER_DEBUG)
341 qDebug("QTcpServer::listen(%i, \"%s\") == true (listening on port %i)", port,
342 address.toString().toLatin1().constData(), d->socketEngine->localPort());
343#endif
344 return true;
345}
346
347/*!
348 Returns \c true if the server is currently listening for incoming
349 connections; otherwise returns \c false.
350
351 \sa listen()
352*/
353bool QTcpServer::isListening() const
354{
355 Q_D(const QTcpServer);
357 return d->socketEngine->state() == QAbstractSocket::ListeningState;
358}
359
360/*!
361 Closes the server. The server will no longer listen for incoming
362 connections.
363
364 \sa listen()
365*/
366void QTcpServer::close()
367{
368 Q_D(QTcpServer);
369
370 qDeleteAll(d->pendingConnections);
371 d->pendingConnections.clear();
372
373 if (d->socketEngine) {
374 d->socketEngine->close();
375 QT_TRY {
376 d->socketEngine->deleteLater();
377 } QT_CATCH(const std::bad_alloc &) {
378 // in out of memory situations, the socketEngine
379 // will be deleted in ~QTcpServer (it's a child-object of this)
380 }
381 d->socketEngine = nullptr;
382 }
383
384 d->state = QAbstractSocket::UnconnectedState;
385}
386
387/*!
388 Returns the native socket descriptor the server uses to listen
389 for incoming instructions, or -1 if the server is not listening.
390
391 If the server is using QNetworkProxy, the returned descriptor may
392 not be usable with native socket functions.
393
394 \sa setSocketDescriptor(), isListening()
395*/
396qintptr QTcpServer::socketDescriptor() const
397{
398 Q_D(const QTcpServer);
400 return d->socketEngine->socketDescriptor();
401}
402
403/*!
404 Sets the socket descriptor this server should use when listening
405 for incoming connections to \a socketDescriptor. Returns \c true if
406 the socket is set successfully; otherwise returns \c false.
407
408 The socket is assumed to be in listening state.
409
410 \sa socketDescriptor(), isListening()
411*/
412bool QTcpServer::setSocketDescriptor(qintptr socketDescriptor)
413{
414 Q_D(QTcpServer);
415 if (isListening()) {
416 qWarning("QTcpServer::setSocketDescriptor() called when already listening");
417 return false;
418 }
419
420 if (d->socketEngine)
421 delete d->socketEngine;
422 d->socketEngine = QAbstractSocketEngine::createSocketEngine(socketDescriptor, this);
423 if (!d->socketEngine) {
424 d->serverSocketError = QAbstractSocket::UnsupportedSocketOperationError;
425 d->serverSocketErrorString = tr("Operation on socket is not supported");
426 return false;
427 }
428 if (!d->socketEngine->initialize(socketDescriptor, QAbstractSocket::ListeningState)) {
429 d->serverSocketError = d->socketEngine->error();
430 d->serverSocketErrorString = d->socketEngine->errorString();
431#if defined (QTCPSERVER_DEBUG)
432 qDebug("QTcpServer::setSocketDescriptor(%i) failed (%s)", socketDescriptor,
433 d->serverSocketErrorString.toLatin1().constData());
434#endif
435 return false;
436 }
437
438 d->socketEngine->setReceiver(d);
439 d->socketEngine->setReadNotificationEnabled(true);
440
441 d->state = d->socketEngine->state();
442 d->address = d->socketEngine->localAddress();
443 d->port = d->socketEngine->localPort();
444
445#if defined (QTCPSERVER_DEBUG)
446 qDebug("QTcpServer::setSocketDescriptor(%i) succeeded.", socketDescriptor);
447#endif
448 return true;
449}
450
451/*!
452 Returns the server's port if the server is listening for
453 connections; otherwise returns 0.
454
455 \sa serverAddress(), listen()
456*/
457quint16 QTcpServer::serverPort() const
458{
459 Q_D(const QTcpServer);
461 return d->socketEngine->localPort();
462}
463
464/*!
465 Returns the server's address if the server is listening for
466 connections; otherwise returns QHostAddress::Null.
467
468 \sa serverPort(), listen()
469*/
470QHostAddress QTcpServer::serverAddress() const
471{
472 Q_D(const QTcpServer);
473 Q_CHECK_SOCKETENGINE(QHostAddress(QHostAddress::Null));
474 return d->socketEngine->localAddress();
475}
476
477/*!
478 Waits for at most \a msec milliseconds or until an incoming
479 connection is available. Returns \c true if a connection is
480 available; otherwise returns \c false. If the operation timed out
481 and \a timedOut is not \nullptr, *\a timedOut will be set to true.
482
483 This is a blocking function call. Its use is disadvised in a
484 single-threaded GUI application, since the whole application will
485 stop responding until the function returns.
486 waitForNewConnection() is mostly useful when there is no event
487 loop available.
488
489 The non-blocking alternative is to connect to the newConnection()
490 signal.
491
492 If msec is -1, this function will not time out.
493
494 \sa hasPendingConnections(), nextPendingConnection()
495*/
496bool QTcpServer::waitForNewConnection(int msec, bool *timedOut)
497{
498 Q_D(QTcpServer);
499 if (d->state != QAbstractSocket::ListeningState)
500 return false;
501
502 if (!d->socketEngine->waitForRead(QDeadlineTimer(msec), timedOut)) {
503 d->serverSocketError = d->socketEngine->error();
504 d->serverSocketErrorString = d->socketEngine->errorString();
505 return false;
506 }
507
508 if (timedOut && *timedOut)
509 return false;
510
511 d->readNotification();
512
513 return true;
514}
515
516/*!
517 Returns \c true if the server has a pending connection; otherwise
518 returns \c false.
519
520 \sa nextPendingConnection(), setMaxPendingConnections()
521*/
522bool QTcpServer::hasPendingConnections() const
523{
524 return !d_func()->pendingConnections.isEmpty();
525}
526
527/*!
528 Returns the next pending connection as a connected QTcpSocket
529 object.
530
531 The socket is created as a child of the server, which means that
532 it is automatically deleted when the QTcpServer object is
533 destroyed. It is still a good idea to delete the object
534 explicitly when you are done with it, to avoid wasting memory.
535
536 \nullptr is returned if this function is called when there are no pending
537 connections.
538
539 \note The returned QTcpSocket object cannot be used from another
540 thread. If you want to use an incoming connection from another thread,
541 you need to override incomingConnection().
542
543 \sa hasPendingConnections()
544*/
545QTcpSocket *QTcpServer::nextPendingConnection()
546{
547 Q_D(QTcpServer);
548 if (d->pendingConnections.isEmpty())
549 return nullptr;
550
551 if (!d->socketEngine) {
552 qWarning("QTcpServer::nextPendingConnection() called while not listening");
553 } else if (!d->socketEngine->isReadNotificationEnabled()) {
554 d->socketEngine->setReadNotificationEnabled(true);
555 }
556
557 return d->pendingConnections.takeFirst();
558}
559
560/*!
561 This virtual function is called by QTcpServer when a new
562 connection is available. The \a socketDescriptor argument is the
563 native socket descriptor for the accepted connection.
564
565 The base implementation creates a QTcpSocket, sets the socket
566 descriptor and then stores the QTcpSocket in an internal list of
567 pending connections. Finally newConnection() is emitted.
568
569 Reimplement this function to alter the server's behavior when a
570 connection is available.
571
572 If this server is using QNetworkProxy then the \a socketDescriptor
573 may not be usable with native socket functions, and should only be
574 used with QTcpSocket::setSocketDescriptor().
575
576 \note If another socket is created in the reimplementation
577 of this method, it needs to be added to the Pending Connections mechanism
578 by calling addPendingConnection().
579
580 \note If you want to handle an incoming connection as a new QTcpSocket
581 object in another thread you have to pass the socketDescriptor
582 to the other thread and create the QTcpSocket object there and
583 use its setSocketDescriptor() method.
584
585 \sa newConnection(), nextPendingConnection(), addPendingConnection()
586*/
587void QTcpServer::incomingConnection(qintptr socketDescriptor)
588{
589#if defined (QTCPSERVER_DEBUG)
590 qDebug("QTcpServer::incomingConnection(%i)", socketDescriptor);
591#endif
592
593 QTcpSocket *socket = new QTcpSocket(this);
594 socket->setSocketDescriptor(socketDescriptor);
595 addPendingConnection(socket);
596}
597
598/*!
599 This function is called by QTcpServer::incomingConnection()
600 to add the \a socket to the list of pending incoming connections.
601
602 \note Don't forget to call this member from reimplemented
603 incomingConnection() if you do not want to break the
604 Pending Connections mechanism. This function emits the
605 pendingConnectionAvailable() signal after the socket has been
606 added.
607
608 \sa incomingConnection(), pendingConnectionAvailable()
609 \since 4.7
610*/
611void QTcpServer::addPendingConnection(QTcpSocket* socket)
612{
613 d_func()->pendingConnections.append(socket);
614 emit pendingConnectionAvailable(QPrivateSignal());
615}
616
617/*!
618 Sets the maximum number of pending accepted connections to \a
619 numConnections. QTcpServer will accept no more than \a
620 numConnections incoming connections before
621 nextPendingConnection() is called. By default, the limit is 30
622 pending connections.
623
624 Clients may still able to connect after the server has reached
625 its maximum number of pending connections (i.e., QTcpSocket can
626 still emit the connected() signal). QTcpServer will stop
627 accepting the new connections, but the operating system may
628 still keep them in queue.
629
630 \sa maxPendingConnections(), hasPendingConnections()
631*/
632void QTcpServer::setMaxPendingConnections(int numConnections)
633{
634 d_func()->maxConnections = numConnections;
635}
636
637/*!
638 Returns the maximum number of pending accepted connections. The
639 default is 30.
640
641 \sa setMaxPendingConnections(), hasPendingConnections()
642*/
643int QTcpServer::maxPendingConnections() const
644{
645 return d_func()->maxConnections;
646}
647
648/*!
649 Sets the backlog queue size of to be accepted connections to \a
650 size. The operating system might reduce or ignore this value.
651 By default, the queue size is 50.
652
653 \note This property must be set prior to calling listen().
654
655 \since 6.3
656
657 \sa listenBacklogSize()
658*/
659void QTcpServer::setListenBacklogSize(int size)
660{
661 d_func()->listenBacklog = size;
662}
663
664/*!
665 Returns the backlog queue size of to be accepted connections.
666
667 \since 6.3
668
669 \sa setListenBacklogSize()
670*/
671int QTcpServer::listenBacklogSize() const
672{
673 return d_func()->listenBacklog;
674}
675
676/*!
677 Returns an error code for the last error that occurred.
678
679 \sa errorString()
680*/
681QAbstractSocket::SocketError QTcpServer::serverError() const
682{
683 return d_func()->serverSocketError;
684}
685
686/*!
687 Returns a human readable description of the last error that
688 occurred.
689
690 \sa serverError()
691*/
692QString QTcpServer::errorString() const
693{
694 return d_func()->serverSocketErrorString;
695}
696
697/*!
698 \since 5.0
699
700 Pauses accepting new connections. Queued connections will remain in queue.
701
702 \sa resumeAccepting()
703*/
704void QTcpServer::pauseAccepting()
705{
706 d_func()->socketEngine->setReadNotificationEnabled(false);
707}
708
709/*!
710 \since 5.0
711
712 Resumes accepting new connections.
713
714 \sa pauseAccepting()
715*/
716void QTcpServer::resumeAccepting()
717{
718 d_func()->socketEngine->setReadNotificationEnabled(true);
719}
720
721#ifndef QT_NO_NETWORKPROXY
722/*!
723 \since 4.1
724
725 Sets the explicit network proxy for this socket to \a networkProxy.
726
727 To disable the use of a proxy for this socket, use the
728 QNetworkProxy::NoProxy proxy type:
729
730 \snippet code/src_network_socket_qtcpserver.cpp 0
731
732 \sa proxy(), QNetworkProxy
733*/
734void QTcpServer::setProxy(const QNetworkProxy &networkProxy)
735{
736 Q_D(QTcpServer);
737 d->proxy = networkProxy;
738}
739
740/*!
741 \since 4.1
742
743 Returns the network proxy for this socket.
744 By default QNetworkProxy::DefaultProxy is used.
745
746 \sa setProxy(), QNetworkProxy
747*/
748QNetworkProxy QTcpServer::proxy() const
749{
750 Q_D(const QTcpServer);
751 return d->proxy;
752}
753#endif // QT_NO_NETWORKPROXY
754
755QT_END_NAMESPACE
756
757#include "moc_qtcpserver.cpp"
#define Q_CHECK_SOCKETENGINE(returnValue)