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

Last change on this file since 754 was 651, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.2 sources.

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