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

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