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

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

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