source: trunk/src/network/socket/qnativesocketengine.cpp

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 42.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the QtNetwork module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at qt-info@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42//#define QNATIVESOCKETENGINE_DEBUG
43
44/*! \class QNativeSocketEngine
45 \internal
46
47 \brief The QNativeSocketEngine class provides low level access to a socket.
48
49 \reentrant
50 \ingroup network
51 \inmodule QtNetwork
52
53 QtSocketLayer provides basic socket functionality provided by the
54 operating system. It also keeps track of what state the socket is
55 in, and which errors that occur.
56
57 The classes QTcpSocket, QUdpSocket and QTcpServer provide a
58 higher level API, and are in general more useful for the common
59 application.
60
61 There are two main ways of initializing the a QNativeSocketEngine; either
62 create a new socket by passing the socket type (TcpSocket or
63 UdpSocket) and network layer protocol (IPv4Protocol or
64 IPv6Protocol) to initialize(), or pass an existing socket
65 descriptor and have QNativeSocketEngine determine the type and protocol
66 itself. The native socket descriptor can later be fetched by
67 calling socketDescriptor(). The socket is made non-blocking, but
68 blocking behavior can still be achieved by calling waitForRead()
69 and waitForWrite(). isValid() can be called to check if the socket
70 has been successfully initialized and is ready to use.
71
72 To connect to a host, determine its address and pass this and the
73 port number to connectToHost(). The socket can then be used as a
74 TCP or UDP client. Otherwise; bind(), listen() and accept() are
75 used to have the socket function as a TCP or UDP server. Call
76 close() to close the socket.
77
78 bytesAvailable() is called to determine how much data is available
79 for reading. read() and write() are used by both TCP and UDP
80 clients to exchange data with the connected peer. UDP clients can
81 also call hasMoreDatagrams(), nextDatagramSize(),
82 readDatagram(), and writeDatagram().
83
84 Call state() to determine the state of the socket, for
85 example, ListeningState or ConnectedState. socketType() tells
86 whether the socket is a TCP socket or a UDP socket, or if the
87 socket type is unknown. protocol() is used to determine the
88 socket's network layer protocol.
89
90 localAddress(), localPort() are called to find the address and
91 port that are currently bound to the socket. If the socket is
92 connected, peerAddress() and peerPort() determine the address and
93 port of the connected peer.
94
95 Finally, if any function should fail, error() and
96 errorString() can be called to determine the cause of the error.
97*/
98
99#include <qabstracteventdispatcher.h>
100#include <qsocketnotifier.h>
101
102#include "qnativesocketengine_p.h"
103#include <private/qthread_p.h>
104#include <private/qobject_p.h>
105
106#if !defined(QT_NO_NETWORKPROXY)
107# include "qnetworkproxy.h"
108# include "qabstractsocket.h"
109# include "qtcpserver.h"
110#endif
111
112QT_BEGIN_NAMESPACE
113
114//#define QNATIVESOCKETENGINE_DEBUG
115
116#define Q_VOID
117
118// Common constructs
119#define Q_CHECK_VALID_SOCKETLAYER(function, returnValue) do { \
120 if (!isValid()) { \
121 qWarning(""#function" was called on an uninitialized socket device"); \
122 return returnValue; \
123 } } while (0)
124#define Q_CHECK_INVALID_SOCKETLAYER(function, returnValue) do { \
125 if (isValid()) { \
126 qWarning(""#function" was called on an already initialized socket device"); \
127 return returnValue; \
128 } } while (0)
129#define Q_CHECK_STATE(function, checkState, returnValue) do { \
130 if (d->socketState != (checkState)) { \
131 qWarning(""#function" was not called in "#checkState); \
132 return (returnValue); \
133 } } while (0)
134#define Q_CHECK_NOT_STATE(function, checkState, returnValue) do { \
135 if (d->socketState == (checkState)) { \
136 qWarning(""#function" was called in "#checkState); \
137 return (returnValue); \
138 } } while (0)
139#define Q_CHECK_STATES(function, state1, state2, returnValue) do { \
140 if (d->socketState != (state1) && d->socketState != (state2)) { \
141 qWarning(""#function" was called" \
142 " not in "#state1" or "#state2); \
143 return (returnValue); \
144 } } while (0)
145#define Q_CHECK_TYPE(function, type, returnValue) do { \
146 if (d->socketType != (type)) { \
147 qWarning(#function" was called by a" \
148 " socket other than "#type""); \
149 return (returnValue); \
150 } } while (0)
151#define Q_TR(a) QT_TRANSLATE_NOOP(QNativeSocketEngine, a)
152
153/*! \internal
154 Constructs the private class and initializes all data members.
155
156 On Windows, WSAStartup is called "recursively" for every
157 concurrent QNativeSocketEngine. This is safe, because WSAStartup and
158 WSACleanup are reference counted.
159*/
160QNativeSocketEnginePrivate::QNativeSocketEnginePrivate()
161{
162 socketDescriptor = -1;
163 readNotifier = 0;
164 writeNotifier = 0;
165 exceptNotifier = 0;
166}
167
168/*! \internal
169 Destructs the private class.
170*/
171QNativeSocketEnginePrivate::~QNativeSocketEnginePrivate()
172{
173}
174
175/*! \internal
176
177 Sets the error and error string if not set already. The only
178 interesting error is the first one that occurred, and not the last
179 one.
180*/
181void QNativeSocketEnginePrivate::setError(QAbstractSocket::SocketError error, ErrorString errorString) const
182{
183 if (hasSetSocketError) {
184 // Only set socket errors once for one engine; expect the
185 // socket to recreate its engine after an error. Note: There's
186 // one exception: SocketError(11) bypasses this as it's purely
187 // a temporary internal error condition.
188 // Another exception is the way the waitFor*() functions set
189 // an error when a timeout occurs. After the call to setError()
190 // they reset the hasSetSocketError to false
191 return;
192 }
193 if (error != QAbstractSocket::SocketError(11))
194 hasSetSocketError = true;
195
196 socketError = error;
197
198 switch (errorString) {
199 case NonBlockingInitFailedErrorString:
200 socketErrorString = QNativeSocketEngine::tr("Unable to initialize non-blocking socket");
201 break;
202 case BroadcastingInitFailedErrorString:
203 socketErrorString = QNativeSocketEngine::tr("Unable to initialize broadcast socket");
204 break;
205 case NoIpV6ErrorString:
206 socketErrorString = QNativeSocketEngine::tr("Attempt to use IPv6 socket on a platform with no IPv6 support");
207 break;
208 case RemoteHostClosedErrorString:
209 socketErrorString = QNativeSocketEngine::tr("The remote host closed the connection");
210 break;
211 case TimeOutErrorString:
212 socketErrorString = QNativeSocketEngine::tr("Network operation timed out");
213 break;
214 case ResourceErrorString:
215 socketErrorString = QNativeSocketEngine::tr("Out of resources");
216 break;
217 case OperationUnsupportedErrorString:
218 socketErrorString = QNativeSocketEngine::tr("Unsupported socket operation");
219 break;
220 case ProtocolUnsupportedErrorString:
221 socketErrorString = QNativeSocketEngine::tr("Protocol type not supported");
222 break;
223 case InvalidSocketErrorString:
224 socketErrorString = QNativeSocketEngine::tr("Invalid socket descriptor");
225 break;
226 case HostUnreachableErrorString:
227 socketErrorString = QNativeSocketEngine::tr("Host unreachable");
228 break;
229 case NetworkUnreachableErrorString:
230 socketErrorString = QNativeSocketEngine::tr("Network unreachable");
231 break;
232 case AccessErrorString:
233 socketErrorString = QNativeSocketEngine::tr("Permission denied");
234 break;
235 case ConnectionTimeOutErrorString:
236 socketErrorString = QNativeSocketEngine::tr("Connection timed out");
237 break;
238 case ConnectionRefusedErrorString:
239 socketErrorString = QNativeSocketEngine::tr("Connection refused");
240 break;
241 case AddressInuseErrorString:
242 socketErrorString = QNativeSocketEngine::tr("The bound address is already in use");
243 break;
244 case AddressNotAvailableErrorString:
245 socketErrorString = QNativeSocketEngine::tr("The address is not available");
246 break;
247 case AddressProtectedErrorString:
248 socketErrorString = QNativeSocketEngine::tr("The address is protected");
249 break;
250 case DatagramTooLargeErrorString:
251 socketErrorString = QNativeSocketEngine::tr("Datagram was too large to send");
252 break;
253 case SendDatagramErrorString:
254 socketErrorString = QNativeSocketEngine::tr("Unable to send a message");
255 break;
256 case ReceiveDatagramErrorString:
257 socketErrorString = QNativeSocketEngine::tr("Unable to receive a message");
258 break;
259 case WriteErrorString:
260 socketErrorString = QNativeSocketEngine::tr("Unable to write");
261 break;
262 case ReadErrorString:
263 socketErrorString = QNativeSocketEngine::tr("Network error");
264 break;
265 case PortInuseErrorString:
266 socketErrorString = QNativeSocketEngine::tr("Another socket is already listening on the same port");
267 break;
268 case NotSocketErrorString:
269 socketErrorString = QNativeSocketEngine::tr("Operation on non-socket");
270 break;
271 case InvalidProxyTypeString:
272 socketErrorString = QNativeSocketEngine::tr("The proxy type is invalid for this operation");
273 break;
274 case UnknownSocketErrorString:
275 socketErrorString = QNativeSocketEngine::tr("Unknown error");
276 break;
277 }
278}
279
280bool QNativeSocketEnginePrivate::checkProxy(const QHostAddress &address)
281{
282 if (address == QHostAddress::LocalHost || address == QHostAddress::LocalHostIPv6)
283 return true;
284
285#if !defined(QT_NO_NETWORKPROXY)
286 QObject *parent = q_func()->parent();
287 QNetworkProxy proxy;
288 if (QAbstractSocket *socket = qobject_cast<QAbstractSocket *>(parent)) {
289 proxy = socket->proxy();
290 } else if (QTcpServer *server = qobject_cast<QTcpServer *>(parent)) {
291 proxy = server->proxy();
292 } else {
293 // no parent -> no proxy
294 return true;
295 }
296
297 if (proxy.type() == QNetworkProxy::DefaultProxy)
298 proxy = QNetworkProxy::applicationProxy();
299
300 if (proxy.type() != QNetworkProxy::DefaultProxy &&
301 proxy.type() != QNetworkProxy::NoProxy) {
302 // QNativeSocketEngine doesn't do proxies
303 setError(QAbstractSocket::UnsupportedSocketOperationError,
304 QNativeSocketEnginePrivate::InvalidProxyTypeString);
305 return false;
306 }
307#endif
308
309 return true;
310}
311
312/*!
313 Constructs a QNativeSocketEngine.
314
315 \sa initialize()
316*/
317QNativeSocketEngine::QNativeSocketEngine(QObject *parent)
318 : QAbstractSocketEngine(*new QNativeSocketEnginePrivate(), parent)
319{
320}
321
322/*!
323 Destructs a QNativeSocketEngine.
324*/
325QNativeSocketEngine::~QNativeSocketEngine()
326{
327 close();
328}
329
330/*!
331 Initializes a QNativeSocketEngine by creating a new socket of type \a
332 socketType and network layer protocol \a protocol. Returns true on
333 success; otherwise returns false.
334
335 If the socket was already initialized, this function closes the
336 socket before reeinitializing it.
337
338 The new socket is non-blocking, and for UDP sockets it's also
339 broadcast enabled.
340*/
341bool QNativeSocketEngine::initialize(QAbstractSocket::SocketType socketType, QAbstractSocket::NetworkLayerProtocol protocol)
342{
343 Q_D(QNativeSocketEngine);
344 if (isValid())
345 close();
346
347#if defined(QT_NO_IPV6)
348 if (protocol == QAbstractSocket::IPv6Protocol) {
349 d->setError(QAbstractSocket::UnsupportedSocketOperationError,
350 QNativeSocketEnginePrivate::NoIpV6ErrorString);
351 return false;
352 }
353#endif
354
355 // Create the socket
356 if (!d->createNewSocket(socketType, protocol)) {
357#if defined (QNATIVESOCKETENGINE_DEBUG)
358 QString typeStr = QLatin1String("UnknownSocketType");
359 if (socketType == QAbstractSocket::TcpSocket) typeStr = QLatin1String("TcpSocket");
360 else if (socketType == QAbstractSocket::UdpSocket) typeStr = QLatin1String("UdpSocket");
361 QString protocolStr = QLatin1String("UnknownProtocol");
362 if (protocol == QAbstractSocket::IPv4Protocol) protocolStr = QLatin1String("IPv4Protocol");
363 else if (protocol == QAbstractSocket::IPv6Protocol) protocolStr = QLatin1String("IPv6Protocol");
364 qDebug("QNativeSocketEngine::initialize(type == %s, protocol == %s) failed: %s",
365 typeStr.toLatin1().constData(), protocolStr.toLatin1().constData(), d->socketErrorString.toLatin1().constData());
366#endif
367 return false;
368 }
369
370 // Make the socket nonblocking.
371 if (!setOption(NonBlockingSocketOption, 1)) {
372 d->setError(QAbstractSocket::UnsupportedSocketOperationError,
373 QNativeSocketEnginePrivate::NonBlockingInitFailedErrorString);
374 close();
375 return false;
376 }
377
378 // Set the broadcasting flag if it's a UDP socket.
379 if (socketType == QAbstractSocket::UdpSocket
380 && !setOption(BroadcastSocketOption, 1)) {
381 d->setError(QAbstractSocket::UnsupportedSocketOperationError,
382 QNativeSocketEnginePrivate::BroadcastingInitFailedErrorString);
383 close();
384 return false;
385 }
386
387
388 // Make sure we receive out-of-band data
389 // On Symbian OS this works only with native IP stack, not with WinSock
390 if (socketType == QAbstractSocket::TcpSocket
391 && !setOption(ReceiveOutOfBandData, 1)) {
392 qWarning("QNativeSocketEngine::initialize unable to inline out-of-band data");
393 }
394
395 // Before Qt 4.6, we always set the send and receive buffer size to 49152 as
396 // this was found to be an optimal value. However, modern OS
397 // all have some kind of auto tuning for this and we therefore don't set
398 // this explictly anymore.
399 // If it introduces any performance regressions for Qt 4.6.x (x > 0) then
400 // it will be put back in.
401 //
402 // You can use tests/manual/qhttpnetworkconnection to test HTTP download speed
403 // with this.
404 //
405 // pre-4.6:
406 // setReceiveBufferSize(49152);
407 // setSendBufferSize(49152);
408
409 d->socketType = socketType;
410 d->socketProtocol = protocol;
411 return true;
412}
413
414/*! \overload
415
416 Initializes the socket using \a socketDescriptor instead of
417 creating a new one. The socket type and network layer protocol are
418 determined automatically. The socket's state is set to \a
419 socketState.
420
421 If the socket type is either TCP or UDP, it is made non-blocking.
422 UDP sockets are also broadcast enabled.
423 */
424bool QNativeSocketEngine::initialize(int socketDescriptor, QAbstractSocket::SocketState socketState)
425{
426 Q_D(QNativeSocketEngine);
427
428 if (isValid())
429 close();
430
431 d->socketDescriptor = socketDescriptor;
432
433 // determine socket type and protocol
434 if (!d->fetchConnectionParameters()) {
435#if defined (QNATIVESOCKETENGINE_DEBUG)
436 qDebug("QNativeSocketEngine::initialize(socketDescriptor == %i) failed: %s",
437 socketDescriptor, d->socketErrorString.toLatin1().constData());
438#endif
439 d->socketDescriptor = -1;
440 return false;
441 }
442
443 if (d->socketType != QAbstractSocket::UnknownSocketType) {
444 // Make the socket nonblocking.
445 if (!setOption(NonBlockingSocketOption, 1)) {
446 d->setError(QAbstractSocket::UnsupportedSocketOperationError,
447 QNativeSocketEnginePrivate::NonBlockingInitFailedErrorString);
448 close();
449 return false;
450 }
451
452 // Set the broadcasting flag if it's a UDP socket.
453 if (d->socketType == QAbstractSocket::UdpSocket
454 && !setOption(BroadcastSocketOption, 1)) {
455 d->setError(QAbstractSocket::UnsupportedSocketOperationError,
456 QNativeSocketEnginePrivate::BroadcastingInitFailedErrorString);
457 close();
458 return false;
459 }
460 }
461
462 d->socketState = socketState;
463 return true;
464}
465
466/*!
467 Returns true if the socket is valid; otherwise returns false. A
468 socket is valid if it has not been successfully initialized, or if
469 it has been closed.
470*/
471bool QNativeSocketEngine::isValid() const
472{
473 Q_D(const QNativeSocketEngine);
474 return d->socketDescriptor != -1;
475}
476
477/*!
478 Returns the native socket descriptor. Any use of this descriptor
479 stands the risk of being non-portable.
480*/
481int QNativeSocketEngine::socketDescriptor() const
482{
483 Q_D(const QNativeSocketEngine);
484 return d->socketDescriptor;
485}
486
487/*!
488 Connects to the IP address and port specified by \a address and \a
489 port. If the connection is established, this function returns true
490 and the socket enters ConnectedState. Otherwise, false is
491 returned.
492
493 If false is returned, state() should be called to see if the
494 socket is in ConnectingState. If so, a delayed TCP connection is
495 taking place, and connectToHost() must be called again later to
496 determine if the connection was established successfully or
497 not. The second connection attempt must be made when the socket is
498 ready for writing. This state can be determined either by
499 connecting a QSocketNotifier to the socket descriptor returned by
500 socketDescriptor(), or by calling the blocking function
501 waitForWrite().
502
503 Example:
504 \snippet doc/src/snippets/code/src_network_socket_qnativesocketengine.cpp 0
505
506 Otherwise, error() should be called to determine the cause of the
507 error.
508*/
509bool QNativeSocketEngine::connectToHost(const QHostAddress &address, quint16 port)
510{
511 Q_D(QNativeSocketEngine);
512 Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::connectToHost(), false);
513
514#if defined (QT_NO_IPV6)
515 if (address.protocol() == QAbstractSocket::IPv6Protocol) {
516 d->setError(QAbstractSocket::UnsupportedSocketOperationError,
517 QNativeSocketEnginePrivate::NoIpV6ErrorString);
518 return false;
519 }
520#endif
521 if (!d->checkProxy(address))
522 return false;
523
524 Q_CHECK_STATES(QNativeSocketEngine::connectToHost(),
525 QAbstractSocket::UnconnectedState, QAbstractSocket::ConnectingState, false);
526
527 d->peerAddress = address;
528 d->peerPort = port;
529 bool connected = d->nativeConnect(address, port);
530 if (connected)
531 d->fetchConnectionParameters();
532
533 return connected;
534}
535
536/*!
537 If there's a connection activity on the socket, process it. Then
538 notify our parent if there really was activity.
539*/
540void QNativeSocketEngine::connectionNotification()
541{
542 Q_D(QNativeSocketEngine);
543 Q_ASSERT(state() == QAbstractSocket::ConnectingState);
544
545 connectToHost(d->peerAddress, d->peerPort);
546 if (state() != QAbstractSocket::ConnectingState) {
547 // we changed states
548 QAbstractSocketEngine::connectionNotification();
549 }
550}
551
552/*!
553 Connects to the remote host name given by \a name on port \a
554 port. When this function is called, the upper-level will not
555 perform a hostname lookup.
556
557 The native socket engine does not support this operation,
558 but some other socket engines (notably proxy-based ones) do.
559*/
560bool QNativeSocketEngine::connectToHostByName(const QString &name, quint16 port)
561{
562 Q_UNUSED(name);
563 Q_UNUSED(port);
564 Q_D(QNativeSocketEngine);
565 d->setError(QAbstractSocket::UnsupportedSocketOperationError,
566 QNativeSocketEnginePrivate::OperationUnsupportedErrorString);
567 return false;
568}
569
570/*!
571 Binds the socket to the address \a address and port \a
572 port. Returns true on success; otherwise false is returned. The
573 port may be 0, in which case an arbitrary unused port is assigned
574 automatically by the operating system.
575
576 Servers call this function to set up the server's address and
577 port. TCP servers must in addition call listen() after bind().
578*/
579bool QNativeSocketEngine::bind(const QHostAddress &address, quint16 port)
580{
581 Q_D(QNativeSocketEngine);
582 Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::bind(), false);
583
584#if defined (QT_NO_IPV6)
585 if (address.protocol() == QAbstractSocket::IPv6Protocol) {
586 d->setError(QAbstractSocket::UnsupportedSocketOperationError,
587 QNativeSocketEnginePrivate::NoIpV6ErrorString);
588 return false;
589 }
590#endif
591 if (!d->checkProxy(address))
592 return false;
593
594 Q_CHECK_STATE(QNativeSocketEngine::bind(), QAbstractSocket::UnconnectedState, false);
595
596 if (!d->nativeBind(address, port))
597 return false;
598
599 d->fetchConnectionParameters();
600 return true;
601}
602
603/*!
604 Prepares a TCP server for accepting incoming connections. This
605 function must be called after bind(), and only by TCP sockets.
606
607 After this function has been called, pending client connections
608 are detected by checking if the socket is ready for reading. This
609 can be done by either creating a QSocketNotifier, passing the
610 socket descriptor returned by socketDescriptor(), or by calling
611 the blocking function waitForRead().
612
613 Example:
614 \snippet doc/src/snippets/code/src_network_socket_qnativesocketengine.cpp 1
615
616 \sa bind(), accept()
617*/
618bool QNativeSocketEngine::listen()
619{
620 Q_D(QNativeSocketEngine);
621 Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::listen(), false);
622 Q_CHECK_STATE(QNativeSocketEngine::listen(), QAbstractSocket::BoundState, false);
623 Q_CHECK_TYPE(QNativeSocketEngine::listen(), QAbstractSocket::TcpSocket, false);
624
625 // We're using a backlog of 50. Most modern kernels support TCP
626 // syncookies by default, and if they do, the backlog is ignored.
627 // When there is no support for TCP syncookies, this value is
628 // fine.
629 return d->nativeListen(50);
630}
631
632/*!
633 Accepts a pending connection from the socket, which must be in
634 ListeningState, and returns its socket descriptor. If no pending
635 connections are available, -1 is returned.
636
637 \sa bind(), listen()
638*/
639int QNativeSocketEngine::accept()
640{
641 Q_D(QNativeSocketEngine);
642 Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::accept(), -1);
643 Q_CHECK_STATE(QNativeSocketEngine::accept(), QAbstractSocket::ListeningState, false);
644 Q_CHECK_TYPE(QNativeSocketEngine::accept(), QAbstractSocket::TcpSocket, false);
645
646 return d->nativeAccept();
647}
648
649/*!
650 Returns the number of bytes that are currently available for
651 reading. On error, -1 is returned.
652
653 For UDP sockets, this function returns the accumulated size of all
654 pending datagrams, and it is therefore more useful for UDP sockets
655 to call hasPendingDatagrams() and pendingDatagramSize().
656*/
657qint64 QNativeSocketEngine::bytesAvailable() const
658{
659 Q_D(const QNativeSocketEngine);
660 Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::bytesAvailable(), -1);
661 Q_CHECK_NOT_STATE(QNativeSocketEngine::bytesAvailable(), QAbstractSocket::UnconnectedState, false);
662
663 return d->nativeBytesAvailable();
664}
665
666/*!
667 Returns true if there is at least one datagram pending. This
668 function is only called by UDP sockets, where a datagram can have
669 a size of 0. TCP sockets call bytesAvailable().
670*/
671bool QNativeSocketEngine::hasPendingDatagrams() const
672{
673 Q_D(const QNativeSocketEngine);
674 Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::hasPendingDatagrams(), false);
675 Q_CHECK_NOT_STATE(QNativeSocketEngine::hasPendingDatagrams(), QAbstractSocket::UnconnectedState, false);
676 Q_CHECK_TYPE(QNativeSocketEngine::hasPendingDatagrams(), QAbstractSocket::UdpSocket, false);
677
678 return d->nativeHasPendingDatagrams();
679}
680
681/*!
682 Returns the size of the pending datagram, or -1 if no datagram is
683 pending. A datagram size of 0 is perfectly valid. This function is
684 called by UDP sockets before receiveMessage(). For TCP sockets,
685 call bytesAvailable().
686*/
687qint64 QNativeSocketEngine::pendingDatagramSize() const
688{
689 Q_D(const QNativeSocketEngine);
690 Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::pendingDatagramSize(), -1);
691 Q_CHECK_TYPE(QNativeSocketEngine::pendingDatagramSize(), QAbstractSocket::UdpSocket, false);
692
693 return d->nativePendingDatagramSize();
694}
695
696/*!
697 Reads up to \a maxSize bytes of a datagram from the socket,
698 stores it in \a data and returns the number of bytes read. The
699 address and port of the sender are stored in \a address and \a
700 port. If either of these pointers is 0, the corresponding value is
701 discarded.
702
703 To avoid unnecessarily loss of data, call pendingDatagramSize() to
704 determine the size of the pending message before reading it. If \a
705 maxSize is too small, the rest of the datagram will be lost.
706
707 Returns -1 if an error occurred.
708
709 \sa hasPendingDatagrams()
710*/
711qint64 QNativeSocketEngine::readDatagram(char *data, qint64 maxSize, QHostAddress *address,
712 quint16 *port)
713{
714 Q_D(QNativeSocketEngine);
715 Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::readDatagram(), -1);
716 Q_CHECK_TYPE(QNativeSocketEngine::readDatagram(), QAbstractSocket::UdpSocket, false);
717
718 return d->nativeReceiveDatagram(data, maxSize, address, port);
719}
720
721/*!
722 Writes a UDP datagram of size \a size bytes to the socket from
723 \a data to the address \a host on port \a port, and returns the
724 number of bytes written, or -1 if an error occurred.
725
726 Only one datagram is sent, and if there is too much data to fit
727 into a single datagram, the operation will fail and error()
728 will return QAbstractSocket::DatagramTooLargeError. Operating systems impose an
729 upper limit to the size of a datagram, but this size is different
730 on almost all platforms. Sending large datagrams is in general
731 disadvised, as even if they are sent successfully, they are likely
732 to be fragmented before arriving at their destination.
733
734 Experience has shown that it is in general safe to send datagrams
735 no larger than 512 bytes.
736
737 \sa readDatagram()
738*/
739qint64 QNativeSocketEngine::writeDatagram(const char *data, qint64 size,
740 const QHostAddress &host, quint16 port)
741{
742 Q_D(QNativeSocketEngine);
743 Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::writeDatagram(), -1);
744 Q_CHECK_TYPE(QNativeSocketEngine::writeDatagram(), QAbstractSocket::UdpSocket, -1);
745 return d->nativeSendDatagram(data, size, host, port);
746}
747
748/*!
749 Writes a block of \a size bytes from \a data to the socket.
750 Returns the number of bytes written, or -1 if an error occurred.
751*/
752qint64 QNativeSocketEngine::write(const char *data, qint64 size)
753{
754 Q_D(QNativeSocketEngine);
755 Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::write(), -1);
756 Q_CHECK_STATE(QNativeSocketEngine::write(), QAbstractSocket::ConnectedState, -1);
757 return d->nativeWrite(data, size);
758}
759
760
761qint64 QNativeSocketEngine::bytesToWrite() const
762{
763 return 0;
764}
765
766/*!
767 Reads up to \a maxSize bytes into \a data from the socket.
768 Returns the number of bytes read, or -1 if an error occurred.
769*/
770qint64 QNativeSocketEngine::read(char *data, qint64 maxSize)
771{
772 Q_D(QNativeSocketEngine);
773 Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::read(), -1);
774 Q_CHECK_STATES(QNativeSocketEngine::read(), QAbstractSocket::ConnectedState, QAbstractSocket::BoundState, -1);
775
776 qint64 readBytes = d->nativeRead(data, maxSize);
777
778 // Handle remote close
779 if (readBytes == 0 && d->socketType == QAbstractSocket::TcpSocket) {
780 d->setError(QAbstractSocket::RemoteHostClosedError,
781 QNativeSocketEnginePrivate::RemoteHostClosedErrorString);
782 close();
783 return -1;
784 } else if (readBytes == -1) {
785 if (!d->hasSetSocketError) {
786 d->hasSetSocketError = true;
787 d->socketError = QAbstractSocket::NetworkError;
788 d->socketErrorString = qt_error_string();
789 }
790 close();
791 return -1;
792 }
793 return readBytes;
794}
795
796/*!
797 Closes the socket. In order to use the socket again, initialize()
798 must be called.
799*/
800void QNativeSocketEngine::close()
801{
802 Q_D(QNativeSocketEngine);
803 if (d->readNotifier)
804 d->readNotifier->setEnabled(false);
805 if (d->writeNotifier)
806 d->writeNotifier->setEnabled(false);
807 if (d->exceptNotifier)
808 d->exceptNotifier->setEnabled(false);
809
810 if(d->socketDescriptor != -1) {
811 d->nativeClose();
812 d->socketDescriptor = -1;
813 }
814 d->socketState = QAbstractSocket::UnconnectedState;
815 d->hasSetSocketError = false;
816 d->localPort = 0;
817 d->localAddress.clear();
818 d->peerPort = 0;
819 d->peerAddress.clear();
820 if (d->readNotifier) {
821 qDeleteInEventHandler(d->readNotifier);
822 d->readNotifier = 0;
823 }
824 if (d->writeNotifier) {
825 qDeleteInEventHandler(d->writeNotifier);
826 d->writeNotifier = 0;
827 }
828 if (d->exceptNotifier) {
829 qDeleteInEventHandler(d->exceptNotifier);
830 d->exceptNotifier = 0;
831 }
832}
833
834/*!
835 Waits for \a msecs milliseconds or until the socket is ready for
836 reading. If \a timedOut is not 0 and \a msecs milliseconds have
837 passed, the value of \a timedOut is set to true.
838
839 Returns true if data is available for reading; otherwise returns
840 false.
841
842 This is a blocking function call; its use is disadvised in a
843 single threaded application, as the whole thread will stop
844 responding until the function returns. waitForRead() is most
845 useful when there is no event loop available. The general approach
846 is to create a QSocketNotifier, passing the socket descriptor
847 returned by socketDescriptor() to its constructor.
848*/
849bool QNativeSocketEngine::waitForRead(int msecs, bool *timedOut)
850{
851 Q_D(const QNativeSocketEngine);
852 Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::waitForRead(), false);
853 Q_CHECK_NOT_STATE(QNativeSocketEngine::waitForRead(),
854 QAbstractSocket::UnconnectedState, false);
855
856 if (timedOut)
857 *timedOut = false;
858
859 int ret = d->nativeSelect(msecs, true);
860 if (ret == 0) {
861 if (timedOut)
862 *timedOut = true;
863 d->setError(QAbstractSocket::SocketTimeoutError,
864 QNativeSocketEnginePrivate::TimeOutErrorString);
865 d->hasSetSocketError = false; // A timeout error is temporary in waitFor functions
866 return false;
867 } else if (state() == QAbstractSocket::ConnectingState) {
868 connectToHost(d->peerAddress, d->peerPort);
869 }
870
871 return ret > 0;
872}
873
874/*!
875 Waits for \a msecs milliseconds or until the socket is ready for
876 writing. If \a timedOut is not 0 and \a msecs milliseconds have
877 passed, the value of \a timedOut is set to true.
878
879 Returns true if data is available for writing; otherwise returns
880 false.
881
882 This is a blocking function call; its use is disadvised in a
883 single threaded application, as the whole thread will stop
884 responding until the function returns. waitForWrite() is most
885 useful when there is no event loop available. The general approach
886 is to create a QSocketNotifier, passing the socket descriptor
887 returned by socketDescriptor() to its constructor.
888*/
889bool QNativeSocketEngine::waitForWrite(int msecs, bool *timedOut)
890{
891 Q_D(QNativeSocketEngine);
892 Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::waitForWrite(), false);
893 Q_CHECK_NOT_STATE(QNativeSocketEngine::waitForWrite(),
894 QAbstractSocket::UnconnectedState, false);
895
896 if (timedOut)
897 *timedOut = false;
898
899 int ret = d->nativeSelect(msecs, false);
900 // On Windows, the socket is in connected state if a call to
901 // select(writable) is successful. In this case we should not
902 // issue a second call to WSAConnect()
903#if defined (Q_WS_WIN)
904 if (ret > 0) {
905 setState(QAbstractSocket::ConnectedState);
906 d_func()->fetchConnectionParameters();
907 return true;
908 } else {
909 int value = 0;
910 int valueSize = sizeof(value);
911 if (::getsockopt(d->socketDescriptor, SOL_SOCKET, SO_ERROR, (char *) &value, &valueSize) == 0) {
912 if (value == WSAECONNREFUSED) {
913 d->setError(QAbstractSocket::ConnectionRefusedError, QNativeSocketEnginePrivate::ConnectionRefusedErrorString);
914 d->socketState = QAbstractSocket::UnconnectedState;
915 return false;
916 } else if (value == WSAETIMEDOUT) {
917 d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::ConnectionTimeOutErrorString);
918 d->socketState = QAbstractSocket::UnconnectedState;
919 return false;
920 } else if (value == WSAEHOSTUNREACH) {
921 d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::HostUnreachableErrorString);
922 d->socketState = QAbstractSocket::UnconnectedState;
923 return false;
924 }
925 }
926 }
927#endif
928
929 if (ret == 0) {
930 if (timedOut)
931 *timedOut = true;
932 d->setError(QAbstractSocket::SocketTimeoutError,
933 QNativeSocketEnginePrivate::TimeOutErrorString);
934 d->hasSetSocketError = false; // A timeout error is temporary in waitFor functions
935 return false;
936 } else if (state() == QAbstractSocket::ConnectingState) {
937 connectToHost(d->peerAddress, d->peerPort);
938 }
939
940 return ret > 0;
941}
942
943bool QNativeSocketEngine::waitForReadOrWrite(bool *readyToRead, bool *readyToWrite,
944 bool checkRead, bool checkWrite,
945 int msecs, bool *timedOut)
946{
947 Q_D(QNativeSocketEngine);
948 Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::waitForWrite(), false);
949 Q_CHECK_NOT_STATE(QNativeSocketEngine::waitForReadOrWrite(),
950 QAbstractSocket::UnconnectedState, false);
951
952 int ret = d->nativeSelect(msecs, checkRead, checkWrite, readyToRead, readyToWrite);
953 // On Windows, the socket is in connected state if a call to
954 // select(writable) is successful. In this case we should not
955 // issue a second call to WSAConnect()
956#if defined (Q_WS_WIN)
957 if (checkWrite && ((readyToWrite && *readyToWrite) || !readyToWrite) && ret > 0) {
958 setState(QAbstractSocket::ConnectedState);
959 d_func()->fetchConnectionParameters();
960 return true;
961 } else {
962 int value = 0;
963 int valueSize = sizeof(value);
964 if (::getsockopt(d->socketDescriptor, SOL_SOCKET, SO_ERROR, (char *) &value, &valueSize) == 0) {
965 if (value == WSAECONNREFUSED) {
966 d->setError(QAbstractSocket::ConnectionRefusedError, QNativeSocketEnginePrivate::ConnectionRefusedErrorString);
967 d->socketState = QAbstractSocket::UnconnectedState;
968 return false;
969 } else if (value == WSAETIMEDOUT) {
970 d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::ConnectionTimeOutErrorString);
971 d->socketState = QAbstractSocket::UnconnectedState;
972 return false;
973 } else if (value == WSAEHOSTUNREACH) {
974 d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::HostUnreachableErrorString);
975 d->socketState = QAbstractSocket::UnconnectedState;
976 return false;
977 }
978 }
979 }
980#endif
981 if (ret == 0) {
982 if (timedOut)
983 *timedOut = true;
984 d->setError(QAbstractSocket::SocketTimeoutError,
985 QNativeSocketEnginePrivate::TimeOutErrorString);
986 d->hasSetSocketError = false; // A timeout error is temporary in waitFor functions
987 return false;
988 } else if (state() == QAbstractSocket::ConnectingState) {
989 connectToHost(d->peerAddress, d->peerPort);
990 }
991
992 return ret > 0;
993}
994
995/*!
996 Returns the size of the operating system's socket receive
997 buffer. Depending on the operating system, this size may be
998 different from what has been set earlier with
999 setReceiveBufferSize().
1000*/
1001qint64 QNativeSocketEngine::receiveBufferSize() const
1002{
1003 Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::receiveBufferSize(), -1);
1004 return option(ReceiveBufferSocketOption);
1005}
1006
1007/*!
1008 Sets the size of the operating system receive buffer to \a size.
1009
1010 For clients, this should be set before connectToHost() is called;
1011 otherwise it will have no effect. For servers, it should be called
1012 before listen().
1013
1014 The operating system receive buffer size effectively limits two
1015 things: how much data can be in transit at any one moment, and how
1016 much data can be received in one iteration of the main event loop.
1017 Setting the size of the receive buffer may have an impact on the
1018 socket's performance.
1019
1020 The default value is operating system-dependent.
1021*/
1022void QNativeSocketEngine::setReceiveBufferSize(qint64 size)
1023{
1024 Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::setReceiveBufferSize(), Q_VOID);
1025 setOption(ReceiveBufferSocketOption, size);
1026}
1027
1028/*!
1029 Returns the size of the operating system send buffer. Depending on
1030 the operating system, this size may be different from what has
1031 been set earlier with setSendBufferSize().
1032*/
1033qint64 QNativeSocketEngine::sendBufferSize() const
1034{
1035 Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::setSendBufferSize(), -1);
1036 return option(SendBufferSocketOption);
1037}
1038
1039/*!
1040 Sets the size of the operating system send buffer to \a size.
1041
1042 The operating system send buffer size effectively limits how much
1043 data can be in transit at any one moment. Setting the size of the
1044 send buffer may have an impact on the socket's performance.
1045
1046 The default value is operating system-dependent.
1047*/
1048void QNativeSocketEngine::setSendBufferSize(qint64 size)
1049{
1050 Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::setSendBufferSize(), Q_VOID);
1051 setOption(SendBufferSocketOption, size);
1052}
1053
1054
1055/*!
1056 Sets the option \a option to the value \a value.
1057*/
1058bool QNativeSocketEngine::setOption(SocketOption option, int value)
1059{
1060 Q_D(QNativeSocketEngine);
1061 return d->setOption(option, value);
1062}
1063
1064/*!
1065 Returns the value of the option \a socketOption.
1066*/
1067int QNativeSocketEngine::option(SocketOption socketOption) const
1068{
1069 Q_D(const QNativeSocketEngine);
1070 return d->option(socketOption);
1071}
1072
1073bool QNativeSocketEngine::isReadNotificationEnabled() const
1074{
1075 Q_D(const QNativeSocketEngine);
1076 return d->readNotifier && d->readNotifier->isEnabled();
1077}
1078
1079/*
1080 \internal
1081 \class QReadNotifier
1082 \brief The QReadNotifer class is used to improve performance.
1083
1084 QReadNotifier is a private class used for performance reasons vs
1085 connecting to the QSocketNotifier activated() signal.
1086 */
1087class QReadNotifier : public QSocketNotifier
1088{
1089public:
1090 QReadNotifier(int fd, QNativeSocketEngine *parent)
1091 : QSocketNotifier(fd, QSocketNotifier::Read, parent)
1092 { engine = parent; }
1093
1094protected:
1095 bool event(QEvent *);
1096
1097 QNativeSocketEngine *engine;
1098};
1099
1100bool QReadNotifier::event(QEvent *e)
1101{
1102 if (e->type() == QEvent::SockAct) {
1103 engine->readNotification();
1104 return true;
1105 }
1106 return QSocketNotifier::event(e);
1107}
1108
1109/*
1110 \internal
1111 \class QWriteNotifier
1112 \brief The QWriteNotifer class is used to improve performance.
1113
1114 QWriteNotifier is a private class used for performance reasons vs
1115 connecting to the QSocketNotifier activated() signal.
1116 */
1117class QWriteNotifier : public QSocketNotifier
1118{
1119public:
1120 QWriteNotifier(int fd, QNativeSocketEngine *parent)
1121 : QSocketNotifier(fd, QSocketNotifier::Write, parent) { engine = parent; }
1122
1123protected:
1124 bool event(QEvent *);
1125
1126 QNativeSocketEngine *engine;
1127};
1128
1129bool QWriteNotifier::event(QEvent *e)
1130{
1131 if (e->type() == QEvent::SockAct) {
1132 if (engine->state() == QAbstractSocket::ConnectingState)
1133 engine->connectionNotification();
1134 else
1135 engine->writeNotification();
1136 return true;
1137 }
1138 return QSocketNotifier::event(e);
1139}
1140
1141class QExceptionNotifier : public QSocketNotifier
1142{
1143public:
1144 QExceptionNotifier(int fd, QNativeSocketEngine *parent)
1145 : QSocketNotifier(fd, QSocketNotifier::Exception, parent) { engine = parent; }
1146
1147protected:
1148 bool event(QEvent *);
1149
1150 QNativeSocketEngine *engine;
1151};
1152
1153bool QExceptionNotifier::event(QEvent *e)
1154{
1155 if (e->type() == QEvent::SockAct) {
1156 if (engine->state() == QAbstractSocket::ConnectingState)
1157 engine->connectionNotification();
1158 else
1159 engine->exceptionNotification();
1160 return true;
1161 }
1162 return QSocketNotifier::event(e);
1163}
1164
1165void QNativeSocketEngine::setReadNotificationEnabled(bool enable)
1166{
1167 Q_D(QNativeSocketEngine);
1168 if (d->readNotifier) {
1169 d->readNotifier->setEnabled(enable);
1170 } else if (enable && d->threadData->eventDispatcher) {
1171 d->readNotifier = new QReadNotifier(d->socketDescriptor, this);
1172 d->readNotifier->setEnabled(true);
1173 }
1174}
1175
1176bool QNativeSocketEngine::isWriteNotificationEnabled() const
1177{
1178 Q_D(const QNativeSocketEngine);
1179 return d->writeNotifier && d->writeNotifier->isEnabled();
1180}
1181
1182void QNativeSocketEngine::setWriteNotificationEnabled(bool enable)
1183{
1184 Q_D(QNativeSocketEngine);
1185 if (d->writeNotifier) {
1186 d->writeNotifier->setEnabled(enable);
1187 } else if (enable && d->threadData->eventDispatcher) {
1188 d->writeNotifier = new QWriteNotifier(d->socketDescriptor, this);
1189 d->writeNotifier->setEnabled(true);
1190 }
1191}
1192
1193bool QNativeSocketEngine::isExceptionNotificationEnabled() const
1194{
1195 Q_D(const QNativeSocketEngine);
1196 return d->exceptNotifier && d->exceptNotifier->isEnabled();
1197}
1198
1199void QNativeSocketEngine::setExceptionNotificationEnabled(bool enable)
1200{
1201 Q_D(QNativeSocketEngine);
1202 if (d->exceptNotifier) {
1203 d->exceptNotifier->setEnabled(enable);
1204 } else if (enable && d->threadData->eventDispatcher) {
1205 d->exceptNotifier = new QExceptionNotifier(d->socketDescriptor, this);
1206 d->exceptNotifier->setEnabled(true);
1207 }
1208}
1209
1210QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.