97QTcpServerPrivate::QTcpServerPrivate()
99 , socketType(QAbstractSocket::UnknownSocketType)
100 , state(QAbstractSocket::UnconnectedState)
101 , socketEngine(
nullptr)
102 , serverSocketError(QAbstractSocket::UnknownSocketError)
118QNetworkProxy QTcpServerPrivate::resolveProxy(
const QHostAddress &address, quint16 port)
120 if (address.isLoopback())
121 return QNetworkProxy::NoProxy;
123 QList<QNetworkProxy> proxies;
124 if (proxy.type() != QNetworkProxy::DefaultProxy) {
129 QNetworkProxyQuery query(port, QString(),
130 socketType == QAbstractSocket::SctpSocket ?
131 QNetworkProxyQuery::SctpServer :
132 QNetworkProxyQuery::TcpServer);
133 proxies = QNetworkProxyFactory::proxyForQuery(query);
137 for (
const QNetworkProxy &p : std::as_const(proxies)) {
138 if (socketType == QAbstractSocket::TcpSocket &&
139 (p.capabilities() & QNetworkProxy::ListeningCapability) != 0)
142 if (socketType == QAbstractSocket::SctpSocket &&
143 (p.capabilities() & QNetworkProxy::SctpListeningCapability) != 0)
149 return QNetworkProxy(QNetworkProxy::DefaultProxy);
172void QTcpServerPrivate::readNotification()
176 if (totalPendingConnections() >= maxConnections) {
177#if defined (QTCPSERVER_DEBUG)
178 qDebug(
"QTcpServerPrivate::_q_processIncomingConnection() too many connections");
180 if (socketEngine->isReadNotificationEnabled())
181 socketEngine->setReadNotificationEnabled(
false);
185 qintptr descriptor = socketEngine->accept();
186 if (descriptor == -1) {
187 if (socketEngine->error() != QAbstractSocket::TemporaryError) {
189 serverSocketError = socketEngine->error();
190 serverSocketErrorString = socketEngine->errorString();
191 emit q->acceptError(serverSocketError);
195#if defined (QTCPSERVER_DEBUG)
196 qDebug(
"QTcpServerPrivate::_q_processIncomingConnection() accepted socket %i", descriptor);
198 QPointer<QTcpServer> that = q;
199 q->incomingConnection(descriptor);
202 emit q->newConnection();
204 if (!that || !q->isListening())
262QTcpServer::QTcpServer(QAbstractSocket::SocketType socketType, QTcpServerPrivate &dd,
263 QObject *parent) : QObject(dd, parent)
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);
273 d->socketType = socketType;
286bool QTcpServer::listen(
const QHostAddress &address, quint16 port)
289 if (d->state == QAbstractSocket::ListeningState) {
290 qWarning(
"QTcpServer::listen() called when already listening");
294 QAbstractSocket::NetworkLayerProtocol proto = address.protocol();
295 QHostAddress addr = address;
297#ifdef QT_NO_NETWORKPROXY
298 static const QNetworkProxy &proxy = *(QNetworkProxy *)0;
300 QNetworkProxy proxy = d->resolveProxy(addr, port);
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");
310 if (!d->socketEngine->initialize(d->socketType, proto)) {
311 d->serverSocketError = d->socketEngine->error();
312 d->serverSocketErrorString = d->socketEngine->errorString();
315 proto = d->socketEngine->protocol();
316 if (addr.protocol() == QAbstractSocket::AnyIPProtocol && proto == QAbstractSocket::IPv4Protocol)
317 addr = QHostAddress::AnyIPv4;
319 d->configureCreatedSocket();
321 if (!d->socketEngine->bind(addr, port)) {
322 d->serverSocketError = d->socketEngine->error();
323 d->serverSocketErrorString = d->socketEngine->errorString();
327 if (!d->socketEngine->listen(d->listenBacklog)) {
328 d->serverSocketError = d->socketEngine->error();
329 d->serverSocketErrorString = d->socketEngine->errorString();
333 d->socketEngine->setReceiver(d);
334 d->socketEngine->setReadNotificationEnabled(
true);
336 d->state = QAbstractSocket::ListeningState;
337 d->address = d->socketEngine->localAddress();
338 d->port = d->socketEngine->localPort();
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());
366void QTcpServer::close()
370 qDeleteAll(d->pendingConnections);
371 d->pendingConnections.clear();
373 if (d->socketEngine) {
374 d->socketEngine->close();
376 d->socketEngine->deleteLater();
377 } QT_CATCH(
const std::bad_alloc &) {
381 d->socketEngine =
nullptr;
384 d->state = QAbstractSocket::UnconnectedState;
412bool QTcpServer::setSocketDescriptor(qintptr socketDescriptor)
416 qWarning(
"QTcpServer::setSocketDescriptor() called when already listening");
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");
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());
438 d->socketEngine->setReceiver(d);
439 d->socketEngine->setReadNotificationEnabled(
true);
441 d->state = d->socketEngine->state();
442 d->address = d->socketEngine->localAddress();
443 d->port = d->socketEngine->localPort();
445#if defined (QTCPSERVER_DEBUG)
446 qDebug(
"QTcpServer::setSocketDescriptor(%i) succeeded.", socketDescriptor);
496bool QTcpServer::waitForNewConnection(
int msec,
bool *timedOut)
499 if (d->state != QAbstractSocket::ListeningState)
502 if (!d->socketEngine->waitForRead(QDeadlineTimer(msec), timedOut)) {
503 d->serverSocketError = d->socketEngine->error();
504 d->serverSocketErrorString = d->socketEngine->errorString();
508 if (timedOut && *timedOut)
511 d->readNotification();
545QTcpSocket *QTcpServer::nextPendingConnection()
548 if (d->pendingConnections.isEmpty())
551 if (!d->socketEngine) {
552 qWarning(
"QTcpServer::nextPendingConnection() called while not listening");
553 }
else if (!d->socketEngine->isReadNotificationEnabled()) {
554 d->socketEngine->setReadNotificationEnabled(
true);
557 return d->pendingConnections.takeFirst();