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

Last change on this file since 67 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

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