1// Copyright (C) 2022 The Qt Company Ltd.
2// Copyright (C) 2016 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5//#define QABSTRACTSOCKET_DEBUG
6
7/*!
8 \class QAbstractSocket
9
10 \brief The QAbstractSocket class provides the base functionality
11 common to all socket types.
12
13 \reentrant
14 \ingroup network
15 \inmodule QtNetwork
16
17 QAbstractSocket is the base class for QTcpSocket and QUdpSocket
18 and contains all common functionality of these two classes. If
19 you need a socket, you have two options:
20
21 \list
22 \li Instantiate QTcpSocket or QUdpSocket.
23 \li Create a native socket descriptor, instantiate
24 QAbstractSocket, and call setSocketDescriptor() to wrap the
25 native socket.
26 \endlist
27
28 TCP (Transmission Control Protocol) is a reliable,
29 stream-oriented, connection-oriented transport protocol. UDP
30 (User Datagram Protocol) is an unreliable, datagram-oriented,
31 connectionless protocol. In practice, this means that TCP is
32 better suited for continuous transmission of data, whereas the
33 more lightweight UDP can be used when reliability isn't
34 important.
35
36 QAbstractSocket's API unifies most of the differences between the
37 two protocols. For example, although UDP is connectionless,
38 connectToHost() establishes a virtual connection for UDP sockets,
39 enabling you to use QAbstractSocket in more or less the same way
40 regardless of the underlying protocol. Internally,
41 QAbstractSocket remembers the address and port passed to
42 connectToHost(), and functions like read() and write() use these
43 values.
44
45 At any time, QAbstractSocket has a state (returned by
46 state()). The initial state is UnconnectedState. After
47 calling connectToHost(), the socket first enters
48 HostLookupState. If the host is found, QAbstractSocket enters
49 ConnectingState and emits the hostFound() signal. When the
50 connection has been established, it enters ConnectedState and
51 emits connected(). If an error occurs at any stage, errorOccurred() is
52 emitted. Whenever the state changes, stateChanged() is emitted.
53 For convenience, isValid() returns \c true if the socket is ready for
54 reading and writing, but note that the socket's state must be
55 ConnectedState before reading and writing can occur.
56
57 Read or write data by calling read() or write(), or use the
58 convenience functions readLine() and readAll(). QAbstractSocket
59 also inherits getChar(), putChar(), and ungetChar() from
60 QIODevice, which work on single bytes. The bytesWritten() signal
61 is emitted when data has been written to the socket. Note that Qt does
62 not limit the write buffer size. You can monitor its size by listening
63 to this signal.
64
65 The readyRead() signal is emitted every time a new chunk of data
66 has arrived. bytesAvailable() then returns the number of bytes
67 that are available for reading. Typically, you would connect the
68 readyRead() signal to a slot and read all available data there.
69 If you don't read all the data at once, the remaining data will
70 still be available later, and any new incoming data will be
71 appended to QAbstractSocket's internal read buffer. To limit the
72 size of the read buffer, call setReadBufferSize().
73
74 To close the socket, call disconnectFromHost(). QAbstractSocket enters
75 QAbstractSocket::ClosingState. After all pending data has been written to
76 the socket, QAbstractSocket actually closes the socket, enters
77 QAbstractSocket::UnconnectedState, and emits disconnected(). If you want
78 to abort a connection immediately, discarding all pending data, call
79 abort() instead. If the remote host closes the connection,
80 QAbstractSocket will emit errorOccurred(QAbstractSocket::RemoteHostClosedError),
81 during which the socket state will still be ConnectedState, and then the
82 disconnected() signal will be emitted.
83
84 The port and address of the connected peer is fetched by calling
85 peerPort() and peerAddress(). peerName() returns the host name of
86 the peer, as passed to connectToHost(). localPort() and
87 localAddress() return the port and address of the local socket.
88
89 QAbstractSocket provides a set of functions that suspend the
90 calling thread until certain signals are emitted. These functions
91 can be used to implement blocking sockets:
92
93 \list
94 \li waitForConnected() blocks until a connection has been established.
95
96 \li waitForReadyRead() blocks until new data is available for
97 reading.
98
99 \li waitForBytesWritten() blocks until one payload of data has been
100 written to the socket.
101
102 \li waitForDisconnected() blocks until the connection has closed.
103 \endlist
104
105 We show an example:
106
107 \snippet network/tcpwait.cpp 0
108
109 If \l{QIODevice::}{waitForReadyRead()} returns \c false, the
110 connection has been closed or an error has occurred.
111
112 Programming with a blocking socket is radically different from
113 programming with a non-blocking socket. A blocking socket doesn't
114 require an event loop and typically leads to simpler code.
115 However, in a GUI application, blocking sockets should only be
116 used in non-GUI threads, to avoid freezing the user interface.
117 See the \l fortuneclient and \l blockingfortuneclient
118 examples for an overview of both approaches.
119
120 \note We discourage the use of the blocking functions together
121 with signals. One of the two possibilities should be used.
122
123 QAbstractSocket can be used with QTextStream and QDataStream's
124 stream operators (operator<<() and operator>>()). There is one
125 issue to be aware of, though: You must make sure that enough data
126 is available before attempting to read it using operator>>().
127
128 \sa QNetworkAccessManager, QTcpServer
129*/
130
131/*!
132 \fn void QAbstractSocket::hostFound()
133
134 This signal is emitted after connectToHost() has been called and
135 the host lookup has succeeded.
136
137 \note Since Qt 4.6.3 QAbstractSocket may emit hostFound()
138 directly from the connectToHost() call since a DNS result could have been
139 cached.
140
141 \sa connected()
142*/
143
144/*!
145 \fn void QAbstractSocket::connected()
146
147 This signal is emitted after connectToHost() has been called and
148 a connection has been successfully established.
149
150 \note On some operating systems the connected() signal may
151 be directly emitted from the connectToHost() call for connections
152 to the localhost.
153
154 \sa connectToHost(), disconnected()
155*/
156
157/*!
158 \fn void QAbstractSocket::disconnected()
159
160 This signal is emitted when the socket has been disconnected.
161
162 \warning If you need to delete the sender() of this signal in a slot connected
163 to it, use the \l{QObject::deleteLater()}{deleteLater()} function.
164
165 \sa connectToHost(), disconnectFromHost(), abort()
166*/
167
168/*!
169 \fn void QAbstractSocket::errorOccurred(QAbstractSocket::SocketError socketError)
170 \since 5.15
171
172 This signal is emitted after an error occurred. The \a socketError
173 parameter describes the type of error that occurred.
174
175 When this signal is emitted, the socket may not be ready for a reconnect
176 attempt. In that case, attempts to reconnect should be done from the event
177 loop. For example, use a QTimer::singleShot() with 0 as the timeout.
178
179 QAbstractSocket::SocketError is not a registered metatype, so for queued
180 connections, you will have to register it with Q_DECLARE_METATYPE() and
181 qRegisterMetaType().
182
183 \sa error(), errorString(), {Creating Custom Qt Types}
184*/
185
186/*!
187 \fn void QAbstractSocket::stateChanged(QAbstractSocket::SocketState socketState)
188
189 This signal is emitted whenever QAbstractSocket's state changes.
190 The \a socketState parameter is the new state.
191
192 QAbstractSocket::SocketState is not a registered metatype, so for queued
193 connections, you will have to register it with Q_DECLARE_METATYPE() and
194 qRegisterMetaType().
195
196 \sa state(), {Creating Custom Qt Types}
197*/
198
199/*!
200 \fn void QAbstractSocket::proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator)
201 \since 4.3
202
203 This signal can be emitted when a \a proxy that requires
204 authentication is used. The \a authenticator object can then be
205 filled in with the required details to allow authentication and
206 continue the connection.
207
208 \note It is not possible to use a QueuedConnection to connect to
209 this signal, as the connection will fail if the authenticator has
210 not been filled in with new information when the signal returns.
211
212 \sa QAuthenticator, QNetworkProxy
213*/
214
215/*!
216 \enum QAbstractSocket::NetworkLayerProtocol
217
218 This enum describes the network layer protocol values used in Qt.
219
220 \value IPv4Protocol IPv4
221 \value IPv6Protocol IPv6
222 \value AnyIPProtocol Either IPv4 or IPv6
223 \value UnknownNetworkLayerProtocol Other than IPv4 and IPv6
224
225 \sa QHostAddress::protocol()
226*/
227
228/*!
229 \enum QAbstractSocket::SocketType
230
231 This enum describes the transport layer protocol.
232
233 \value TcpSocket TCP
234 \value UdpSocket UDP
235 \value SctpSocket SCTP
236 \value UnknownSocketType Other than TCP, UDP and SCTP
237
238 \sa QAbstractSocket::socketType()
239*/
240
241/*!
242 \enum QAbstractSocket::SocketError
243
244 This enum describes the socket errors that can occur.
245
246 \value ConnectionRefusedError The connection was refused by the
247 peer (or timed out).
248 \value RemoteHostClosedError The remote host closed the
249 connection. Note that the client socket (i.e., this socket)
250 will be closed after the remote close notification has
251 been sent.
252 \value HostNotFoundError The host address was not found.
253 \value SocketAccessError The socket operation failed because the
254 application lacked the required privileges.
255 \value SocketResourceError The local system ran out of resources
256 (e.g., too many sockets).
257 \value SocketTimeoutError The socket operation timed out.
258 \value DatagramTooLargeError The datagram was larger than the
259 operating system's limit (which can be as low as 8192
260 bytes).
261 \value NetworkError An error occurred with the network (e.g., the
262 network cable was accidentally plugged out).
263 \value AddressInUseError The address specified to QAbstractSocket::bind() is
264 already in use and was set to be exclusive.
265 \value SocketAddressNotAvailableError The address specified to
266 QAbstractSocket::bind() does not belong to the host.
267 \value UnsupportedSocketOperationError The requested socket operation is
268 not supported by the local operating system (e.g., lack of
269 IPv6 support).
270 \value ProxyAuthenticationRequiredError The socket is using a proxy, and
271 the proxy requires authentication.
272 \value SslHandshakeFailedError The SSL/TLS handshake failed, so
273 the connection was closed (only used in QSslSocket)
274 \value UnfinishedSocketOperationError Used by QAbstractSocketEngine only,
275 The last operation attempted has not finished yet (still in progress in
276 the background).
277 \value ProxyConnectionRefusedError Could not contact the proxy server because
278 the connection to that server was denied
279 \value ProxyConnectionClosedError The connection to the proxy server was closed
280 unexpectedly (before the connection to the final peer was established)
281 \value ProxyConnectionTimeoutError The connection to the proxy server timed out
282 or the proxy server stopped responding in the authentication phase.
283 \value ProxyNotFoundError The proxy address set with setProxy() (or the application
284 proxy) was not found.
285 \value ProxyProtocolError The connection negotiation with the proxy server failed,
286 because the response from the proxy server could not be understood.
287 \value OperationError An operation was attempted while the socket was in a state that
288 did not permit it.
289 \value SslInternalError The SSL library being used reported an internal error. This is
290 probably the result of a bad installation or misconfiguration of the library.
291 \value SslInvalidUserDataError Invalid data (certificate, key, cypher, etc.) was
292 provided and its use resulted in an error in the SSL library.
293 \value TemporaryError A temporary error occurred (e.g., operation would block and socket
294 is non-blocking).
295
296 \value UnknownSocketError An unidentified error occurred.
297 \sa QAbstractSocket::error()
298 \sa QAbstractSocket::errorOccurred()
299*/
300
301/*!
302 \enum QAbstractSocket::SocketState
303
304 This enum describes the different states in which a socket can be.
305
306 \value UnconnectedState The socket is not connected.
307 \value HostLookupState The socket is performing a host name lookup.
308 \value ConnectingState The socket has started establishing a connection.
309 \value ConnectedState A connection is established.
310 \value BoundState The socket is bound to an address and port.
311 \value ClosingState The socket is about to close (data may still
312 be waiting to be written).
313 \value ListeningState For internal use only.
314
315 \sa QAbstractSocket::state()
316*/
317
318/*!
319 \enum QAbstractSocket::SocketOption
320 \since 4.6
321
322 This enum represents the options that can be set on a socket. If
323 desired, they can be set after having received the connected()
324 signal from the socket or after having received a new socket from
325 a QTcpServer.
326
327 \value LowDelayOption Try to optimize the socket for low
328 latency. For a QTcpSocket this would set the TCP_NODELAY option
329 and disable Nagle's algorithm. Set this to 1 to enable.
330
331 \value KeepAliveOption Set this to 1 to enable the SO_KEEPALIVE
332 socket option
333
334 \value MulticastTtlOption Set this to an integer value to set
335 IP_MULTICAST_TTL (TTL for multicast datagrams) socket option.
336
337 \value MulticastLoopbackOption Set this to 1 to enable the
338 IP_MULTICAST_LOOP (multicast loopback) socket option.
339
340 \value TypeOfServiceOption This option is not supported on
341 Windows. This maps to the IP_TOS socket option. For possible values,
342 see table below.
343
344 \value SendBufferSizeSocketOption Sets the socket send buffer size
345 in bytes at the OS level. This maps to the SO_SNDBUF socket option.
346 This option does not affect the QIODevice or QAbstractSocket buffers.
347 This enum value has been introduced in Qt 5.3.
348
349 \value ReceiveBufferSizeSocketOption Sets the socket receive
350 buffer size in bytes at the OS level.
351 This maps to the SO_RCVBUF socket option.
352 This option does not affect the QIODevice or QAbstractSocket buffers
353 (see \l{QAbstractSocket::}{setReadBufferSize()}).
354 This enum value has been introduced in Qt 5.3.
355
356 \value PathMtuSocketOption Retrieves the Path Maximum Transmission Unit
357 (PMTU) value currently known by the IP stack, if any. Some IP stacks also
358 allow setting the MTU for transmission.
359 This enum value was introduced in Qt 5.11.
360
361 Possible values for \e{TypeOfServiceOption} are:
362
363 \table
364 \header \li Value \li Description
365 \row \li 224 \li Network control
366 \row \li 192 \li Internetwork control
367 \row \li 160 \li CRITIC/ECP
368 \row \li 128 \li Flash override
369 \row \li 96 \li Flash
370 \row \li 64 \li Immediate
371 \row \li 32 \li Priority
372 \row \li 0 \li Routine
373 \endtable
374
375 \sa QAbstractSocket::setSocketOption(), QAbstractSocket::socketOption()
376*/
377
378/*! \enum QAbstractSocket::BindFlag
379 \since 5.0
380
381 This enum describes the different flags you can pass to modify the
382 behavior of QAbstractSocket::bind().
383
384 \value ShareAddress Allow other services to bind to the same address
385 and port. This is useful when multiple processes share
386 the load of a single service by listening to the same address and port
387 (e.g., a web server with several pre-forked listeners can greatly
388 improve response time). However, because any service is allowed to
389 rebind, this option is subject to certain security considerations.
390 Note that by combining this option with ReuseAddressHint, you will
391 also allow your service to rebind an existing shared address. On
392 Unix, this is equivalent to the SO_REUSEADDR socket option. On Windows,
393 this is the default behavior, so this option is ignored.
394
395 \value DontShareAddress Bind the address and port exclusively, so that
396 no other services are allowed to rebind. By passing this option to
397 QAbstractSocket::bind(), you are guaranteed that on success, your service
398 is the only one that listens to the address and port. No services are
399 allowed to rebind, even if they pass ReuseAddressHint. This option
400 provides more security than ShareAddress, but on certain operating
401 systems, it requires you to run the server with administrator privileges.
402 On Unix and \macos, not sharing is the default behavior for binding
403 an address and port, so this option is ignored. On Windows, this
404 option uses the SO_EXCLUSIVEADDRUSE socket option.
405
406 \value ReuseAddressHint Provides a hint to QAbstractSocket that it should try
407 to rebind the service even if the address and port are already bound by
408 another socket. On Windows and Unix, this is equivalent to the SO_REUSEADDR
409 socket option.
410
411 \value DefaultForPlatform The default option for the current platform.
412 On Unix and \macos, this is equivalent to (DontShareAddress
413 + ReuseAddressHint), and on Windows, it is equivalent to ShareAddress.
414*/
415
416/*! \enum QAbstractSocket::PauseMode
417 \since 5.0
418
419 This enum describes the behavior of when the socket should hold
420 back with continuing data transfer.
421 The only notification currently supported is QSslSocket::sslErrors().
422
423 \value PauseNever Do not pause data transfer on the socket. This is the
424 default and matches the behavior of Qt 4.
425 \value PauseOnSslErrors Pause data transfer on the socket upon receiving an
426 SSL error notification. I.E. QSslSocket::sslErrors().
427*/
428
429#include <QtNetwork/private/qtnetworkglobal_p.h>
430
431#include "qabstractsocket.h"
432#include "qabstractsocket_p.h"
433
434#include "private/qhostinfo_p.h"
435
436#include <qabstracteventdispatcher.h>
437#include <qhostaddress.h>
438#include <qhostinfo.h>
439#include <qmetaobject.h>
440#include <qpointer.h>
441#include <qtimer.h>
442#include <qelapsedtimer.h>
443#include <qscopedvaluerollback.h>
444#include <qvarlengtharray.h>
445
446#include <private/qthread_p.h>
447
448#ifdef QABSTRACTSOCKET_DEBUG
449#include <qdebug.h>
450#include <private/qdebug_p.h>
451#endif
452
453#include <time.h>
454
455#define Q_CHECK_SOCKETENGINE(returnValue) do { \
456 if (!d->socketEngine) { \
457 return returnValue; \
458 } } while (0)
459
460#ifndef QABSTRACTSOCKET_BUFFERSIZE
461#define QABSTRACTSOCKET_BUFFERSIZE 32768
462#endif
463#define QT_TRANSFER_TIMEOUT 120000
464
465QT_BEGIN_NAMESPACE
466
467using namespace Qt::StringLiterals;
468
469QT_IMPL_METATYPE_EXTERN_TAGGED(QAbstractSocket::SocketState, QAbstractSocket__SocketState)
470QT_IMPL_METATYPE_EXTERN_TAGGED(QAbstractSocket::SocketError, QAbstractSocket__SocketError)
471
472static const int DefaultConnectTimeout = 30000;
473
474static bool isProxyError(QAbstractSocket::SocketError error)
475{
476 switch (error) {
477 case QAbstractSocket::ProxyAuthenticationRequiredError:
478 case QAbstractSocket::ProxyConnectionRefusedError:
479 case QAbstractSocket::ProxyConnectionClosedError:
480 case QAbstractSocket::ProxyConnectionTimeoutError:
481 case QAbstractSocket::ProxyNotFoundError:
482 case QAbstractSocket::ProxyProtocolError:
483 return true;
484 default:
485 return false;
486 }
487}
488
489/*! \internal
490
491 Constructs a QAbstractSocketPrivate. Initializes all members.
492*/
493QAbstractSocketPrivate::QAbstractSocketPrivate()
494{
495 writeBufferChunkSize = QABSTRACTSOCKET_BUFFERSIZE;
496}
497
498/*! \internal
499
500 Destructs the QAbstractSocket. If the socket layer is open, it
501 will be reset.
502*/
503QAbstractSocketPrivate::~QAbstractSocketPrivate()
504{
505}
506
507/*! \internal
508
509 Resets the socket layer and deletes any socket notifiers.
510*/
511void QAbstractSocketPrivate::resetSocketLayer()
512{
513#if defined (QABSTRACTSOCKET_DEBUG)
514 qDebug("QAbstractSocketPrivate::resetSocketLayer()");
515#endif
516
517 hasPendingData = false;
518 if (socketEngine) {
519 socketEngine->close();
520 socketEngine->disconnect();
521 delete socketEngine;
522 socketEngine = nullptr;
523 cachedSocketDescriptor = -1;
524 }
525 if (connectTimer)
526 connectTimer->stop();
527}
528
529/*! \internal
530
531 Initializes the socket layer to by of type \a type, using the
532 network layer protocol \a protocol. Resets the socket layer first
533 if it's already initialized. Sets up the socket notifiers.
534*/
535bool QAbstractSocketPrivate::initSocketLayer(QAbstractSocket::NetworkLayerProtocol protocol)
536{
537#ifdef QT_NO_NETWORKPROXY
538 // this is here to avoid a duplication of the call to createSocketEngine below
539 static const QNetworkProxy &proxyInUse = *(QNetworkProxy *)0;
540#endif
541
542 Q_Q(QAbstractSocket);
543#if defined (QABSTRACTSOCKET_DEBUG)
544 QString typeStr;
545 if (q->socketType() == QAbstractSocket::TcpSocket) typeStr = "TcpSocket"_L1;
546 else if (q->socketType() == QAbstractSocket::UdpSocket) typeStr = "UdpSocket"_L1;
547 else if (q->socketType() == QAbstractSocket::SctpSocket) typeStr = "SctpSocket"_L1;
548 else typeStr = "UnknownSocketType"_L1;
549 QString protocolStr;
550 if (protocol == QAbstractSocket::IPv4Protocol) protocolStr = "IPv4Protocol"_L1;
551 else if (protocol == QAbstractSocket::IPv6Protocol) protocolStr = "IPv6Protocol"_L1;
552 else protocolStr = "UnknownNetworkLayerProtocol"_L1;
553#endif
554
555 resetSocketLayer();
556 socketEngine = QAbstractSocketEngine::createSocketEngine(socketType: q->socketType(), proxyInUse, parent: q);
557 if (!socketEngine) {
558 setError(errorCode: QAbstractSocket::UnsupportedSocketOperationError,
559 errorString: QAbstractSocket::tr(s: "Operation on socket is not supported"));
560 return false;
561 }
562 if (!socketEngine->initialize(type: q->socketType(), protocol)) {
563#if defined (QABSTRACTSOCKET_DEBUG)
564 qDebug("QAbstractSocketPrivate::initSocketLayer(%s, %s) failed (%s)",
565 typeStr.toLatin1().constData(), protocolStr.toLatin1().constData(),
566 socketEngine->errorString().toLatin1().constData());
567#endif
568 setError(errorCode: socketEngine->error(), errorString: socketEngine->errorString());
569 return false;
570 }
571
572 configureCreatedSocket();
573
574 if (threadData.loadRelaxed()->hasEventDispatcher())
575 socketEngine->setReceiver(this);
576
577#if defined (QABSTRACTSOCKET_DEBUG)
578 qDebug("QAbstractSocketPrivate::initSocketLayer(%s, %s) success",
579 typeStr.toLatin1().constData(), protocolStr.toLatin1().constData());
580#endif
581 return true;
582}
583
584/*! \internal
585*/
586void QAbstractSocketPrivate::configureCreatedSocket()
587{
588#ifndef QT_NO_SCTP
589 Q_Q(QAbstractSocket);
590 // Set single stream mode for unbuffered SCTP socket
591 if (socketEngine && q->socketType() == QAbstractSocket::SctpSocket)
592 socketEngine->setOption(QAbstractSocketEngine::MaxStreamsSocketOption, 1);
593#endif
594}
595
596/*! \internal
597
598 Slot connected to the read socket notifier. This slot is called
599 when new data is available for reading, or when the socket has
600 been closed. Handles recursive calls.
601*/
602bool QAbstractSocketPrivate::canReadNotification()
603{
604 Q_Q(QAbstractSocket);
605#if defined (QABSTRACTSOCKET_DEBUG)
606 qDebug("QAbstractSocketPrivate::canReadNotification()");
607#endif
608
609 // If buffered, read data from the socket into the read buffer
610 if (isBuffered) {
611 const qint64 oldBufferSize = buffer.size();
612
613 // Return if there is no space in the buffer
614 if (readBufferMaxSize && oldBufferSize >= readBufferMaxSize) {
615 socketEngine->setReadNotificationEnabled(false);
616#if defined (QABSTRACTSOCKET_DEBUG)
617 qDebug("QAbstractSocketPrivate::canReadNotification() buffer is full");
618#endif
619 return false;
620 }
621
622 // If reading from the socket fails after getting a read
623 // notification, close the socket.
624 if (!readFromSocket()) {
625#if defined (QABSTRACTSOCKET_DEBUG)
626 qDebug("QAbstractSocketPrivate::canReadNotification() disconnecting socket");
627#endif
628 q->disconnectFromHost();
629 return false;
630 }
631
632 // Return if there is no new data available.
633 if (buffer.size() == oldBufferSize) {
634 // If the socket is opened only for writing, return true
635 // to indicate that the data was discarded.
636 return !q->isReadable();
637 }
638 } else {
639 if (hasPendingData) {
640 socketEngine->setReadNotificationEnabled(false);
641 return true;
642 }
643 hasPendingData = true;
644 }
645
646 emitReadyRead();
647
648#if defined (QABSTRACTSOCKET_DEBUG)
649 // If we were closed as a result of the readyRead() signal.
650 if (state == QAbstractSocket::UnconnectedState || state == QAbstractSocket::ClosingState)
651 qDebug("QAbstractSocketPrivate::canReadNotification() socket is closing - returning");
652#endif
653
654 return true;
655}
656
657/*! \internal
658
659 Slot connected to the close socket notifier. It's called when the
660 socket is closed.
661*/
662void QAbstractSocketPrivate::canCloseNotification()
663{
664 Q_Q(QAbstractSocket);
665 // Note that this method is only called on Windows. Other platforms close in the canReadNotification()
666
667#if defined (QABSTRACTSOCKET_DEBUG)
668 qDebug("QAbstractSocketPrivate::canCloseNotification()");
669#endif
670
671 qint64 newBytes = 0;
672 if (isBuffered) {
673 // Try to read to the buffer, if the read fail we can close the socket.
674 newBytes = buffer.size();
675 qint64 oldReadBufferMaxSize = readBufferMaxSize;
676 readBufferMaxSize = 0; // temporarily disable max read buffer, we want to empty the OS buffer
677 bool hadReadFromSocket = readFromSocket();
678 readBufferMaxSize = oldReadBufferMaxSize;
679 if (!hadReadFromSocket) {
680 q->disconnectFromHost();
681 return;
682 }
683 newBytes = buffer.size() - newBytes;
684 if (newBytes) {
685 // If there was still some data to be read from the socket
686 // then we could get another FD_READ. The disconnect will
687 // then occur when we read from the socket again and fail
688 // in canReadNotification or by the manually created
689 // closeNotification below.
690 emitReadyRead();
691
692 QMetaObject::invokeMethod(obj: socketEngine, member: "closeNotification", c: Qt::QueuedConnection);
693 }
694 } else if ((socketType == QAbstractSocket::TcpSocket ||
695 socketType == QAbstractSocket::SctpSocket) && socketEngine) {
696 emitReadyRead();
697 }
698}
699
700
701/*! \internal
702
703 Slot connected to the write socket notifier. It's called during a
704 delayed connect or when the socket is ready for writing.
705*/
706bool QAbstractSocketPrivate::canWriteNotification()
707{
708#if defined (QABSTRACTSOCKET_DEBUG)
709 qDebug("QAbstractSocketPrivate::canWriteNotification() flushing");
710#endif
711
712 return writeToSocket();
713}
714
715/*! \internal
716
717 Slot connected to a notification of connection status
718 change. Either we finished connecting or we failed to connect.
719*/
720void QAbstractSocketPrivate::connectionNotification()
721{
722 // If in connecting state, check if the connection has been
723 // established, otherwise flush pending data.
724 if (state == QAbstractSocket::ConnectingState) {
725#if defined (QABSTRACTSOCKET_DEBUG)
726 qDebug("QAbstractSocketPrivate::connectionNotification() testing connection");
727#endif
728 _q_testConnection();
729 }
730}
731
732/*! \internal
733
734 Writes one pending data block in the write buffer to the socket.
735
736 It is usually invoked by canWriteNotification after one or more
737 calls to write().
738
739 Emits bytesWritten().
740*/
741bool QAbstractSocketPrivate::writeToSocket()
742{
743 Q_Q(QAbstractSocket);
744 if (!socketEngine || !socketEngine->isValid() || (writeBuffer.isEmpty()
745 && socketEngine->bytesToWrite() == 0)) {
746#if defined (QABSTRACTSOCKET_DEBUG)
747 qDebug("QAbstractSocketPrivate::writeToSocket() nothing to do: valid ? %s, writeBuffer.isEmpty() ? %s",
748 (socketEngine && socketEngine->isValid()) ? "yes" : "no", writeBuffer.isEmpty() ? "yes" : "no");
749#endif
750
751 // this covers the case when the buffer was empty, but we had to wait for the socket engine to finish
752 if (state == QAbstractSocket::ClosingState) {
753 q->disconnectFromHost();
754 } else {
755 if (socketEngine)
756 socketEngine->setWriteNotificationEnabled(false);
757 }
758
759 return false;
760 }
761
762 qint64 nextSize = writeBuffer.nextDataBlockSize();
763 const char *ptr = writeBuffer.readPointer();
764
765 // Attempt to write it all in one chunk.
766 qint64 written = nextSize ? socketEngine->write(data: ptr, len: nextSize) : Q_INT64_C(0);
767 if (written < 0) {
768#if defined (QABSTRACTSOCKET_DEBUG)
769 qDebug() << "QAbstractSocketPrivate::writeToSocket() write error, aborting."
770 << socketEngine->errorString();
771#endif
772 setErrorAndEmit(errorCode: socketEngine->error(), errorString: socketEngine->errorString());
773 // an unexpected error so close the socket.
774 q->abort();
775 return false;
776 }
777
778#if defined (QABSTRACTSOCKET_DEBUG)
779 qDebug("QAbstractSocketPrivate::writeToSocket() %lld bytes written to the network",
780 written);
781#endif
782
783 if (written > 0) {
784 // Remove what we wrote so far.
785 writeBuffer.free(bytes: written);
786
787 // Emit notifications.
788 emitBytesWritten(bytes: written);
789 }
790
791 if (writeBuffer.isEmpty() && socketEngine && !socketEngine->bytesToWrite())
792 socketEngine->setWriteNotificationEnabled(false);
793 if (state == QAbstractSocket::ClosingState)
794 q->disconnectFromHost();
795
796 return written > 0;
797}
798
799/*! \internal
800
801 Writes pending data in the write buffers to the socket. The function
802 writes as much as it can without blocking. If any data was written,
803 this function returns true; otherwise false is returned.
804*/
805bool QAbstractSocketPrivate::flush()
806{
807 bool dataWasWritten = false;
808
809 while (!allWriteBuffersEmpty() && writeToSocket())
810 dataWasWritten = true;
811
812 return dataWasWritten;
813}
814
815#ifndef QT_NO_NETWORKPROXY
816/*! \internal
817
818 Resolve the proxy to its final value.
819*/
820void QAbstractSocketPrivate::resolveProxy(const QString &hostname, quint16 port)
821{
822 QList<QNetworkProxy> proxies;
823
824 if (proxy.type() != QNetworkProxy::DefaultProxy) {
825 // a non-default proxy was set with setProxy
826 proxies << proxy;
827 } else {
828 // try the application settings instead
829 QNetworkProxyQuery query(hostname, port, protocolTag,
830 socketType == QAbstractSocket::TcpSocket ?
831 QNetworkProxyQuery::TcpSocket :
832 socketType == QAbstractSocket::SctpSocket ?
833 QNetworkProxyQuery::SctpSocket :
834 QNetworkProxyQuery::UdpSocket);
835 proxies = QNetworkProxyFactory::proxyForQuery(query);
836 }
837
838 // return the first that we can use
839 for (const QNetworkProxy &p : std::as_const(t&: proxies)) {
840 if (socketType == QAbstractSocket::UdpSocket &&
841 (p.capabilities() & QNetworkProxy::UdpTunnelingCapability) == 0)
842 continue;
843
844 if (socketType == QAbstractSocket::TcpSocket &&
845 (p.capabilities() & QNetworkProxy::TunnelingCapability) == 0)
846 continue;
847
848 if (socketType == QAbstractSocket::SctpSocket &&
849 (p.capabilities() & QNetworkProxy::SctpTunnelingCapability) == 0)
850 continue;
851
852 proxyInUse = p;
853 return;
854 }
855
856 // no proxy found
857 // DefaultProxy here will raise an error
858 proxyInUse = QNetworkProxy();
859}
860#endif // !QT_NO_NETWORKPROXY
861
862#if !defined(QT_NO_NETWORKPROXY)
863/*!
864 \internal
865
866 Starts the connection to \a host, like _q_startConnecting below,
867 but without hostname resolution.
868*/
869void QAbstractSocketPrivate::startConnectingByName(const QString &host)
870{
871 Q_Q(QAbstractSocket);
872 if (state == QAbstractSocket::ConnectingState || state == QAbstractSocket::ConnectedState)
873 return;
874
875#if defined(QABSTRACTSOCKET_DEBUG)
876 qDebug("QAbstractSocketPrivate::startConnectingByName(host == %s)", qPrintable(host));
877#endif
878
879 // ### Let the socket engine drive this?
880 state = QAbstractSocket::ConnectingState;
881 emit q->stateChanged(state);
882
883 if (cachedSocketDescriptor != -1 || initSocketLayer(protocol: QAbstractSocket::UnknownNetworkLayerProtocol)) {
884 // Try to connect to the host. If it succeeds immediately
885 // (e.g. QSocks5SocketEngine in UDPASSOCIATE mode), emit
886 // connected() and return.
887 if (socketEngine->connectToHostByName(name: host, port)) {
888 fetchConnectionParameters();
889 return;
890 }
891
892 if (socketEngine->state() == QAbstractSocket::ConnectingState)
893 return;
894
895 // failed to connect
896 setError(errorCode: socketEngine->error(), errorString: socketEngine->errorString());
897 }
898
899 state = QAbstractSocket::UnconnectedState;
900 emit q->errorOccurred(socketError);
901 emit q->stateChanged(state);
902}
903
904#endif // !QT_NO_NETWORKPROXY
905
906/*! \internal
907
908 Slot connected to QHostInfo::lookupHost() in connectToHost(). This
909 function starts the process of connecting to any number of
910 candidate IP addresses for the host, if it was found. Calls
911 _q_connectToNextAddress().
912*/
913void QAbstractSocketPrivate::_q_startConnecting(const QHostInfo &hostInfo)
914{
915 Q_Q(QAbstractSocket);
916 addresses.clear();
917 if (state != QAbstractSocket::HostLookupState)
918 return;
919
920 if (hostLookupId != -1 && hostLookupId != hostInfo.lookupId()) {
921 qWarning(msg: "QAbstractSocketPrivate::_q_startConnecting() received hostInfo for wrong lookup ID %d expected %d", hostInfo.lookupId(), hostLookupId);
922 }
923
924 // Only add the addresses for the preferred network layer.
925 // Or all if preferred network layer is not set.
926 if (preferredNetworkLayerProtocol == QAbstractSocket::UnknownNetworkLayerProtocol || preferredNetworkLayerProtocol == QAbstractSocket::AnyIPProtocol) {
927 addresses = hostInfo.addresses();
928 } else {
929 const auto candidates = hostInfo.addresses();
930 for (const QHostAddress &address : candidates) {
931 if (address.protocol() == preferredNetworkLayerProtocol)
932 addresses += address;
933 }
934 }
935
936
937#if defined(QABSTRACTSOCKET_DEBUG)
938 QString s = "{"_L1;
939 for (int i = 0; i < addresses.count(); ++i) {
940 if (i != 0) s += ", "_L1;
941 s += addresses.at(i).toString();
942 }
943 s += u'}';
944 qDebug("QAbstractSocketPrivate::_q_startConnecting(hostInfo == %s)", s.toLatin1().constData());
945#endif
946
947 // Try all addresses twice.
948 addresses += addresses;
949
950 // If there are no addresses in the host list, report this to the
951 // user.
952 if (addresses.isEmpty()) {
953#if defined(QABSTRACTSOCKET_DEBUG)
954 qDebug("QAbstractSocketPrivate::_q_startConnecting(), host not found");
955#endif
956 state = QAbstractSocket::UnconnectedState;
957 setError(errorCode: QAbstractSocket::HostNotFoundError, errorString: QAbstractSocket::tr(s: "Host not found"));
958 emit q->stateChanged(state);
959 emit q->errorOccurred(QAbstractSocket::HostNotFoundError);
960 return;
961 }
962
963 // Enter Connecting state (see also sn_write, which is called by
964 // the write socket notifier after connect())
965 state = QAbstractSocket::ConnectingState;
966 emit q->stateChanged(state);
967
968 // Report the successful host lookup
969 emit q->hostFound();
970
971 // The addresses returned by the lookup will be tested one after
972 // another by _q_connectToNextAddress().
973 _q_connectToNextAddress();
974}
975
976/*! \internal
977
978 Called by a queued or direct connection from _q_startConnecting() or
979 _q_testConnection(), this function takes the first address of the
980 pending addresses list and tries to connect to it. If the
981 connection succeeds, QAbstractSocket will emit
982 connected(). Otherwise, errorOccurred(ConnectionRefusedError) or
983 errorOccurred(SocketTimeoutError) is emitted.
984*/
985void QAbstractSocketPrivate::_q_connectToNextAddress()
986{
987 Q_Q(QAbstractSocket);
988 do {
989 // Check for more pending addresses
990 if (addresses.isEmpty()) {
991#if defined(QABSTRACTSOCKET_DEBUG)
992 qDebug("QAbstractSocketPrivate::_q_connectToNextAddress(), all addresses failed.");
993#endif
994 state = QAbstractSocket::UnconnectedState;
995 if (socketEngine) {
996 if ((socketEngine->error() == QAbstractSocket::UnknownSocketError
997#ifdef Q_OS_AIX
998 // On AIX, the second connect call will result in EINVAL and not
999 // ECONNECTIONREFUSED; although the meaning is the same.
1000 || socketEngine->error() == QAbstractSocket::UnsupportedSocketOperationError
1001#endif
1002 ) && socketEngine->state() == QAbstractSocket::ConnectingState) {
1003 setError(errorCode: QAbstractSocket::ConnectionRefusedError,
1004 errorString: QAbstractSocket::tr(s: "Connection refused"));
1005 } else {
1006 setError(errorCode: socketEngine->error(), errorString: socketEngine->errorString());
1007 }
1008 } else {
1009// socketError = QAbstractSocket::ConnectionRefusedError;
1010// q->setErrorString(QAbstractSocket::tr("Connection refused"));
1011 }
1012 emit q->stateChanged(state);
1013 emit q->errorOccurred(socketError);
1014 return;
1015 }
1016
1017 // Pick the first host address candidate
1018 host = addresses.takeFirst();
1019#if defined(QABSTRACTSOCKET_DEBUG)
1020 qDebug("QAbstractSocketPrivate::_q_connectToNextAddress(), connecting to %s:%i, %d left to try",
1021 host.toString().toLatin1().constData(), port, addresses.count());
1022#endif
1023
1024 if (cachedSocketDescriptor == -1 && !initSocketLayer(protocol: host.protocol())) {
1025 // hope that the next address is better
1026#if defined(QABSTRACTSOCKET_DEBUG)
1027 qDebug("QAbstractSocketPrivate::_q_connectToNextAddress(), failed to initialize sock layer");
1028#endif
1029 continue;
1030 }
1031
1032 // Tries to connect to the address. If it succeeds immediately
1033 // (localhost address on BSD or any UDP connect), emit
1034 // connected() and return.
1035 if (
1036 socketEngine->connectToHost(address: host, port)) {
1037 //_q_testConnection();
1038 fetchConnectionParameters();
1039 return;
1040 }
1041
1042 // Check that we're in delayed connection state. If not, try
1043 // the next address
1044 if (socketEngine->state() != QAbstractSocket::ConnectingState) {
1045#if defined(QABSTRACTSOCKET_DEBUG)
1046 qDebug("QAbstractSocketPrivate::_q_connectToNextAddress(), connection failed (%s)",
1047 socketEngine->errorString().toLatin1().constData());
1048#endif
1049 continue;
1050 }
1051
1052 // Start the connect timer.
1053 if (threadData.loadRelaxed()->hasEventDispatcher()) {
1054 if (!connectTimer) {
1055 connectTimer = new QTimer(q);
1056 QObject::connect(sender: connectTimer, SIGNAL(timeout()),
1057 receiver: q, SLOT(_q_abortConnectionAttempt()),
1058 Qt::DirectConnection);
1059 }
1060 int connectTimeout = DefaultConnectTimeout;
1061 connectTimer->start(msec: connectTimeout);
1062 }
1063
1064 // Wait for a write notification that will eventually call
1065 // _q_testConnection().
1066 socketEngine->setWriteNotificationEnabled(true);
1067 break;
1068 } while (state != QAbstractSocket::ConnectedState);
1069}
1070
1071/*! \internal
1072
1073 Tests if a connection has been established. If it has, connected()
1074 is emitted. Otherwise, _q_connectToNextAddress() is invoked.
1075*/
1076void QAbstractSocketPrivate::_q_testConnection()
1077{
1078 if (connectTimer)
1079 connectTimer->stop();
1080
1081 if (socketEngine) {
1082 if (socketEngine->state() == QAbstractSocket::ConnectedState) {
1083 // Fetch the parameters if our connection is completed;
1084 // otherwise, fall out and try the next address.
1085 fetchConnectionParameters();
1086 if (pendingClose) {
1087 q_func()->disconnectFromHost();
1088 pendingClose = false;
1089 }
1090 return;
1091 }
1092
1093 // don't retry the other addresses if we had a proxy error
1094 if (isProxyError(error: socketEngine->error()))
1095 addresses.clear();
1096 }
1097
1098#if defined(QABSTRACTSOCKET_DEBUG)
1099 qDebug("QAbstractSocketPrivate::_q_testConnection() connection failed,"
1100 " checking for alternative addresses");
1101#endif
1102 _q_connectToNextAddress();
1103}
1104
1105/*! \internal
1106
1107 This function is called after a certain number of seconds has
1108 passed while waiting for a connection. It simply tests the
1109 connection, and continues to the next address if the connection
1110 failed.
1111*/
1112void QAbstractSocketPrivate::_q_abortConnectionAttempt()
1113{
1114 Q_Q(QAbstractSocket);
1115#if defined(QABSTRACTSOCKET_DEBUG)
1116 qDebug("QAbstractSocketPrivate::_q_abortConnectionAttempt() (timed out)");
1117#endif
1118 if (socketEngine)
1119 socketEngine->setWriteNotificationEnabled(false);
1120
1121 connectTimer->stop();
1122
1123 if (addresses.isEmpty()) {
1124 state = QAbstractSocket::UnconnectedState;
1125 setError(errorCode: QAbstractSocket::SocketTimeoutError,
1126 errorString: QAbstractSocket::tr(s: "Connection timed out"));
1127 emit q->stateChanged(state);
1128 emit q->errorOccurred(socketError);
1129 } else {
1130 _q_connectToNextAddress();
1131 }
1132}
1133
1134/*! \internal
1135
1136 Reads data from the socket layer into the read buffer. Returns
1137 true on success; otherwise false.
1138*/
1139bool QAbstractSocketPrivate::readFromSocket()
1140{
1141 Q_Q(QAbstractSocket);
1142 // Find how many bytes we can read from the socket layer.
1143 qint64 bytesToRead = socketEngine->bytesAvailable();
1144 if (bytesToRead == 0) {
1145 // Under heavy load, certain conditions can trigger read notifications
1146 // for socket notifiers on which there is no activity. If we continue
1147 // to read 0 bytes from the socket, we will trigger behavior similar
1148 // to that which signals a remote close. When we hit this condition,
1149 // we try to read 4k of data from the socket, which will give us either
1150 // an EAGAIN/EWOULDBLOCK if the connection is alive (i.e., the remote
1151 // host has _not_ disappeared).
1152 bytesToRead = 4096;
1153 }
1154
1155 if (q->isReadable()) {
1156 if (readBufferMaxSize && bytesToRead > (readBufferMaxSize - buffer.size()))
1157 bytesToRead = readBufferMaxSize - buffer.size();
1158
1159#if defined(QABSTRACTSOCKET_DEBUG)
1160 qDebug("QAbstractSocketPrivate::readFromSocket() about to read %lld bytes",
1161 bytesToRead);
1162#endif
1163
1164 // Read from the socket, store data in the read buffer.
1165 char *ptr = buffer.reserve(bytes: bytesToRead);
1166 qint64 readBytes = socketEngine->read(data: ptr, maxlen: bytesToRead);
1167 if (readBytes == -2) {
1168 // No bytes currently available for reading.
1169 buffer.chop(bytes: bytesToRead);
1170 return true;
1171 }
1172 buffer.chop(bytes: bytesToRead - (readBytes < 0 ? qint64(0) : readBytes));
1173#if defined(QABSTRACTSOCKET_DEBUG)
1174 qDebug("QAbstractSocketPrivate::readFromSocket() got %lld bytes, buffer size = %lld",
1175 readBytes, buffer.size());
1176#endif
1177 } else {
1178 // Discard unwanted data if opened in WriteOnly mode
1179 QVarLengthArray<char, 4096> discardBuffer(bytesToRead);
1180
1181#if defined(QABSTRACTSOCKET_DEBUG)
1182 qDebug("QAbstractSocketPrivate::readFromSocket() about to discard %lld bytes",
1183 bytesToRead);
1184#endif
1185 socketEngine->read(data: discardBuffer.data(), maxlen: bytesToRead);
1186 }
1187
1188 if (!socketEngine->isValid()) {
1189#if defined(QABSTRACTSOCKET_DEBUG)
1190 qDebug("QAbstractSocketPrivate::readFromSocket() read failed: %s",
1191 socketEngine->errorString().toLatin1().constData());
1192#endif
1193 setErrorAndEmit(errorCode: socketEngine->error(), errorString: socketEngine->errorString());
1194 resetSocketLayer();
1195 return false;
1196 }
1197
1198 return true;
1199}
1200
1201/*! \internal
1202
1203 Emits readyRead(), protecting against recursion.
1204*/
1205void QAbstractSocketPrivate::emitReadyRead(int channel)
1206{
1207 Q_Q(QAbstractSocket);
1208 // Only emit readyRead() when not recursing.
1209 if (!emittedReadyRead && channel == currentReadChannel) {
1210 QScopedValueRollback<bool> r(emittedReadyRead);
1211 emittedReadyRead = true;
1212 emit q->readyRead();
1213 }
1214 // channelReadyRead() can be emitted recursively - even for the same channel.
1215 emit q->channelReadyRead(channel);
1216}
1217
1218/*! \internal
1219
1220 Emits bytesWritten(), protecting against recursion.
1221*/
1222void QAbstractSocketPrivate::emitBytesWritten(qint64 bytes, int channel)
1223{
1224 Q_Q(QAbstractSocket);
1225 // Only emit bytesWritten() when not recursing.
1226 if (!emittedBytesWritten && channel == currentWriteChannel) {
1227 QScopedValueRollback<bool> r(emittedBytesWritten);
1228 emittedBytesWritten = true;
1229 emit q->bytesWritten(bytes);
1230 }
1231 // channelBytesWritten() can be emitted recursively - even for the same channel.
1232 emit q->channelBytesWritten(channel, bytes);
1233}
1234
1235/*! \internal
1236
1237 Sets up the internal state after the connection has succeeded.
1238*/
1239void QAbstractSocketPrivate::fetchConnectionParameters()
1240{
1241 Q_Q(QAbstractSocket);
1242
1243 peerName = hostName;
1244 if (socketEngine) {
1245 if (q->isReadable()) {
1246 const int inboundStreamCount = socketEngine->inboundStreamCount();
1247 setReadChannelCount(qMax(a: 1, b: inboundStreamCount));
1248 if (inboundStreamCount == 0)
1249 readChannelCount = 0;
1250 }
1251 if (q->isWritable()) {
1252 const int outboundStreamCount = socketEngine->outboundStreamCount();
1253 setWriteChannelCount(qMax(a: 1, b: outboundStreamCount));
1254 if (outboundStreamCount == 0)
1255 writeChannelCount = 0;
1256 }
1257 socketEngine->setReadNotificationEnabled(true);
1258 socketEngine->setWriteNotificationEnabled(true);
1259 localPort = socketEngine->localPort();
1260 peerPort = socketEngine->peerPort();
1261 localAddress = socketEngine->localAddress();
1262 peerAddress = socketEngine->peerAddress();
1263 cachedSocketDescriptor = socketEngine->socketDescriptor();
1264 }
1265
1266 state = QAbstractSocket::ConnectedState;
1267#if defined(QABSTRACTSOCKET_DEBUG)
1268 qDebug("QAbstractSocketPrivate::fetchConnectionParameters() connection to %s:%i established",
1269 host.toString().toLatin1().constData(), port);
1270#endif
1271 emit q->stateChanged(state);
1272 emit q->connected();
1273}
1274
1275/*! \reimp
1276*/
1277qint64 QAbstractSocket::skipData(qint64 maxSize)
1278{
1279 Q_D(const QAbstractSocket);
1280
1281 // if we're not connected, return -1 indicating EOF
1282 if (!d->socketEngine || !d->socketEngine->isValid()
1283 || d->state != QAbstractSocket::ConnectedState)
1284 return -1;
1285
1286 // Caller, QIODevice::skip(), has ensured buffer is empty. So, wait
1287 // for more data in buffered mode.
1288 if (d->isBuffered)
1289 return 0;
1290
1291 return QIODevice::skipData(maxSize);
1292}
1293
1294void QAbstractSocketPrivate::pauseSocketNotifiers(QAbstractSocket *socket)
1295{
1296 QAbstractSocketEngine *socketEngine = socket->d_func()->socketEngine;
1297 if (!socketEngine)
1298 return;
1299 bool read = socketEngine->isReadNotificationEnabled();
1300 bool write = socketEngine->isWriteNotificationEnabled();
1301 bool except = socketEngine->isExceptionNotificationEnabled();
1302
1303#ifdef QABSTRACTSOCKET_DEBUG
1304 qDebug() << socketEngine->socketDescriptor()
1305 << "pause notifiers, storing 'true' states, currently read:" << read
1306 << "write:" << write << "except:" << except;
1307#endif
1308 // We do this if-check to avoid accidentally overwriting any previously stored state
1309 // It will reset to false once the socket is re-enabled.
1310 if (read) {
1311 socket->d_func()->prePauseReadSocketNotifierState = true;
1312 socketEngine->setReadNotificationEnabled(false);
1313 }
1314 if (write) {
1315 socket->d_func()->prePauseWriteSocketNotifierState = true;
1316 socketEngine->setWriteNotificationEnabled(false);
1317 }
1318 if (except) {
1319 socket->d_func()->prePauseExceptionSocketNotifierState = true;
1320 socketEngine->setExceptionNotificationEnabled(false);
1321 }
1322}
1323
1324void QAbstractSocketPrivate::resumeSocketNotifiers(QAbstractSocket *socket)
1325{
1326 QAbstractSocketEngine *socketEngine = socket->d_func()->socketEngine;
1327 if (!socketEngine)
1328 return;
1329 QAbstractSocketPrivate *priv = socket->d_func();
1330#ifdef QABSTRACTSOCKET_DEBUG
1331 qDebug() << socketEngine->socketDescriptor()
1332 << "Maybe resume notifiers, read:" << priv->prePauseReadSocketNotifierState
1333 << "write:" << priv->prePauseWriteSocketNotifierState
1334 << "exception:" << priv->prePauseExceptionSocketNotifierState;
1335#endif
1336 if (std::exchange(obj&: priv->prePauseReadSocketNotifierState, new_val: false))
1337 socketEngine->setReadNotificationEnabled(true);
1338 if (std::exchange(obj&: priv->prePauseWriteSocketNotifierState, new_val: false))
1339 socketEngine->setWriteNotificationEnabled(true);
1340 if (std::exchange(obj&: priv->prePauseExceptionSocketNotifierState, new_val: false))
1341 socketEngine->setExceptionNotificationEnabled(true);
1342}
1343
1344QAbstractSocketEngine* QAbstractSocketPrivate::getSocketEngine(QAbstractSocket *socket)
1345{
1346 return socket->d_func()->socketEngine;
1347}
1348
1349/*!
1350 \internal
1351
1352 Sets the socket error state to \c errorCode and \a errorString.
1353*/
1354void QAbstractSocketPrivate::setError(QAbstractSocket::SocketError errorCode,
1355 const QString &errStr)
1356{
1357 socketError = errorCode;
1358 errorString = errStr;
1359}
1360
1361/*!
1362 \internal
1363
1364 Sets the socket error state to \c errorCode and \a errorString,
1365 and emits the QAbstractSocket::errorOccurred() signal.
1366*/
1367void QAbstractSocketPrivate::setErrorAndEmit(QAbstractSocket::SocketError errorCode,
1368 const QString &errorString)
1369{
1370 Q_Q(QAbstractSocket);
1371 setError(errorCode, errStr: errorString);
1372 emit q->errorOccurred(errorCode);
1373}
1374
1375/*! \internal
1376
1377 Constructs a new abstract socket of type \a socketType. The \a
1378 parent argument is passed to QObject's constructor.
1379*/
1380QAbstractSocket::QAbstractSocket(SocketType socketType,
1381 QAbstractSocketPrivate &dd, QObject *parent)
1382 : QIODevice(dd, parent)
1383{
1384 Q_D(QAbstractSocket);
1385#if defined(QABSTRACTSOCKET_DEBUG)
1386 qDebug("QAbstractSocket::QAbstractSocket(%sSocket, QAbstractSocketPrivate == %p, parent == %p)",
1387 socketType == TcpSocket ? "Tcp" : socketType == UdpSocket ? "Udp"
1388 : socketType == SctpSocket ? "Sctp" : "Unknown", &dd, parent);
1389#endif
1390 d->socketType = socketType;
1391}
1392
1393/*!
1394 Creates a new abstract socket of type \a socketType. The \a
1395 parent argument is passed to QObject's constructor.
1396
1397 \sa socketType(), QTcpSocket, QUdpSocket
1398*/
1399QAbstractSocket::QAbstractSocket(SocketType socketType, QObject *parent)
1400 : QAbstractSocket(socketType, *new QAbstractSocketPrivate, parent)
1401{
1402}
1403
1404/*!
1405 Destroys the socket.
1406*/
1407QAbstractSocket::~QAbstractSocket()
1408{
1409 Q_D(QAbstractSocket);
1410#if defined(QABSTRACTSOCKET_DEBUG)
1411 qDebug("QAbstractSocket::~QAbstractSocket()");
1412#endif
1413 if (d->state != UnconnectedState)
1414 abort();
1415}
1416
1417/*!
1418 \since 5.0
1419
1420 Continues data transfer on the socket. This method should only be used
1421 after the socket has been set to pause upon notifications and a
1422 notification has been received.
1423 The only notification currently supported is QSslSocket::sslErrors().
1424 Calling this method if the socket is not paused results in undefined
1425 behavior.
1426
1427 \sa pauseMode(), setPauseMode()
1428*/
1429void QAbstractSocket::resume()
1430{
1431 QAbstractSocketPrivate::resumeSocketNotifiers(socket: this);
1432}
1433
1434/*!
1435 \since 5.0
1436
1437 Returns the pause mode of this socket.
1438
1439 \sa setPauseMode(), resume()
1440*/
1441QAbstractSocket::PauseModes QAbstractSocket::pauseMode() const
1442{
1443 return d_func()->pauseMode;
1444}
1445
1446
1447/*!
1448 \since 5.0
1449
1450 Controls whether to pause upon receiving a notification. The \a pauseMode parameter
1451 specifies the conditions in which the socket should be paused. The only notification
1452 currently supported is QSslSocket::sslErrors(). If set to PauseOnSslErrors,
1453 data transfer on the socket will be paused and needs to be enabled explicitly
1454 again by calling resume().
1455 By default this option is set to PauseNever.
1456 This option must be called before connecting to the server, otherwise it will
1457 result in undefined behavior.
1458
1459 \sa pauseMode(), resume()
1460*/
1461void QAbstractSocket::setPauseMode(PauseModes pauseMode)
1462{
1463 d_func()->pauseMode = pauseMode;
1464}
1465
1466/*!
1467 \since 5.0
1468
1469 Binds to \a address on port \a port, using the BindMode \a mode.
1470
1471 For UDP sockets, after binding, the signal QUdpSocket::readyRead() is emitted
1472 whenever a UDP datagram arrives on the specified address and port.
1473 Thus, this function is useful to write UDP servers.
1474
1475 For TCP sockets, this function may be used to specify which interface to use
1476 for an outgoing connection, which is useful in case of multiple network
1477 interfaces.
1478
1479 By default, the socket is bound using the DefaultForPlatform BindMode.
1480 If a port is not specified, a random port is chosen.
1481
1482 On success, the function returns \c true and the socket enters
1483 BoundState; otherwise it returns \c false.
1484
1485*/
1486bool QAbstractSocket::bind(const QHostAddress &address, quint16 port, BindMode mode)
1487{
1488 Q_D(QAbstractSocket);
1489 return d->bind(address, port, mode);
1490}
1491
1492bool QAbstractSocketPrivate::bind(const QHostAddress &address, quint16 port, QAbstractSocket::BindMode mode)
1493{
1494 Q_Q(QAbstractSocket);
1495
1496 // now check if the socket engine is initialized and to the right type
1497 if (!socketEngine || !socketEngine->isValid()) {
1498 QHostAddress nullAddress;
1499 resolveProxy(hostname: nullAddress.toString(), port);
1500
1501 QAbstractSocket::NetworkLayerProtocol protocol = address.protocol();
1502 if (protocol == QAbstractSocket::UnknownNetworkLayerProtocol)
1503 protocol = nullAddress.protocol();
1504
1505 if (!initSocketLayer(protocol))
1506 return false;
1507 }
1508
1509 if (mode != QAbstractSocket::DefaultForPlatform) {
1510#ifdef Q_OS_UNIX
1511 if ((mode & QAbstractSocket::ShareAddress) || (mode & QAbstractSocket::ReuseAddressHint))
1512 socketEngine->setOption(option: QAbstractSocketEngine::AddressReusable, value: 1);
1513 else
1514 socketEngine->setOption(option: QAbstractSocketEngine::AddressReusable, value: 0);
1515#endif
1516#ifdef Q_OS_WIN
1517 if (mode & QAbstractSocket::ReuseAddressHint)
1518 socketEngine->setOption(QAbstractSocketEngine::AddressReusable, 1);
1519 else
1520 socketEngine->setOption(QAbstractSocketEngine::AddressReusable, 0);
1521 if (mode & QAbstractSocket::DontShareAddress)
1522 socketEngine->setOption(QAbstractSocketEngine::BindExclusively, 1);
1523 else
1524 socketEngine->setOption(QAbstractSocketEngine::BindExclusively, 0);
1525#endif
1526 }
1527 bool result = socketEngine->bind(address, port);
1528 cachedSocketDescriptor = socketEngine->socketDescriptor();
1529
1530 if (!result) {
1531 setErrorAndEmit(errorCode: socketEngine->error(), errorString: socketEngine->errorString());
1532 return false;
1533 }
1534
1535 state = QAbstractSocket::BoundState;
1536 localAddress = socketEngine->localAddress();
1537 localPort = socketEngine->localPort();
1538
1539 emit q->stateChanged(state);
1540 // A slot attached to stateChanged() signal can break our invariant:
1541 // by closing the socket it will reset its socket engine - thus we
1542 // have additional check (isValid()) ...
1543 if (q->isValid() && socketType == QAbstractSocket::UdpSocket)
1544 socketEngine->setReadNotificationEnabled(true);
1545 return true;
1546}
1547
1548/*!
1549 \fn bool QAbstractSocket::bind(QHostAddress::SpecialAddress addr, quint16 port, BindMode mode)
1550 \since 6.2
1551 \overload
1552
1553 Binds to the special address \a addr on port \a port, using the BindMode \a
1554 mode.
1555
1556 By default, the socket is bound using the DefaultForPlatform BindMode.
1557 If a port is not specified, a random port is chosen.
1558*/
1559
1560/*!
1561 \fn bool QAbstractSocket::bind(quint16 port, BindMode mode)
1562 \since 5.0
1563 \overload
1564
1565 Binds to QHostAddress:Any on port \a port, using the BindMode \a mode.
1566
1567 By default, the socket is bound using the DefaultForPlatform BindMode.
1568 If a port is not specified, a random port is chosen.
1569*/
1570#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
1571bool QAbstractSocket::bind(quint16 port, BindMode mode)
1572{
1573 return bind(address: QHostAddress::Any, port, mode);
1574}
1575#endif
1576
1577/*!
1578 Returns \c true if the socket is valid and ready for use; otherwise
1579 returns \c false.
1580
1581 \note The socket's state must be ConnectedState before reading and
1582 writing can occur.
1583
1584 \sa state()
1585*/
1586bool QAbstractSocket::isValid() const
1587{
1588 return d_func()->socketEngine ? d_func()->socketEngine->isValid() : isOpen();
1589}
1590
1591/*!
1592 Attempts to make a connection to \a hostName on the given \a port.
1593 The \a protocol parameter can be used to specify which network
1594 protocol to use (eg. IPv4 or IPv6).
1595
1596 The socket is opened in the given \a openMode and first enters
1597 HostLookupState, then performs a host name lookup of \a hostName.
1598 If the lookup succeeds, hostFound() is emitted and QAbstractSocket
1599 enters ConnectingState. It then attempts to connect to the address
1600 or addresses returned by the lookup. Finally, if a connection is
1601 established, QAbstractSocket enters ConnectedState and
1602 emits connected().
1603
1604 At any point, the socket can emit errorOccurred() to signal that an error
1605 occurred.
1606
1607 \a hostName may be an IP address in string form (e.g.,
1608 "43.195.83.32"), or it may be a host name (e.g.,
1609 "example.com"). QAbstractSocket will do a lookup only if
1610 required. \a port is in native byte order.
1611
1612 \sa state(), peerName(), peerAddress(), peerPort(), waitForConnected()
1613*/
1614void QAbstractSocket::connectToHost(const QString &hostName, quint16 port,
1615 OpenMode openMode,
1616 NetworkLayerProtocol protocol)
1617{
1618 Q_D(QAbstractSocket);
1619#if defined(QABSTRACTSOCKET_DEBUG)
1620 qDebug("QAbstractSocket::connectToHost(\"%s\", %i, %i)...", qPrintable(hostName), port,
1621 (int) openMode);
1622#endif
1623
1624 if (d->state == ConnectedState || d->state == ConnectingState
1625 || d->state == ClosingState || d->state == HostLookupState) {
1626 qWarning(msg: "QAbstractSocket::connectToHost() called when already looking up or connecting/connected to \"%s\"", qPrintable(hostName));
1627 d->setErrorAndEmit(errorCode: OperationError, errorString: tr(s: "Trying to connect while connection is in progress"));
1628 return;
1629 }
1630
1631 d->preferredNetworkLayerProtocol = protocol;
1632 d->hostName = hostName;
1633 d->port = port;
1634 d->setReadChannelCount(0);
1635 d->setWriteChannelCount(0);
1636 d->abortCalled = false;
1637 d->pendingClose = false;
1638 if (d->state != BoundState) {
1639 d->state = UnconnectedState;
1640 d->localPort = 0;
1641 d->localAddress.clear();
1642 }
1643 d->peerPort = 0;
1644 d->peerAddress.clear();
1645 d->peerName = hostName;
1646 if (d->hostLookupId != -1) {
1647 QHostInfo::abortHostLookup(lookupId: d->hostLookupId);
1648 d->hostLookupId = -1;
1649 }
1650
1651#ifndef QT_NO_NETWORKPROXY
1652 // Get the proxy information
1653 d->resolveProxy(hostname: hostName, port);
1654 if (d->proxyInUse.type() == QNetworkProxy::DefaultProxy) {
1655 // failed to setup the proxy
1656 d->setErrorAndEmit(errorCode: UnsupportedSocketOperationError,
1657 errorString: tr(s: "Operation on socket is not supported"));
1658 return;
1659 }
1660#endif
1661
1662 // Sync up with error string, which open() shall clear.
1663 d->socketError = UnknownSocketError;
1664 if (openMode & QIODevice::Unbuffered)
1665 d->isBuffered = false;
1666 else if (!d_func()->isBuffered)
1667 openMode |= QAbstractSocket::Unbuffered;
1668
1669 QIODevice::open(mode: openMode);
1670 d->readChannelCount = d->writeChannelCount = 0;
1671
1672 d->state = HostLookupState;
1673 emit stateChanged(d->state);
1674
1675 QHostAddress temp;
1676 if (temp.setAddress(hostName)) {
1677 QHostInfo info;
1678 info.setAddresses(QList<QHostAddress>() << temp);
1679 d->_q_startConnecting(hostInfo: info);
1680#ifndef QT_NO_NETWORKPROXY
1681 } else if (d->proxyInUse.capabilities() & QNetworkProxy::HostNameLookupCapability) {
1682 // the proxy supports connection by name, so use it
1683 d->startConnectingByName(host: hostName);
1684 return;
1685#endif
1686 } else {
1687 if (d->threadData.loadRelaxed()->hasEventDispatcher()) {
1688 // this internal API for QHostInfo either immediately gives us the desired
1689 // QHostInfo from cache or later calls the _q_startConnecting slot.
1690 bool immediateResultValid = false;
1691 QHostInfo hostInfo = qt_qhostinfo_lookup(name: hostName,
1692 receiver: this,
1693 SLOT(_q_startConnecting(QHostInfo)),
1694 valid: &immediateResultValid,
1695 id: &d->hostLookupId);
1696 if (immediateResultValid) {
1697 d->hostLookupId = -1;
1698 d->_q_startConnecting(hostInfo);
1699 }
1700 }
1701 }
1702
1703#if defined(QABSTRACTSOCKET_DEBUG)
1704 qDebug("QAbstractSocket::connectToHost(\"%s\", %i) == %s%s", hostName.toLatin1().constData(), port,
1705 (d->state == ConnectedState) ? "true" : "false",
1706 (d->state == ConnectingState || d->state == HostLookupState)
1707 ? " (connection in progress)" : "");
1708#endif
1709}
1710
1711/*! \overload
1712
1713 Attempts to make a connection to \a address on port \a port.
1714*/
1715void QAbstractSocket::connectToHost(const QHostAddress &address, quint16 port,
1716 OpenMode openMode)
1717{
1718#if defined(QABSTRACTSOCKET_DEBUG)
1719 qDebug("QAbstractSocket::connectToHost([%s], %i, %i)...",
1720 address.toString().toLatin1().constData(), port, (int) openMode);
1721#endif
1722 connectToHost(hostName: address.toString(), port, openMode);
1723}
1724
1725/*!
1726 Returns the number of bytes that are waiting to be written. The
1727 bytes are written when control goes back to the event loop or
1728 when flush() is called.
1729
1730 \sa bytesAvailable(), flush()
1731*/
1732qint64 QAbstractSocket::bytesToWrite() const
1733{
1734 const qint64 pendingBytes = QIODevice::bytesToWrite();
1735#if defined(QABSTRACTSOCKET_DEBUG)
1736 qDebug("QAbstractSocket::bytesToWrite() == %lld", pendingBytes);
1737#endif
1738 return pendingBytes;
1739}
1740
1741/*!
1742 Returns the number of incoming bytes that are waiting to be read.
1743
1744 \sa bytesToWrite(), read()
1745*/
1746qint64 QAbstractSocket::bytesAvailable() const
1747{
1748 Q_D(const QAbstractSocket);
1749 qint64 available = QIODevice::bytesAvailable();
1750
1751 if (!d->isBuffered && d->socketEngine && d->socketEngine->isValid())
1752 available += d->socketEngine->bytesAvailable();
1753
1754#if defined(QABSTRACTSOCKET_DEBUG)
1755 qDebug("QAbstractSocket::bytesAvailable() == %lld", available);
1756#endif
1757 return available;
1758}
1759
1760/*!
1761 Returns the host port number (in native byte order) of the local
1762 socket if available; otherwise returns 0.
1763
1764 \sa localAddress(), peerPort(), setLocalPort()
1765*/
1766quint16 QAbstractSocket::localPort() const
1767{
1768 Q_D(const QAbstractSocket);
1769 return d->localPort;
1770}
1771
1772/*!
1773 Returns the host address of the local socket if available;
1774 otherwise returns QHostAddress::Null.
1775
1776 This is normally the main IP address of the host, but can be
1777 QHostAddress::LocalHost (127.0.0.1) for connections to the
1778 local host.
1779
1780 \sa localPort(), peerAddress(), setLocalAddress()
1781*/
1782QHostAddress QAbstractSocket::localAddress() const
1783{
1784 Q_D(const QAbstractSocket);
1785 return d->localAddress;
1786}
1787
1788/*!
1789 Returns the port of the connected peer if the socket is in
1790 ConnectedState; otherwise returns 0.
1791
1792 \sa peerAddress(), localPort(), setPeerPort()
1793*/
1794quint16 QAbstractSocket::peerPort() const
1795{
1796 Q_D(const QAbstractSocket);
1797 return d->peerPort;
1798}
1799
1800/*!
1801 Returns the address of the connected peer if the socket is in
1802 ConnectedState; otherwise returns QHostAddress::Null.
1803
1804 \sa peerName(), peerPort(), localAddress(), setPeerAddress()
1805*/
1806QHostAddress QAbstractSocket::peerAddress() const
1807{
1808 Q_D(const QAbstractSocket);
1809 return d->peerAddress;
1810}
1811
1812/*!
1813 Returns the name of the peer as specified by connectToHost(), or
1814 an empty QString if connectToHost() has not been called.
1815
1816 \sa peerAddress(), peerPort(), setPeerName()
1817*/
1818QString QAbstractSocket::peerName() const
1819{
1820 Q_D(const QAbstractSocket);
1821 return d->peerName.isEmpty() ? d->hostName : d->peerName;
1822}
1823
1824/*!
1825 Returns the native socket descriptor of the QAbstractSocket object
1826 if this is available; otherwise returns -1.
1827
1828 If the socket is using QNetworkProxy, the returned descriptor
1829 may not be usable with native socket functions.
1830
1831 The socket descriptor is not available when QAbstractSocket is in
1832 UnconnectedState.
1833
1834 \sa setSocketDescriptor()
1835*/
1836qintptr QAbstractSocket::socketDescriptor() const
1837{
1838 Q_D(const QAbstractSocket);
1839 return d->cachedSocketDescriptor;
1840}
1841
1842/*!
1843 Initializes QAbstractSocket with the native socket descriptor \a
1844 socketDescriptor. Returns \c true if \a socketDescriptor is accepted
1845 as a valid socket descriptor; otherwise returns \c false.
1846 The socket is opened in the mode specified by \a openMode, and
1847 enters the socket state specified by \a socketState.
1848 Read and write buffers are cleared, discarding any pending data.
1849
1850 \b{Note:} It is not possible to initialize two abstract sockets
1851 with the same native socket descriptor.
1852
1853 \sa socketDescriptor()
1854*/
1855bool QAbstractSocket::setSocketDescriptor(qintptr socketDescriptor, SocketState socketState,
1856 OpenMode openMode)
1857{
1858 Q_D(QAbstractSocket);
1859
1860 d->resetSocketLayer();
1861 d->setReadChannelCount(0);
1862 d->setWriteChannelCount(0);
1863 d->socketEngine = QAbstractSocketEngine::createSocketEngine(socketDescriptor, parent: this);
1864 if (!d->socketEngine) {
1865 d->setError(errorCode: UnsupportedSocketOperationError, errStr: tr(s: "Operation on socket is not supported"));
1866 return false;
1867 }
1868 bool result = d->socketEngine->initialize(socketDescriptor, socketState);
1869 if (!result) {
1870 d->setError(errorCode: d->socketEngine->error(), errStr: d->socketEngine->errorString());
1871 return false;
1872 }
1873
1874 // Sync up with error string, which open() shall clear.
1875 d->socketError = UnknownSocketError;
1876 if (d->threadData.loadRelaxed()->hasEventDispatcher())
1877 d->socketEngine->setReceiver(d);
1878
1879 QIODevice::open(mode: openMode);
1880
1881 if (socketState == ConnectedState) {
1882 if (isReadable()) {
1883 const int inboundStreamCount = d->socketEngine->inboundStreamCount();
1884 d->setReadChannelCount(qMax(a: 1, b: inboundStreamCount));
1885 if (inboundStreamCount == 0)
1886 d->readChannelCount = 0;
1887 }
1888 if (isWritable()) {
1889 const int outboundStreamCount = d->socketEngine->outboundStreamCount();
1890 d->setWriteChannelCount(qMax(a: 1, b: outboundStreamCount));
1891 if (outboundStreamCount == 0)
1892 d->writeChannelCount = 0;
1893 }
1894 } else {
1895 d->readChannelCount = d->writeChannelCount = 0;
1896 }
1897
1898 if (d->state != socketState) {
1899 d->state = socketState;
1900 emit stateChanged(d->state);
1901 }
1902
1903 d->pendingClose = false;
1904 d->socketEngine->setReadNotificationEnabled(true);
1905 d->localPort = d->socketEngine->localPort();
1906 d->peerPort = d->socketEngine->peerPort();
1907 d->localAddress = d->socketEngine->localAddress();
1908 d->peerAddress = d->socketEngine->peerAddress();
1909 d->cachedSocketDescriptor = socketDescriptor;
1910
1911 return true;
1912}
1913
1914/*!
1915 \since 4.6
1916 Sets the given \a option to the value described by \a value.
1917
1918 \note Since the options are set on an internal socket the options
1919 only apply if the socket has been created. This is only guaranteed to
1920 have happened after a call to bind(), or when connected() has been emitted.
1921
1922 \sa socketOption()
1923*/
1924void QAbstractSocket::setSocketOption(QAbstractSocket::SocketOption option, const QVariant &value)
1925{
1926 if (!d_func()->socketEngine)
1927 return;
1928
1929 switch (option) {
1930 case LowDelayOption:
1931 d_func()->socketEngine->setOption(option: QAbstractSocketEngine::LowDelayOption, value: value.toInt());
1932 break;
1933
1934 case KeepAliveOption:
1935 d_func()->socketEngine->setOption(option: QAbstractSocketEngine::KeepAliveOption, value: value.toInt());
1936 break;
1937
1938 case MulticastTtlOption:
1939 d_func()->socketEngine->setOption(option: QAbstractSocketEngine::MulticastTtlOption, value: value.toInt());
1940 break;
1941
1942 case MulticastLoopbackOption:
1943 d_func()->socketEngine->setOption(option: QAbstractSocketEngine::MulticastLoopbackOption, value: value.toInt());
1944 break;
1945
1946 case TypeOfServiceOption:
1947 d_func()->socketEngine->setOption(option: QAbstractSocketEngine::TypeOfServiceOption, value: value.toInt());
1948 break;
1949
1950 case SendBufferSizeSocketOption:
1951 d_func()->socketEngine->setOption(option: QAbstractSocketEngine::SendBufferSocketOption, value: value.toInt());
1952 break;
1953
1954 case ReceiveBufferSizeSocketOption:
1955 d_func()->socketEngine->setOption(option: QAbstractSocketEngine::ReceiveBufferSocketOption, value: value.toInt());
1956 break;
1957
1958 case PathMtuSocketOption:
1959 d_func()->socketEngine->setOption(option: QAbstractSocketEngine::PathMtuInformation, value: value.toInt());
1960 break;
1961 }
1962}
1963
1964/*!
1965 \since 4.6
1966 Returns the value of the \a option option.
1967
1968 \sa setSocketOption()
1969*/
1970QVariant QAbstractSocket::socketOption(QAbstractSocket::SocketOption option)
1971{
1972 if (!d_func()->socketEngine)
1973 return QVariant();
1974
1975 int ret = -1;
1976 switch (option) {
1977 case LowDelayOption:
1978 ret = d_func()->socketEngine->option(option: QAbstractSocketEngine::LowDelayOption);
1979 break;
1980
1981 case KeepAliveOption:
1982 ret = d_func()->socketEngine->option(option: QAbstractSocketEngine::KeepAliveOption);
1983 break;
1984
1985 case MulticastTtlOption:
1986 ret = d_func()->socketEngine->option(option: QAbstractSocketEngine::MulticastTtlOption);
1987 break;
1988 case MulticastLoopbackOption:
1989 ret = d_func()->socketEngine->option(option: QAbstractSocketEngine::MulticastLoopbackOption);
1990 break;
1991
1992 case TypeOfServiceOption:
1993 ret = d_func()->socketEngine->option(option: QAbstractSocketEngine::TypeOfServiceOption);
1994 break;
1995
1996 case SendBufferSizeSocketOption:
1997 ret = d_func()->socketEngine->option(option: QAbstractSocketEngine::SendBufferSocketOption);
1998 break;
1999
2000 case ReceiveBufferSizeSocketOption:
2001 ret = d_func()->socketEngine->option(option: QAbstractSocketEngine::ReceiveBufferSocketOption);
2002 break;
2003
2004 case PathMtuSocketOption:
2005 ret = d_func()->socketEngine->option(option: QAbstractSocketEngine::PathMtuInformation);
2006 break;
2007 }
2008 if (ret == -1)
2009 return QVariant();
2010 else
2011 return QVariant(ret);
2012}
2013
2014/*!
2015 Waits until the socket is connected, up to \a msecs
2016 milliseconds. If the connection has been established, this
2017 function returns \c true; otherwise it returns \c false. In the case
2018 where it returns \c false, you can call error() to determine
2019 the cause of the error.
2020
2021 The following example waits up to one second for a connection
2022 to be established:
2023
2024 \snippet code/src_network_socket_qabstractsocket.cpp 0
2025
2026 If msecs is -1, this function will not time out.
2027
2028 \note This function may wait slightly longer than \a msecs,
2029 depending on the time it takes to complete the host lookup.
2030
2031 \note Multiple calls to this functions do not accumulate the time.
2032 If the function times out, the connecting process will be aborted.
2033
2034 \note This function may fail randomly on Windows. Consider using the event
2035 loop and the connected() signal if your software will run on Windows.
2036
2037 \sa connectToHost(), connected()
2038*/
2039bool QAbstractSocket::waitForConnected(int msecs)
2040{
2041 Q_D(QAbstractSocket);
2042#if defined (QABSTRACTSOCKET_DEBUG)
2043 qDebug("QAbstractSocket::waitForConnected(%i)", msecs);
2044#endif
2045
2046 if (state() == ConnectedState) {
2047#if defined (QABSTRACTSOCKET_DEBUG)
2048 qDebug("QAbstractSocket::waitForConnected(%i) already connected", msecs);
2049#endif
2050 return true;
2051 }
2052
2053 bool wasPendingClose = d->pendingClose;
2054 d->pendingClose = false;
2055 QElapsedTimer stopWatch;
2056 stopWatch.start();
2057
2058 if (d->state == HostLookupState) {
2059#if defined (QABSTRACTSOCKET_DEBUG)
2060 qDebug("QAbstractSocket::waitForConnected(%i) doing host name lookup", msecs);
2061#endif
2062 QHostInfo::abortHostLookup(lookupId: d->hostLookupId);
2063 d->hostLookupId = -1;
2064 QHostAddress temp;
2065 if (temp.setAddress(d->hostName)) {
2066 QHostInfo info;
2067 info.setAddresses(QList<QHostAddress>() << temp);
2068 d->_q_startConnecting(hostInfo: info);
2069 } else {
2070 d->_q_startConnecting(hostInfo: QHostInfo::fromName(name: d->hostName));
2071 }
2072 }
2073 if (state() == UnconnectedState)
2074 return false; // connect not im progress anymore!
2075
2076 int connectTimeout = DefaultConnectTimeout;
2077 bool timedOut = true;
2078#if defined (QABSTRACTSOCKET_DEBUG)
2079 int attempt = 1;
2080#endif
2081 while (state() == ConnectingState && (msecs == -1 || stopWatch.elapsed() < msecs)) {
2082 int timeout = qt_subtract_from_timeout(timeout: msecs, elapsed: stopWatch.elapsed());
2083 if (msecs != -1 && timeout > connectTimeout)
2084 timeout = connectTimeout;
2085#if defined (QABSTRACTSOCKET_DEBUG)
2086 qDebug("QAbstractSocket::waitForConnected(%i) waiting %.2f secs for connection attempt #%i",
2087 msecs, timeout / 1000.0, attempt++);
2088#endif
2089 timedOut = false;
2090
2091 if (d->socketEngine && d->socketEngine->waitForWrite(msecs: timeout, timedOut: &timedOut) && !timedOut) {
2092 d->_q_testConnection();
2093 } else {
2094 d->_q_connectToNextAddress();
2095 }
2096 }
2097
2098 if ((timedOut && state() != ConnectedState) || state() == ConnectingState) {
2099 d->setError(errorCode: SocketTimeoutError, errStr: tr(s: "Socket operation timed out"));
2100 d->state = UnconnectedState;
2101 emit stateChanged(d->state);
2102 d->resetSocketLayer();
2103 }
2104
2105#if defined (QABSTRACTSOCKET_DEBUG)
2106 qDebug("QAbstractSocket::waitForConnected(%i) == %s", msecs,
2107 state() == ConnectedState ? "true" : "false");
2108#endif
2109 if (state() != ConnectedState)
2110 return false;
2111 if (wasPendingClose)
2112 disconnectFromHost();
2113 return true;
2114}
2115
2116/*!
2117 This function blocks until new data is available for reading and the
2118 \l{QIODevice::}{readyRead()} signal has been emitted. The function
2119 will timeout after \a msecs milliseconds; the default timeout is
2120 30000 milliseconds.
2121
2122 The function returns \c true if the readyRead() signal is emitted and
2123 there is new data available for reading; otherwise it returns \c false
2124 (if an error occurred or the operation timed out).
2125
2126 \note This function may fail randomly on Windows. Consider using the event
2127 loop and the readyRead() signal if your software will run on Windows.
2128
2129 \sa waitForBytesWritten()
2130*/
2131bool QAbstractSocket::waitForReadyRead(int msecs)
2132{
2133 Q_D(QAbstractSocket);
2134#if defined (QABSTRACTSOCKET_DEBUG)
2135 qDebug("QAbstractSocket::waitForReadyRead(%i)", msecs);
2136#endif
2137
2138 // require calling connectToHost() before waitForReadyRead()
2139 if (state() == UnconnectedState) {
2140 /* If all you have is a QIODevice pointer to an abstractsocket, you cannot check
2141 this, so you cannot avoid this warning. */
2142// qWarning("QAbstractSocket::waitForReadyRead() is not allowed in UnconnectedState");
2143 return false;
2144 }
2145
2146 QElapsedTimer stopWatch;
2147 stopWatch.start();
2148
2149 // handle a socket in connecting state
2150 if (state() == HostLookupState || state() == ConnectingState) {
2151 if (!waitForConnected(msecs))
2152 return false;
2153 }
2154
2155 do {
2156 if (state() != ConnectedState && state() != BoundState)
2157 return false;
2158 Q_ASSERT(d->socketEngine);
2159
2160 bool readyToRead = false;
2161 bool readyToWrite = false;
2162 if (!d->socketEngine->waitForReadOrWrite(readyToRead: &readyToRead, readyToWrite: &readyToWrite, checkRead: true, checkWrite: !d->writeBuffer.isEmpty(),
2163 msecs: qt_subtract_from_timeout(timeout: msecs, elapsed: stopWatch.elapsed()))) {
2164#if defined (QABSTRACTSOCKET_DEBUG)
2165 qDebug("QAbstractSocket::waitForReadyRead(%i) failed (%i, %s)",
2166 msecs, d->socketEngine->error(), d->socketEngine->errorString().toLatin1().constData());
2167#endif
2168 d->setErrorAndEmit(errorCode: d->socketEngine->error(), errorString: d->socketEngine->errorString());
2169 if (d->socketError != SocketTimeoutError)
2170 close();
2171 return false;
2172 }
2173
2174 if (readyToRead) {
2175 if (d->canReadNotification())
2176 return true;
2177 }
2178
2179 if (readyToWrite)
2180 d->canWriteNotification();
2181 } while (msecs == -1 || qt_subtract_from_timeout(timeout: msecs, elapsed: stopWatch.elapsed()) > 0);
2182 return false;
2183}
2184
2185/*! \reimp
2186
2187 This function blocks until at least one byte has been written on the socket
2188 and the \l{QIODevice::}{bytesWritten()} signal has been emitted. The
2189 function will timeout after \a msecs milliseconds; the default timeout is
2190 30000 milliseconds.
2191
2192 The function returns \c true if the bytesWritten() signal is emitted;
2193 otherwise it returns \c false (if an error occurred or the operation timed
2194 out).
2195
2196 \note This function may fail randomly on Windows. Consider using the event
2197 loop and the bytesWritten() signal if your software will run on Windows.
2198
2199 \sa waitForReadyRead()
2200 */
2201bool QAbstractSocket::waitForBytesWritten(int msecs)
2202{
2203 Q_D(QAbstractSocket);
2204#if defined (QABSTRACTSOCKET_DEBUG)
2205 qDebug("QAbstractSocket::waitForBytesWritten(%i)", msecs);
2206#endif
2207
2208 // require calling connectToHost() before waitForBytesWritten()
2209 if (state() == UnconnectedState) {
2210 qWarning(msg: "QAbstractSocket::waitForBytesWritten() is not allowed in UnconnectedState");
2211 return false;
2212 }
2213
2214 if (d->writeBuffer.isEmpty())
2215 return false;
2216
2217 QElapsedTimer stopWatch;
2218 stopWatch.start();
2219
2220 // handle a socket in connecting state
2221 if (state() == HostLookupState || state() == ConnectingState) {
2222 if (!waitForConnected(msecs))
2223 return false;
2224 }
2225
2226 forever {
2227 bool readyToRead = false;
2228 bool readyToWrite = false;
2229 if (!d->socketEngine->waitForReadOrWrite(readyToRead: &readyToRead, readyToWrite: &readyToWrite,
2230 checkRead: !d->readBufferMaxSize || d->buffer.size() < d->readBufferMaxSize,
2231 checkWrite: !d->writeBuffer.isEmpty(),
2232 msecs: qt_subtract_from_timeout(timeout: msecs, elapsed: stopWatch.elapsed()))) {
2233#if defined (QABSTRACTSOCKET_DEBUG)
2234 qDebug("QAbstractSocket::waitForBytesWritten(%i) failed (%i, %s)",
2235 msecs, d->socketEngine->error(), d->socketEngine->errorString().toLatin1().constData());
2236#endif
2237 d->setErrorAndEmit(errorCode: d->socketEngine->error(), errorString: d->socketEngine->errorString());
2238 if (d->socketError != SocketTimeoutError)
2239 close();
2240 return false;
2241 }
2242
2243 if (readyToRead) {
2244#if defined (QABSTRACTSOCKET_DEBUG)
2245 qDebug("QAbstractSocket::waitForBytesWritten calls canReadNotification");
2246#endif
2247 d->canReadNotification();
2248 }
2249
2250
2251 if (readyToWrite) {
2252 if (d->canWriteNotification()) {
2253#if defined (QABSTRACTSOCKET_DEBUG)
2254 qDebug("QAbstractSocket::waitForBytesWritten returns true");
2255#endif
2256 return true;
2257 }
2258 }
2259
2260 if (state() != ConnectedState)
2261 return false;
2262 }
2263 return false;
2264}
2265
2266/*!
2267 Waits until the socket has disconnected, up to \a msecs milliseconds. If the
2268 connection was successfully disconnected, this function returns \c true;
2269 otherwise it returns \c false (if the operation timed out, if an error
2270 occurred, or if this QAbstractSocket is already disconnected). In the case
2271 where it returns \c false, you can call error() to determine the cause of
2272 the error.
2273
2274 The following example waits up to one second for a connection
2275 to be closed:
2276
2277 \snippet code/src_network_socket_qabstractsocket.cpp 1
2278
2279 If msecs is -1, this function will not time out.
2280
2281 \note This function may fail randomly on Windows. Consider using the event
2282 loop and the disconnected() signal if your software will run on Windows.
2283
2284 \sa disconnectFromHost(), close()
2285*/
2286bool QAbstractSocket::waitForDisconnected(int msecs)
2287{
2288 Q_D(QAbstractSocket);
2289
2290 // require calling connectToHost() before waitForDisconnected()
2291 if (state() == UnconnectedState) {
2292 qWarning(msg: "QAbstractSocket::waitForDisconnected() is not allowed in UnconnectedState");
2293 return false;
2294 }
2295
2296 QElapsedTimer stopWatch;
2297 stopWatch.start();
2298
2299 // handle a socket in connecting state
2300 if (state() == HostLookupState || state() == ConnectingState) {
2301 if (!waitForConnected(msecs))
2302 return false;
2303 if (state() == UnconnectedState)
2304 return true;
2305 }
2306
2307 forever {
2308 bool readyToRead = false;
2309 bool readyToWrite = false;
2310 if (!d->socketEngine->waitForReadOrWrite(readyToRead: &readyToRead, readyToWrite: &readyToWrite, checkRead: state() == ConnectedState,
2311 checkWrite: !d->writeBuffer.isEmpty(),
2312 msecs: qt_subtract_from_timeout(timeout: msecs, elapsed: stopWatch.elapsed()))) {
2313#if defined (QABSTRACTSOCKET_DEBUG)
2314 qDebug("QAbstractSocket::waitForReadyRead(%i) failed (%i, %s)",
2315 msecs, d->socketEngine->error(), d->socketEngine->errorString().toLatin1().constData());
2316#endif
2317 d->setErrorAndEmit(errorCode: d->socketEngine->error(), errorString: d->socketEngine->errorString());
2318 if (d->socketError != SocketTimeoutError)
2319 close();
2320 return false;
2321 }
2322
2323 if (readyToRead)
2324 d->canReadNotification();
2325 if (readyToWrite)
2326 d->canWriteNotification();
2327
2328 if (state() == UnconnectedState)
2329 return true;
2330 }
2331 return false;
2332}
2333
2334/*!
2335 Aborts the current connection and resets the socket. Unlike disconnectFromHost(),
2336 this function immediately closes the socket, discarding any pending data in the
2337 write buffer.
2338
2339 \sa disconnectFromHost(), close()
2340*/
2341void QAbstractSocket::abort()
2342{
2343 Q_D(QAbstractSocket);
2344#if defined (QABSTRACTSOCKET_DEBUG)
2345 qDebug("QAbstractSocket::abort()");
2346#endif
2347 d->setWriteChannelCount(0);
2348 d->abortCalled = true;
2349 close();
2350}
2351
2352/*! \reimp
2353*/
2354bool QAbstractSocket::isSequential() const
2355{
2356 return true;
2357}
2358
2359/*!
2360 This function writes as much as possible from the internal write buffer to
2361 the underlying network socket, without blocking. If any data was written,
2362 this function returns \c true; otherwise false is returned.
2363
2364 Call this function if you need QAbstractSocket to start sending buffered
2365 data immediately. The number of bytes successfully written depends on the
2366 operating system. In most cases, you do not need to call this function,
2367 because QAbstractSocket will start sending data automatically once control
2368 goes back to the event loop. In the absence of an event loop, call
2369 waitForBytesWritten() instead.
2370
2371 \sa write(), waitForBytesWritten()
2372*/
2373bool QAbstractSocket::flush()
2374{
2375 return d_func()->flush();
2376}
2377
2378/*! \reimp
2379*/
2380qint64 QAbstractSocket::readData(char *data, qint64 maxSize)
2381{
2382 Q_D(QAbstractSocket);
2383
2384 // if we're not connected, return -1 indicating EOF
2385 if (!d->socketEngine || !d->socketEngine->isValid() || d->state != QAbstractSocket::ConnectedState)
2386 return maxSize ? qint64(-1) : qint64(0);
2387
2388 qint64 readBytes = (maxSize && !d->isBuffered) ? d->socketEngine->read(data, maxlen: maxSize)
2389 : qint64(0);
2390 if (readBytes == -2) {
2391 // -2 from the engine means no bytes available (EAGAIN) so read more later
2392 readBytes = 0;
2393 }
2394 if (readBytes < 0) {
2395 d->setError(errorCode: d->socketEngine->error(), errStr: d->socketEngine->errorString());
2396 d->resetSocketLayer();
2397 d->state = QAbstractSocket::UnconnectedState;
2398 } else {
2399 // Only do this when there was no error
2400 d->hasPendingData = false;
2401 d->socketEngine->setReadNotificationEnabled(true);
2402 }
2403
2404#if defined (QABSTRACTSOCKET_DEBUG)
2405 qDebug("QAbstractSocket::readData(%p \"%s\", %lli) == %lld [engine]", data,
2406 QtDebugUtils::toPrintable(data, readBytes, 32).constData(), maxSize, readBytes);
2407#endif
2408 return readBytes;
2409}
2410
2411/*! \reimp
2412*/
2413qint64 QAbstractSocket::readLineData(char *data, qint64 maxlen)
2414{
2415 return QIODevice::readLineData(data, maxlen);
2416}
2417
2418/*! \reimp
2419*/
2420qint64 QAbstractSocket::writeData(const char *data, qint64 size)
2421{
2422 Q_D(QAbstractSocket);
2423 if (d->state == QAbstractSocket::UnconnectedState
2424 || (!d->socketEngine && d->socketType != TcpSocket && !d->isBuffered)) {
2425 d->setError(errorCode: UnknownSocketError, errStr: tr(s: "Socket is not connected"));
2426 return -1;
2427 }
2428
2429 if (!d->isBuffered && d->socketType == TcpSocket
2430 && d->socketEngine && d->writeBuffer.isEmpty()) {
2431 // This code is for the new Unbuffered QTcpSocket use case
2432 qint64 written = size ? d->socketEngine->write(data, len: size) : Q_INT64_C(0);
2433 if (written < 0) {
2434 d->setError(errorCode: d->socketEngine->error(), errStr: d->socketEngine->errorString());
2435 } else if (written < size) {
2436 // Buffer what was not written yet
2437 d->writeBuffer.append(data: data + written, size: size - written);
2438 written = size;
2439 d->socketEngine->setWriteNotificationEnabled(true);
2440 }
2441
2442#if defined (QABSTRACTSOCKET_DEBUG)
2443 qDebug("QAbstractSocket::writeData(%p \"%s\", %lli) == %lli", data,
2444 QtDebugUtils::toPrintable(data, size, 32).constData(), size, written);
2445#endif
2446 return written; // written = actually written + what has been buffered
2447 } else if (!d->isBuffered && d->socketType != TcpSocket) {
2448 // This is for a QUdpSocket that was connect()ed
2449 qint64 written = d->socketEngine->write(data, len: size);
2450 if (written < 0)
2451 d->setError(errorCode: d->socketEngine->error(), errStr: d->socketEngine->errorString());
2452
2453#if defined (QABSTRACTSOCKET_DEBUG)
2454 qDebug("QAbstractSocket::writeData(%p \"%s\", %lli) == %lli", data,
2455 QtDebugUtils::toPrintable(data, size, 32).constData(), size, written);
2456#endif
2457 if (written >= 0)
2458 d->emitBytesWritten(bytes: written);
2459 return written;
2460 }
2461
2462 // This is the code path for normal buffered QTcpSocket or
2463 // unbuffered QTcpSocket when there was already something in the
2464 // write buffer and therefore we could not do a direct engine write.
2465 // We just write to our write buffer and enable the write notifier
2466 // The write notifier then flush()es the buffer.
2467
2468 d->write(data, size);
2469 qint64 written = size;
2470
2471 if (d->socketEngine && !d->writeBuffer.isEmpty())
2472 d->socketEngine->setWriteNotificationEnabled(true);
2473
2474#if defined (QABSTRACTSOCKET_DEBUG)
2475 qDebug("QAbstractSocket::writeData(%p \"%s\", %lli) == %lli", data,
2476 QtDebugUtils::toPrintable(data, size, 32).constData(), size, written);
2477#endif
2478 return written;
2479}
2480
2481/*!
2482 \since 4.1
2483
2484 Sets the port on the local side of a connection to \a port.
2485
2486 You can call this function in a subclass of QAbstractSocket to
2487 change the return value of the localPort() function after a
2488 connection has been established. This feature is commonly used by
2489 proxy connections for virtual connection settings.
2490
2491 Note that this function does not bind the local port of the socket
2492 prior to a connection (e.g., QAbstractSocket::bind()).
2493
2494 \sa localAddress(), setLocalAddress(), setPeerPort()
2495*/
2496void QAbstractSocket::setLocalPort(quint16 port)
2497{
2498 Q_D(QAbstractSocket);
2499 d->localPort = port;
2500}
2501
2502/*!
2503 \since 4.1
2504
2505 Sets the address on the local side of a connection to
2506 \a address.
2507
2508 You can call this function in a subclass of QAbstractSocket to
2509 change the return value of the localAddress() function after a
2510 connection has been established. This feature is commonly used by
2511 proxy connections for virtual connection settings.
2512
2513 Note that this function does not bind the local address of the socket
2514 prior to a connection (e.g., QAbstractSocket::bind()).
2515
2516 \sa localAddress(), setLocalPort(), setPeerAddress()
2517*/
2518void QAbstractSocket::setLocalAddress(const QHostAddress &address)
2519{
2520 Q_D(QAbstractSocket);
2521 d->localAddress = address;
2522}
2523
2524/*!
2525 \since 4.1
2526
2527 Sets the port of the remote side of the connection to
2528 \a port.
2529
2530 You can call this function in a subclass of QAbstractSocket to
2531 change the return value of the peerPort() function after a
2532 connection has been established. This feature is commonly used by
2533 proxy connections for virtual connection settings.
2534
2535 \sa peerPort(), setPeerAddress(), setLocalPort()
2536*/
2537void QAbstractSocket::setPeerPort(quint16 port)
2538{
2539 Q_D(QAbstractSocket);
2540 d->peerPort = port;
2541}
2542
2543/*!
2544 \since 4.1
2545
2546 Sets the address of the remote side of the connection
2547 to \a address.
2548
2549 You can call this function in a subclass of QAbstractSocket to
2550 change the return value of the peerAddress() function after a
2551 connection has been established. This feature is commonly used by
2552 proxy connections for virtual connection settings.
2553
2554 \sa peerAddress(), setPeerPort(), setLocalAddress()
2555*/
2556void QAbstractSocket::setPeerAddress(const QHostAddress &address)
2557{
2558 Q_D(QAbstractSocket);
2559 d->peerAddress = address;
2560}
2561
2562/*!
2563 \since 4.1
2564
2565 Sets the host name of the remote peer to \a name.
2566
2567 You can call this function in a subclass of QAbstractSocket to
2568 change the return value of the peerName() function after a
2569 connection has been established. This feature is commonly used by
2570 proxy connections for virtual connection settings.
2571
2572 \sa peerName()
2573*/
2574void QAbstractSocket::setPeerName(const QString &name)
2575{
2576 Q_D(QAbstractSocket);
2577 d->peerName = name;
2578}
2579
2580/*!
2581 Closes the I/O device for the socket and calls disconnectFromHost()
2582 to close the socket's connection.
2583
2584 See QIODevice::close() for a description of the actions that occur when an I/O
2585 device is closed.
2586
2587 \sa abort()
2588*/
2589void QAbstractSocket::close()
2590{
2591 Q_D(QAbstractSocket);
2592#if defined(QABSTRACTSOCKET_DEBUG)
2593 qDebug("QAbstractSocket::close()");
2594#endif
2595 QIODevice::close();
2596 if (d->state != UnconnectedState)
2597 disconnectFromHost();
2598}
2599
2600/*!
2601 Attempts to close the socket. If there is pending data waiting to
2602 be written, QAbstractSocket will enter ClosingState and wait
2603 until all data has been written. Eventually, it will enter
2604 UnconnectedState and emit the disconnected() signal.
2605
2606 \sa connectToHost()
2607*/
2608void QAbstractSocket::disconnectFromHost()
2609{
2610 Q_D(QAbstractSocket);
2611#if defined(QABSTRACTSOCKET_DEBUG)
2612 qDebug("QAbstractSocket::disconnectFromHost()");
2613#endif
2614
2615 if (d->state == UnconnectedState) {
2616#if defined(QABSTRACTSOCKET_DEBUG)
2617 qDebug("QAbstractSocket::disconnectFromHost() was called on an unconnected socket");
2618#endif
2619 return;
2620 }
2621
2622 if (!d->abortCalled && (d->state == ConnectingState || d->state == HostLookupState)) {
2623#if defined(QABSTRACTSOCKET_DEBUG)
2624 qDebug("QAbstractSocket::disconnectFromHost() but we're still connecting");
2625#endif
2626 d->pendingClose = true;
2627 return;
2628 }
2629
2630 // Disable and delete read notification
2631 if (d->socketEngine)
2632 d->socketEngine->setReadNotificationEnabled(false);
2633
2634 if (d->abortCalled) {
2635#if defined(QABSTRACTSOCKET_DEBUG)
2636 qDebug("QAbstractSocket::disconnectFromHost() aborting immediately");
2637#endif
2638 if (d->state == HostLookupState) {
2639 QHostInfo::abortHostLookup(lookupId: d->hostLookupId);
2640 d->hostLookupId = -1;
2641 }
2642 } else {
2643 // Perhaps emit closing()
2644 if (d->state != ClosingState) {
2645 d->state = ClosingState;
2646#if defined(QABSTRACTSOCKET_DEBUG)
2647 qDebug("QAbstractSocket::disconnectFromHost() emits stateChanged()(ClosingState)");
2648#endif
2649 emit stateChanged(d->state);
2650 } else {
2651#if defined(QABSTRACTSOCKET_DEBUG)
2652 qDebug("QAbstractSocket::disconnectFromHost() return from delayed close");
2653#endif
2654 }
2655
2656 // Wait for pending data to be written.
2657 if (d->socketEngine && d->socketEngine->isValid() && (!d->allWriteBuffersEmpty()
2658 || d->socketEngine->bytesToWrite() > 0)) {
2659 d->socketEngine->setWriteNotificationEnabled(true);
2660
2661#if defined(QABSTRACTSOCKET_DEBUG)
2662 qDebug("QAbstractSocket::disconnectFromHost() delaying disconnect");
2663#endif
2664 return;
2665 } else {
2666#if defined(QABSTRACTSOCKET_DEBUG)
2667 qDebug("QAbstractSocket::disconnectFromHost() disconnecting immediately");
2668#endif
2669 }
2670 }
2671
2672 SocketState previousState = d->state;
2673 d->resetSocketLayer();
2674 d->state = UnconnectedState;
2675 emit stateChanged(d->state);
2676 emit readChannelFinished(); // we got an EOF
2677
2678 // only emit disconnected if we were connected before
2679 if (previousState == ConnectedState || previousState == ClosingState)
2680 emit disconnected();
2681
2682 d->localPort = 0;
2683 d->peerPort = 0;
2684 d->localAddress.clear();
2685 d->peerAddress.clear();
2686 d->peerName.clear();
2687 d->setWriteChannelCount(0);
2688
2689#if defined(QABSTRACTSOCKET_DEBUG)
2690 qDebug("QAbstractSocket::disconnectFromHost() disconnected!");
2691#endif
2692
2693}
2694
2695/*!
2696 Returns the size of the internal read buffer. This limits the
2697 amount of data that the client can receive before you call read()
2698 or readAll().
2699
2700 A read buffer size of 0 (the default) means that the buffer has
2701 no size limit, ensuring that no data is lost.
2702
2703 \sa setReadBufferSize(), read()
2704*/
2705qint64 QAbstractSocket::readBufferSize() const
2706{
2707 return d_func()->readBufferMaxSize;
2708}
2709
2710/*!
2711 Sets the size of QAbstractSocket's internal read buffer to be \a
2712 size bytes.
2713
2714 If the buffer size is limited to a certain size, QAbstractSocket
2715 won't buffer more than this size of data. Exceptionally, a buffer
2716 size of 0 means that the read buffer is unlimited and all
2717 incoming data is buffered. This is the default.
2718
2719 This option is useful if you only read the data at certain points
2720 in time (e.g., in a real-time streaming application) or if you
2721 want to protect your socket against receiving too much data,
2722 which may eventually cause your application to run out of memory.
2723
2724 Only QTcpSocket uses QAbstractSocket's internal buffer; QUdpSocket
2725 does not use any buffering at all, but rather relies on the
2726 implicit buffering provided by the operating system.
2727 Because of this, calling this function on QUdpSocket has no
2728 effect.
2729
2730 \sa readBufferSize(), read()
2731*/
2732void QAbstractSocket::setReadBufferSize(qint64 size)
2733{
2734 Q_D(QAbstractSocket);
2735
2736 if (d->readBufferMaxSize == size)
2737 return;
2738 d->readBufferMaxSize = size;
2739
2740 // Do not change the notifier unless we are connected.
2741 if (d->socketEngine && d->state == QAbstractSocket::ConnectedState) {
2742 // Ensure that the read notification is enabled if we've now got
2743 // room in the read buffer.
2744 d->socketEngine->setReadNotificationEnabled(size == 0 || d->buffer.size() < size);
2745 }
2746}
2747
2748/*!
2749 Returns the state of the socket.
2750
2751 \sa error()
2752*/
2753QAbstractSocket::SocketState QAbstractSocket::state() const
2754{
2755 return d_func()->state;
2756}
2757
2758/*!
2759 Sets the state of the socket to \a state.
2760
2761 \sa state()
2762*/
2763void QAbstractSocket::setSocketState(SocketState state)
2764{
2765 d_func()->state = state;
2766}
2767
2768/*!
2769 Returns the socket type (TCP, UDP, or other).
2770
2771 \sa QTcpSocket, QUdpSocket
2772*/
2773QAbstractSocket::SocketType QAbstractSocket::socketType() const
2774{
2775 return d_func()->socketType;
2776}
2777
2778/*!
2779 Returns the type of error that last occurred.
2780
2781 \sa state(), errorString()
2782*/
2783QAbstractSocket::SocketError QAbstractSocket::error() const
2784{
2785 return d_func()->socketError;
2786}
2787
2788/*!
2789 Sets the type of error that last occurred to \a socketError.
2790
2791 \sa setSocketState(), setErrorString()
2792*/
2793void QAbstractSocket::setSocketError(SocketError socketError)
2794{
2795 d_func()->socketError = socketError;
2796}
2797
2798#ifndef QT_NO_NETWORKPROXY
2799/*!
2800 \since 4.1
2801
2802 Sets the explicit network proxy for this socket to \a networkProxy.
2803
2804 To disable the use of a proxy for this socket, use the
2805 QNetworkProxy::NoProxy proxy type:
2806
2807 \snippet code/src_network_socket_qabstractsocket.cpp 2
2808
2809 The default value for the proxy is QNetworkProxy::DefaultProxy,
2810 which means the socket will use the application settings: if a
2811 proxy is set with QNetworkProxy::setApplicationProxy, it will use
2812 that; otherwise, if a factory is set with
2813 QNetworkProxyFactory::setApplicationProxyFactory, it will query
2814 that factory with type QNetworkProxyQuery::TcpSocket.
2815
2816 \sa proxy(), QNetworkProxy, QNetworkProxyFactory::queryProxy()
2817*/
2818void QAbstractSocket::setProxy(const QNetworkProxy &networkProxy)
2819{
2820 Q_D(QAbstractSocket);
2821 d->proxy = networkProxy;
2822}
2823
2824/*!
2825 \since 4.1
2826
2827 Returns the network proxy for this socket.
2828 By default QNetworkProxy::DefaultProxy is used, which means this
2829 socket will query the default proxy settings for the application.
2830
2831 \sa setProxy(), QNetworkProxy, QNetworkProxyFactory
2832*/
2833QNetworkProxy QAbstractSocket::proxy() const
2834{
2835 Q_D(const QAbstractSocket);
2836 return d->proxy;
2837}
2838
2839/*!
2840 \since 5.13
2841
2842 Returns the protocol tag for this socket.
2843 If the protocol tag is set then this is passed to QNetworkProxyQuery
2844 when this is created internally to indicate the protocol tag to be
2845 used.
2846
2847 \sa setProtocolTag(), QNetworkProxyQuery
2848*/
2849
2850QString QAbstractSocket::protocolTag() const
2851{
2852 Q_D(const QAbstractSocket);
2853 return d->protocolTag;
2854}
2855
2856/*!
2857 \since 5.13
2858
2859 Sets the protocol tag for this socket to \a tag.
2860
2861 \sa protocolTag()
2862*/
2863
2864void QAbstractSocket::setProtocolTag(const QString &tag)
2865{
2866 Q_D(QAbstractSocket);
2867 d->protocolTag = tag;
2868}
2869
2870#endif // QT_NO_NETWORKPROXY
2871
2872#ifndef QT_NO_DEBUG_STREAM
2873Q_NETWORK_EXPORT QDebug operator<<(QDebug debug, QAbstractSocket::SocketError error)
2874{
2875 QDebugStateSaver saver(debug);
2876 debug.resetFormat().nospace();
2877 switch (error) {
2878 case QAbstractSocket::ConnectionRefusedError:
2879 debug << "QAbstractSocket::ConnectionRefusedError";
2880 break;
2881 case QAbstractSocket::RemoteHostClosedError:
2882 debug << "QAbstractSocket::RemoteHostClosedError";
2883 break;
2884 case QAbstractSocket::HostNotFoundError:
2885 debug << "QAbstractSocket::HostNotFoundError";
2886 break;
2887 case QAbstractSocket::SocketAccessError:
2888 debug << "QAbstractSocket::SocketAccessError";
2889 break;
2890 case QAbstractSocket::SocketResourceError:
2891 debug << "QAbstractSocket::SocketResourceError";
2892 break;
2893 case QAbstractSocket::SocketTimeoutError:
2894 debug << "QAbstractSocket::SocketTimeoutError";
2895 break;
2896 case QAbstractSocket::DatagramTooLargeError:
2897 debug << "QAbstractSocket::DatagramTooLargeError";
2898 break;
2899 case QAbstractSocket::NetworkError:
2900 debug << "QAbstractSocket::NetworkError";
2901 break;
2902 case QAbstractSocket::AddressInUseError:
2903 debug << "QAbstractSocket::AddressInUseError";
2904 break;
2905 case QAbstractSocket::SocketAddressNotAvailableError:
2906 debug << "QAbstractSocket::SocketAddressNotAvailableError";
2907 break;
2908 case QAbstractSocket::UnsupportedSocketOperationError:
2909 debug << "QAbstractSocket::UnsupportedSocketOperationError";
2910 break;
2911 case QAbstractSocket::UnfinishedSocketOperationError:
2912 debug << "QAbstractSocket::UnfinishedSocketOperationError";
2913 break;
2914 case QAbstractSocket::ProxyAuthenticationRequiredError:
2915 debug << "QAbstractSocket::ProxyAuthenticationRequiredError";
2916 break;
2917 case QAbstractSocket::UnknownSocketError:
2918 debug << "QAbstractSocket::UnknownSocketError";
2919 break;
2920 case QAbstractSocket::ProxyConnectionRefusedError:
2921 debug << "QAbstractSocket::ProxyConnectionRefusedError";
2922 break;
2923 case QAbstractSocket::ProxyConnectionClosedError:
2924 debug << "QAbstractSocket::ProxyConnectionClosedError";
2925 break;
2926 case QAbstractSocket::ProxyConnectionTimeoutError:
2927 debug << "QAbstractSocket::ProxyConnectionTimeoutError";
2928 break;
2929 case QAbstractSocket::ProxyNotFoundError:
2930 debug << "QAbstractSocket::ProxyNotFoundError";
2931 break;
2932 case QAbstractSocket::ProxyProtocolError:
2933 debug << "QAbstractSocket::ProxyProtocolError";
2934 break;
2935 default:
2936 debug << "QAbstractSocket::SocketError(" << int(error) << ')';
2937 break;
2938 }
2939 return debug;
2940}
2941
2942Q_NETWORK_EXPORT QDebug operator<<(QDebug debug, QAbstractSocket::SocketState state)
2943{
2944 QDebugStateSaver saver(debug);
2945 debug.resetFormat().nospace();
2946 switch (state) {
2947 case QAbstractSocket::UnconnectedState:
2948 debug << "QAbstractSocket::UnconnectedState";
2949 break;
2950 case QAbstractSocket::HostLookupState:
2951 debug << "QAbstractSocket::HostLookupState";
2952 break;
2953 case QAbstractSocket::ConnectingState:
2954 debug << "QAbstractSocket::ConnectingState";
2955 break;
2956 case QAbstractSocket::ConnectedState:
2957 debug << "QAbstractSocket::ConnectedState";
2958 break;
2959 case QAbstractSocket::BoundState:
2960 debug << "QAbstractSocket::BoundState";
2961 break;
2962 case QAbstractSocket::ListeningState:
2963 debug << "QAbstractSocket::ListeningState";
2964 break;
2965 case QAbstractSocket::ClosingState:
2966 debug << "QAbstractSocket::ClosingState";
2967 break;
2968 default:
2969 debug << "QAbstractSocket::SocketState(" << int(state) << ')';
2970 break;
2971 }
2972 return debug;
2973}
2974#endif
2975
2976QT_END_NAMESPACE
2977
2978#include "moc_qabstractsocket.cpp"
2979

source code of qtbase/src/network/socket/qabstractsocket.cpp