758 lines
22 KiB
C++
758 lines
22 KiB
C++
// Copyright (C) 2016 The Qt Company Ltd.
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
|
|
|
//#define QTCPSERVER_DEBUG
|
|
|
|
/*! \class QTcpServer
|
|
|
|
\brief The QTcpServer class provides a TCP-based server.
|
|
|
|
\reentrant
|
|
\ingroup network
|
|
\inmodule QtNetwork
|
|
|
|
This class makes it possible to accept incoming TCP connections.
|
|
You can specify the port or have QTcpServer pick one
|
|
automatically. You can listen on a specific address or on all the
|
|
machine's addresses.
|
|
|
|
Call listen() to have the server listen for incoming connections.
|
|
The newConnection() signal is then emitted each time a client
|
|
connects to the server. When the client connection has been added
|
|
to the pending connection queue using the addPendingConnection()
|
|
function, the pendingConnectionAvailable() signal is emitted.
|
|
|
|
Call nextPendingConnection() to accept the pending connection as
|
|
a connected QTcpSocket. The function returns a pointer to a
|
|
QTcpSocket in QAbstractSocket::ConnectedState that you can use for
|
|
communicating with the client.
|
|
|
|
If an error occurs, serverError() returns the type of error, and
|
|
errorString() can be called to get a human readable description of
|
|
what happened.
|
|
|
|
When listening for connections, the address and port on which the
|
|
server is listening are available as serverAddress() and
|
|
serverPort().
|
|
|
|
Calling close() makes QTcpServer stop listening for incoming
|
|
connections.
|
|
|
|
Although QTcpServer is mostly designed for use with an event
|
|
loop, it's possible to use it without one. In that case, you must
|
|
use waitForNewConnection(), which blocks until either a
|
|
connection is available or a timeout expires.
|
|
|
|
\sa QTcpSocket, {Fortune Server}, {Threaded Fortune Server},
|
|
{Torrent Example}
|
|
*/
|
|
|
|
/*! \fn void QTcpServer::newConnection()
|
|
|
|
This signal is emitted every time a new connection is available, regardless
|
|
of whether it has been added to the pending connections queue or not.
|
|
|
|
\sa hasPendingConnections(), nextPendingConnection()
|
|
*/
|
|
|
|
/*! \fn void QTcpServer::pendingConnectionAvailable()
|
|
|
|
This signal is emitted every time a new connection has been added to the
|
|
pending connections queue.
|
|
|
|
\sa hasPendingConnections(), nextPendingConnection()
|
|
\since 6.4
|
|
*/
|
|
|
|
/*! \fn void QTcpServer::acceptError(QAbstractSocket::SocketError socketError)
|
|
\since 5.0
|
|
|
|
This signal is emitted when accepting a new connection results in an error.
|
|
The \a socketError parameter describes the type of error that occurred.
|
|
|
|
\sa pauseAccepting(), resumeAccepting()
|
|
*/
|
|
|
|
#include "qtcpserver.h"
|
|
#include "qtcpserver_p.h"
|
|
|
|
#include "qalgorithms.h"
|
|
#include "qhostaddress.h"
|
|
#include "qlist.h"
|
|
#include "qpointer.h"
|
|
#include "qabstractsocketengine_p.h"
|
|
#include "qtcpsocket.h"
|
|
#include "qnetworkproxy.h"
|
|
|
|
QT_BEGIN_NAMESPACE
|
|
|
|
#define Q_CHECK_SOCKETENGINE(returnValue) do { \
|
|
if (!d->socketEngine) { \
|
|
return returnValue; \
|
|
} } while (0)
|
|
|
|
/*! \internal
|
|
*/
|
|
QTcpServerPrivate::QTcpServerPrivate()
|
|
: port(0)
|
|
, socketType(QAbstractSocket::UnknownSocketType)
|
|
, state(QAbstractSocket::UnconnectedState)
|
|
, socketEngine(nullptr)
|
|
, serverSocketError(QAbstractSocket::UnknownSocketError)
|
|
, maxConnections(30)
|
|
{
|
|
}
|
|
|
|
/*! \internal
|
|
*/
|
|
QTcpServerPrivate::~QTcpServerPrivate()
|
|
{
|
|
}
|
|
|
|
#ifndef QT_NO_NETWORKPROXY
|
|
/*! \internal
|
|
|
|
Resolve the proxy to its final value.
|
|
*/
|
|
QNetworkProxy QTcpServerPrivate::resolveProxy(const QHostAddress &address, quint16 port)
|
|
{
|
|
if (address.isLoopback())
|
|
return QNetworkProxy::NoProxy;
|
|
|
|
QList<QNetworkProxy> proxies;
|
|
if (proxy.type() != QNetworkProxy::DefaultProxy) {
|
|
// a non-default proxy was set with setProxy
|
|
proxies << proxy;
|
|
} else {
|
|
// try the application settings instead
|
|
QNetworkProxyQuery query(port, QString(),
|
|
socketType == QAbstractSocket::SctpSocket ?
|
|
QNetworkProxyQuery::SctpServer :
|
|
QNetworkProxyQuery::TcpServer);
|
|
proxies = QNetworkProxyFactory::proxyForQuery(query);
|
|
}
|
|
|
|
// return the first that we can use
|
|
for (const QNetworkProxy &p : std::as_const(proxies)) {
|
|
if (socketType == QAbstractSocket::TcpSocket &&
|
|
(p.capabilities() & QNetworkProxy::ListeningCapability) != 0)
|
|
return p;
|
|
|
|
if (socketType == QAbstractSocket::SctpSocket &&
|
|
(p.capabilities() & QNetworkProxy::SctpListeningCapability) != 0)
|
|
return p;
|
|
}
|
|
|
|
// no proxy found
|
|
// DefaultProxy will raise an error
|
|
return QNetworkProxy(QNetworkProxy::DefaultProxy);
|
|
}
|
|
#endif
|
|
|
|
/*! \internal
|
|
*/
|
|
void QTcpServerPrivate::configureCreatedSocket()
|
|
{
|
|
#if defined(Q_OS_UNIX)
|
|
// Under Unix, we want to be able to bind to the port, even if a socket on
|
|
// the same address-port is in TIME_WAIT. Under Windows this is possible
|
|
// anyway -- furthermore, the meaning of reusable on Windows is different:
|
|
// it means that you can use the same address-port for multiple listening
|
|
// sockets.
|
|
// Don't abort though if we can't set that option. For example the socks
|
|
// engine doesn't support that option, but that shouldn't prevent us from
|
|
// trying to bind/listen.
|
|
socketEngine->setOption(QAbstractSocketEngine::AddressReusable, 1);
|
|
#endif
|
|
}
|
|
|
|
/*! \internal
|
|
*/
|
|
void QTcpServerPrivate::readNotification()
|
|
{
|
|
Q_Q(QTcpServer);
|
|
for (;;) {
|
|
if (totalPendingConnections() >= maxConnections) {
|
|
#if defined (QTCPSERVER_DEBUG)
|
|
qDebug("QTcpServerPrivate::_q_processIncomingConnection() too many connections");
|
|
#endif
|
|
if (socketEngine->isReadNotificationEnabled())
|
|
socketEngine->setReadNotificationEnabled(false);
|
|
return;
|
|
}
|
|
|
|
qintptr descriptor = socketEngine->accept();
|
|
if (descriptor == -1) {
|
|
if (socketEngine->error() != QAbstractSocket::TemporaryError) {
|
|
q->pauseAccepting();
|
|
serverSocketError = socketEngine->error();
|
|
serverSocketErrorString = socketEngine->errorString();
|
|
emit q->acceptError(serverSocketError);
|
|
}
|
|
break;
|
|
}
|
|
#if defined (QTCPSERVER_DEBUG)
|
|
qDebug("QTcpServerPrivate::_q_processIncomingConnection() accepted socket %i", descriptor);
|
|
#endif
|
|
QPointer<QTcpServer> that = q;
|
|
q->incomingConnection(descriptor);
|
|
|
|
if (that)
|
|
emit q->newConnection();
|
|
|
|
if (!that || !q->isListening())
|
|
return;
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\internal
|
|
Return the amount of sockets currently in queue for the server.
|
|
This is to make maxPendingConnections work properly with servers that don't
|
|
necessarily have 'ready-to-go' sockets as soon as they connect,
|
|
e.g. QSslServer.
|
|
By default we just return pendingConnections.size(), which is equivalent to
|
|
what it did before.
|
|
*/
|
|
int QTcpServerPrivate::totalPendingConnections() const
|
|
{
|
|
return int(pendingConnections.size());
|
|
}
|
|
|
|
/*!
|
|
Constructs a QTcpServer object.
|
|
|
|
\a parent is passed to the QObject constructor.
|
|
|
|
\sa listen(), setSocketDescriptor()
|
|
*/
|
|
QTcpServer::QTcpServer(QObject *parent)
|
|
: QObject(*new QTcpServerPrivate, parent)
|
|
{
|
|
Q_D(QTcpServer);
|
|
#if defined(QTCPSERVER_DEBUG)
|
|
qDebug("QTcpServer::QTcpServer(%p)", parent);
|
|
#endif
|
|
d->socketType = QAbstractSocket::TcpSocket;
|
|
}
|
|
|
|
/*!
|
|
Destroys the QTcpServer object. If the server is listening for
|
|
connections, the socket is automatically closed.
|
|
|
|
Any client \l{QTcpSocket}s that are still connected must either
|
|
disconnect or be reparented before the server is deleted.
|
|
|
|
\sa close()
|
|
*/
|
|
QTcpServer::~QTcpServer()
|
|
{
|
|
#if defined(QTCPSERVER_DEBUG)
|
|
qDebug("QTcpServer::~QTcpServer()");
|
|
#endif
|
|
close();
|
|
}
|
|
|
|
/*! \internal
|
|
|
|
Constructs a new server object with socket of type \a socketType. The \a
|
|
parent argument is passed to QObject's constructor.
|
|
*/
|
|
QTcpServer::QTcpServer(QAbstractSocket::SocketType socketType, QTcpServerPrivate &dd,
|
|
QObject *parent) : QObject(dd, parent)
|
|
{
|
|
Q_D(QTcpServer);
|
|
#if defined(QTCPSERVER_DEBUG)
|
|
qDebug("QTcpServer::QTcpServer(%sSocket, QTcpServerPrivate == %p, parent == %p)",
|
|
socketType == QAbstractSocket::TcpSocket ? "Tcp"
|
|
: socketType == QAbstractSocket::UdpSocket ? "Udp"
|
|
: socketType == QAbstractSocket::SctpSocket ? "Sctp"
|
|
: "Unknown", &dd, parent);
|
|
#endif
|
|
d->socketType = socketType;
|
|
}
|
|
|
|
/*!
|
|
Tells the server to listen for incoming connections on address \a
|
|
address and port \a port. If \a port is 0, a port is chosen
|
|
automatically. If \a address is QHostAddress::Any, the server
|
|
will listen on all network interfaces.
|
|
|
|
Returns \c true on success; otherwise returns \c false.
|
|
|
|
\sa isListening()
|
|
*/
|
|
bool QTcpServer::listen(const QHostAddress &address, quint16 port)
|
|
{
|
|
Q_D(QTcpServer);
|
|
if (d->state == QAbstractSocket::ListeningState) {
|
|
qWarning("QTcpServer::listen() called when already listening");
|
|
return false;
|
|
}
|
|
|
|
QAbstractSocket::NetworkLayerProtocol proto = address.protocol();
|
|
QHostAddress addr = address;
|
|
|
|
#ifdef QT_NO_NETWORKPROXY
|
|
static const QNetworkProxy &proxy = *(QNetworkProxy *)0;
|
|
#else
|
|
QNetworkProxy proxy = d->resolveProxy(addr, port);
|
|
#endif
|
|
|
|
delete d->socketEngine;
|
|
d->socketEngine = QAbstractSocketEngine::createSocketEngine(d->socketType, proxy, this);
|
|
if (!d->socketEngine) {
|
|
d->serverSocketError = QAbstractSocket::UnsupportedSocketOperationError;
|
|
d->serverSocketErrorString = tr("Operation on socket is not supported");
|
|
return false;
|
|
}
|
|
if (!d->socketEngine->initialize(d->socketType, proto)) {
|
|
d->serverSocketError = d->socketEngine->error();
|
|
d->serverSocketErrorString = d->socketEngine->errorString();
|
|
return false;
|
|
}
|
|
proto = d->socketEngine->protocol();
|
|
if (addr.protocol() == QAbstractSocket::AnyIPProtocol && proto == QAbstractSocket::IPv4Protocol)
|
|
addr = QHostAddress::AnyIPv4;
|
|
|
|
d->configureCreatedSocket();
|
|
|
|
if (!d->socketEngine->bind(addr, port)) {
|
|
d->serverSocketError = d->socketEngine->error();
|
|
d->serverSocketErrorString = d->socketEngine->errorString();
|
|
return false;
|
|
}
|
|
|
|
if (!d->socketEngine->listen(d->listenBacklog)) {
|
|
d->serverSocketError = d->socketEngine->error();
|
|
d->serverSocketErrorString = d->socketEngine->errorString();
|
|
return false;
|
|
}
|
|
|
|
d->socketEngine->setReceiver(d);
|
|
d->socketEngine->setReadNotificationEnabled(true);
|
|
|
|
d->state = QAbstractSocket::ListeningState;
|
|
d->address = d->socketEngine->localAddress();
|
|
d->port = d->socketEngine->localPort();
|
|
|
|
#if defined (QTCPSERVER_DEBUG)
|
|
qDebug("QTcpServer::listen(%i, \"%s\") == true (listening on port %i)", port,
|
|
address.toString().toLatin1().constData(), d->socketEngine->localPort());
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
/*!
|
|
Returns \c true if the server is currently listening for incoming
|
|
connections; otherwise returns \c false.
|
|
|
|
\sa listen()
|
|
*/
|
|
bool QTcpServer::isListening() const
|
|
{
|
|
Q_D(const QTcpServer);
|
|
Q_CHECK_SOCKETENGINE(false);
|
|
return d->socketEngine->state() == QAbstractSocket::ListeningState;
|
|
}
|
|
|
|
/*!
|
|
Closes the server. The server will no longer listen for incoming
|
|
connections.
|
|
|
|
\sa listen()
|
|
*/
|
|
void QTcpServer::close()
|
|
{
|
|
Q_D(QTcpServer);
|
|
|
|
qDeleteAll(d->pendingConnections);
|
|
d->pendingConnections.clear();
|
|
|
|
if (d->socketEngine) {
|
|
d->socketEngine->close();
|
|
QT_TRY {
|
|
d->socketEngine->deleteLater();
|
|
} QT_CATCH(const std::bad_alloc &) {
|
|
// in out of memory situations, the socketEngine
|
|
// will be deleted in ~QTcpServer (it's a child-object of this)
|
|
}
|
|
d->socketEngine = nullptr;
|
|
}
|
|
|
|
d->state = QAbstractSocket::UnconnectedState;
|
|
}
|
|
|
|
/*!
|
|
Returns the native socket descriptor the server uses to listen
|
|
for incoming instructions, or -1 if the server is not listening.
|
|
|
|
If the server is using QNetworkProxy, the returned descriptor may
|
|
not be usable with native socket functions.
|
|
|
|
\sa setSocketDescriptor(), isListening()
|
|
*/
|
|
qintptr QTcpServer::socketDescriptor() const
|
|
{
|
|
Q_D(const QTcpServer);
|
|
Q_CHECK_SOCKETENGINE(-1);
|
|
return d->socketEngine->socketDescriptor();
|
|
}
|
|
|
|
/*!
|
|
Sets the socket descriptor this server should use when listening
|
|
for incoming connections to \a socketDescriptor. Returns \c true if
|
|
the socket is set successfully; otherwise returns \c false.
|
|
|
|
The socket is assumed to be in listening state.
|
|
|
|
\sa socketDescriptor(), isListening()
|
|
*/
|
|
bool QTcpServer::setSocketDescriptor(qintptr socketDescriptor)
|
|
{
|
|
Q_D(QTcpServer);
|
|
if (isListening()) {
|
|
qWarning("QTcpServer::setSocketDescriptor() called when already listening");
|
|
return false;
|
|
}
|
|
|
|
if (d->socketEngine)
|
|
delete d->socketEngine;
|
|
d->socketEngine = QAbstractSocketEngine::createSocketEngine(socketDescriptor, this);
|
|
if (!d->socketEngine) {
|
|
d->serverSocketError = QAbstractSocket::UnsupportedSocketOperationError;
|
|
d->serverSocketErrorString = tr("Operation on socket is not supported");
|
|
return false;
|
|
}
|
|
if (!d->socketEngine->initialize(socketDescriptor, QAbstractSocket::ListeningState)) {
|
|
d->serverSocketError = d->socketEngine->error();
|
|
d->serverSocketErrorString = d->socketEngine->errorString();
|
|
#if defined (QTCPSERVER_DEBUG)
|
|
qDebug("QTcpServer::setSocketDescriptor(%i) failed (%s)", socketDescriptor,
|
|
d->serverSocketErrorString.toLatin1().constData());
|
|
#endif
|
|
return false;
|
|
}
|
|
|
|
d->socketEngine->setReceiver(d);
|
|
d->socketEngine->setReadNotificationEnabled(true);
|
|
|
|
d->state = d->socketEngine->state();
|
|
d->address = d->socketEngine->localAddress();
|
|
d->port = d->socketEngine->localPort();
|
|
|
|
#if defined (QTCPSERVER_DEBUG)
|
|
qDebug("QTcpServer::setSocketDescriptor(%i) succeeded.", socketDescriptor);
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
/*!
|
|
Returns the server's port if the server is listening for
|
|
connections; otherwise returns 0.
|
|
|
|
\sa serverAddress(), listen()
|
|
*/
|
|
quint16 QTcpServer::serverPort() const
|
|
{
|
|
Q_D(const QTcpServer);
|
|
Q_CHECK_SOCKETENGINE(0);
|
|
return d->socketEngine->localPort();
|
|
}
|
|
|
|
/*!
|
|
Returns the server's address if the server is listening for
|
|
connections; otherwise returns QHostAddress::Null.
|
|
|
|
\sa serverPort(), listen()
|
|
*/
|
|
QHostAddress QTcpServer::serverAddress() const
|
|
{
|
|
Q_D(const QTcpServer);
|
|
Q_CHECK_SOCKETENGINE(QHostAddress(QHostAddress::Null));
|
|
return d->socketEngine->localAddress();
|
|
}
|
|
|
|
/*!
|
|
Waits for at most \a msec milliseconds or until an incoming
|
|
connection is available. Returns \c true if a connection is
|
|
available; otherwise returns \c false. If the operation timed out
|
|
and \a timedOut is not \nullptr, *\a timedOut will be set to true.
|
|
|
|
This is a blocking function call. Its use is disadvised in a
|
|
single-threaded GUI application, since the whole application will
|
|
stop responding until the function returns.
|
|
waitForNewConnection() is mostly useful when there is no event
|
|
loop available.
|
|
|
|
The non-blocking alternative is to connect to the newConnection()
|
|
signal.
|
|
|
|
If msec is -1, this function will not time out.
|
|
|
|
\sa hasPendingConnections(), nextPendingConnection()
|
|
*/
|
|
bool QTcpServer::waitForNewConnection(int msec, bool *timedOut)
|
|
{
|
|
Q_D(QTcpServer);
|
|
if (d->state != QAbstractSocket::ListeningState)
|
|
return false;
|
|
|
|
if (!d->socketEngine->waitForRead(QDeadlineTimer(msec), timedOut)) {
|
|
d->serverSocketError = d->socketEngine->error();
|
|
d->serverSocketErrorString = d->socketEngine->errorString();
|
|
return false;
|
|
}
|
|
|
|
if (timedOut && *timedOut)
|
|
return false;
|
|
|
|
d->readNotification();
|
|
|
|
return true;
|
|
}
|
|
|
|
/*!
|
|
Returns \c true if the server has a pending connection; otherwise
|
|
returns \c false.
|
|
|
|
\sa nextPendingConnection(), setMaxPendingConnections()
|
|
*/
|
|
bool QTcpServer::hasPendingConnections() const
|
|
{
|
|
return !d_func()->pendingConnections.isEmpty();
|
|
}
|
|
|
|
/*!
|
|
Returns the next pending connection as a connected QTcpSocket
|
|
object.
|
|
|
|
The socket is created as a child of the server, which means that
|
|
it is automatically deleted when the QTcpServer object is
|
|
destroyed. It is still a good idea to delete the object
|
|
explicitly when you are done with it, to avoid wasting memory.
|
|
|
|
\nullptr is returned if this function is called when there are no pending
|
|
connections.
|
|
|
|
\note The returned QTcpSocket object cannot be used from another
|
|
thread. If you want to use an incoming connection from another thread,
|
|
you need to override incomingConnection().
|
|
|
|
\sa hasPendingConnections()
|
|
*/
|
|
QTcpSocket *QTcpServer::nextPendingConnection()
|
|
{
|
|
Q_D(QTcpServer);
|
|
if (d->pendingConnections.isEmpty())
|
|
return nullptr;
|
|
|
|
if (!d->socketEngine) {
|
|
qWarning("QTcpServer::nextPendingConnection() called while not listening");
|
|
} else if (!d->socketEngine->isReadNotificationEnabled()) {
|
|
d->socketEngine->setReadNotificationEnabled(true);
|
|
}
|
|
|
|
return d->pendingConnections.takeFirst();
|
|
}
|
|
|
|
/*!
|
|
This virtual function is called by QTcpServer when a new
|
|
connection is available. The \a socketDescriptor argument is the
|
|
native socket descriptor for the accepted connection.
|
|
|
|
The base implementation creates a QTcpSocket, sets the socket
|
|
descriptor and then stores the QTcpSocket in an internal list of
|
|
pending connections. Finally newConnection() is emitted.
|
|
|
|
Reimplement this function to alter the server's behavior when a
|
|
connection is available.
|
|
|
|
If this server is using QNetworkProxy then the \a socketDescriptor
|
|
may not be usable with native socket functions, and should only be
|
|
used with QTcpSocket::setSocketDescriptor().
|
|
|
|
\note If another socket is created in the reimplementation
|
|
of this method, it needs to be added to the Pending Connections mechanism
|
|
by calling addPendingConnection().
|
|
|
|
\note If you want to handle an incoming connection as a new QTcpSocket
|
|
object in another thread you have to pass the socketDescriptor
|
|
to the other thread and create the QTcpSocket object there and
|
|
use its setSocketDescriptor() method.
|
|
|
|
\sa newConnection(), nextPendingConnection(), addPendingConnection()
|
|
*/
|
|
void QTcpServer::incomingConnection(qintptr socketDescriptor)
|
|
{
|
|
#if defined (QTCPSERVER_DEBUG)
|
|
qDebug("QTcpServer::incomingConnection(%i)", socketDescriptor);
|
|
#endif
|
|
|
|
QTcpSocket *socket = new QTcpSocket(this);
|
|
socket->setSocketDescriptor(socketDescriptor);
|
|
addPendingConnection(socket);
|
|
}
|
|
|
|
/*!
|
|
This function is called by QTcpServer::incomingConnection()
|
|
to add the \a socket to the list of pending incoming connections.
|
|
|
|
\note Don't forget to call this member from reimplemented
|
|
incomingConnection() if you do not want to break the
|
|
Pending Connections mechanism. This function emits the
|
|
pendingConnectionAvailable() signal after the socket has been
|
|
added.
|
|
|
|
\sa incomingConnection(), pendingConnectionAvailable()
|
|
\since 4.7
|
|
*/
|
|
void QTcpServer::addPendingConnection(QTcpSocket* socket)
|
|
{
|
|
d_func()->pendingConnections.append(socket);
|
|
emit pendingConnectionAvailable(QPrivateSignal());
|
|
}
|
|
|
|
/*!
|
|
Sets the maximum number of pending accepted connections to \a
|
|
numConnections. QTcpServer will accept no more than \a
|
|
numConnections incoming connections before
|
|
nextPendingConnection() is called. By default, the limit is 30
|
|
pending connections.
|
|
|
|
Clients may still able to connect after the server has reached
|
|
its maximum number of pending connections (i.e., QTcpSocket can
|
|
still emit the connected() signal). QTcpServer will stop
|
|
accepting the new connections, but the operating system may
|
|
still keep them in queue.
|
|
|
|
\sa maxPendingConnections(), hasPendingConnections()
|
|
*/
|
|
void QTcpServer::setMaxPendingConnections(int numConnections)
|
|
{
|
|
d_func()->maxConnections = numConnections;
|
|
}
|
|
|
|
/*!
|
|
Returns the maximum number of pending accepted connections. The
|
|
default is 30.
|
|
|
|
\sa setMaxPendingConnections(), hasPendingConnections()
|
|
*/
|
|
int QTcpServer::maxPendingConnections() const
|
|
{
|
|
return d_func()->maxConnections;
|
|
}
|
|
|
|
/*!
|
|
Sets the backlog queue size of to be accepted connections to \a
|
|
size. The operating system might reduce or ignore this value.
|
|
By default, the queue size is 50.
|
|
|
|
\note This property must be set prior to calling listen().
|
|
|
|
\since 6.3
|
|
|
|
\sa listenBacklogSize()
|
|
*/
|
|
void QTcpServer::setListenBacklogSize(int size)
|
|
{
|
|
d_func()->listenBacklog = size;
|
|
}
|
|
|
|
/*!
|
|
Returns the backlog queue size of to be accepted connections.
|
|
|
|
\since 6.3
|
|
|
|
\sa setListenBacklogSize()
|
|
*/
|
|
int QTcpServer::listenBacklogSize() const
|
|
{
|
|
return d_func()->listenBacklog;
|
|
}
|
|
|
|
/*!
|
|
Returns an error code for the last error that occurred.
|
|
|
|
\sa errorString()
|
|
*/
|
|
QAbstractSocket::SocketError QTcpServer::serverError() const
|
|
{
|
|
return d_func()->serverSocketError;
|
|
}
|
|
|
|
/*!
|
|
Returns a human readable description of the last error that
|
|
occurred.
|
|
|
|
\sa serverError()
|
|
*/
|
|
QString QTcpServer::errorString() const
|
|
{
|
|
return d_func()->serverSocketErrorString;
|
|
}
|
|
|
|
/*!
|
|
\since 5.0
|
|
|
|
Pauses accepting new connections. Queued connections will remain in queue.
|
|
|
|
\sa resumeAccepting()
|
|
*/
|
|
void QTcpServer::pauseAccepting()
|
|
{
|
|
d_func()->socketEngine->setReadNotificationEnabled(false);
|
|
}
|
|
|
|
/*!
|
|
\since 5.0
|
|
|
|
Resumes accepting new connections.
|
|
|
|
\sa pauseAccepting()
|
|
*/
|
|
void QTcpServer::resumeAccepting()
|
|
{
|
|
d_func()->socketEngine->setReadNotificationEnabled(true);
|
|
}
|
|
|
|
#ifndef QT_NO_NETWORKPROXY
|
|
/*!
|
|
\since 4.1
|
|
|
|
Sets the explicit network proxy for this socket to \a networkProxy.
|
|
|
|
To disable the use of a proxy for this socket, use the
|
|
QNetworkProxy::NoProxy proxy type:
|
|
|
|
\snippet code/src_network_socket_qtcpserver.cpp 0
|
|
|
|
\sa proxy(), QNetworkProxy
|
|
*/
|
|
void QTcpServer::setProxy(const QNetworkProxy &networkProxy)
|
|
{
|
|
Q_D(QTcpServer);
|
|
d->proxy = networkProxy;
|
|
}
|
|
|
|
/*!
|
|
\since 4.1
|
|
|
|
Returns the network proxy for this socket.
|
|
By default QNetworkProxy::DefaultProxy is used.
|
|
|
|
\sa setProxy(), QNetworkProxy
|
|
*/
|
|
QNetworkProxy QTcpServer::proxy() const
|
|
{
|
|
Q_D(const QTcpServer);
|
|
return d->proxy;
|
|
}
|
|
#endif // QT_NO_NETWORKPROXY
|
|
|
|
QT_END_NAMESPACE
|
|
|
|
#include "moc_qtcpserver.cpp"
|
|
|