1 /**************************************************************************** |
1 /**************************************************************************** |
2 ** |
2 ** |
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |
4 ** All rights reserved. |
4 ** All rights reserved. |
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
6 ** |
6 ** |
7 ** This file is part of the QtNetwork module of the Qt Toolkit. |
7 ** This file is part of the QtNetwork module of the Qt Toolkit. |
8 ** |
8 ** |
153 However, in a GUI application, blocking sockets should only be |
153 However, in a GUI application, blocking sockets should only be |
154 used in non-GUI threads, to avoid freezing the user interface. |
154 used in non-GUI threads, to avoid freezing the user interface. |
155 See the \l network/fortuneclient and \l network/blockingfortuneclient |
155 See the \l network/fortuneclient and \l network/blockingfortuneclient |
156 examples for an overview of both approaches. |
156 examples for an overview of both approaches. |
157 |
157 |
|
158 \note We discourage the use of the blocking functions together |
|
159 with signals. One of the two possibilities should be used. |
|
160 |
158 QAbstractSocket can be used with QTextStream and QDataStream's |
161 QAbstractSocket can be used with QTextStream and QDataStream's |
159 stream operators (operator<<() and operator>>()). There is one |
162 stream operators (operator<<() and operator>>()). There is one |
160 issue to be aware of, though: You must make sure that enough data |
163 issue to be aware of, though: You must make sure that enough data |
161 is available before attempting to read it using operator>>(). |
164 is available before attempting to read it using operator>>(). |
162 |
165 |
167 \fn void QAbstractSocket::hostFound() |
170 \fn void QAbstractSocket::hostFound() |
168 |
171 |
169 This signal is emitted after connectToHost() has been called and |
172 This signal is emitted after connectToHost() has been called and |
170 the host lookup has succeeded. |
173 the host lookup has succeeded. |
171 |
174 |
|
175 \note Since Qt 4.6.3 QAbstractSocket may emit hostFound() |
|
176 directly from the connectToHost() call since a DNS result could have been |
|
177 cached. |
|
178 |
172 \sa connected() |
179 \sa connected() |
173 */ |
180 */ |
174 |
181 |
175 /*! |
182 /*! |
176 \fn void QAbstractSocket::connected() |
183 \fn void QAbstractSocket::connected() |
177 |
184 |
178 This signal is emitted after connectToHost() has been called and |
185 This signal is emitted after connectToHost() has been called and |
179 a connection has been successfully established. |
186 a connection has been successfully established. |
|
187 |
|
188 \note On some operating systems the connected() signal may |
|
189 be directly emitted from the connectToHost() call for connections |
|
190 to the localhost. |
180 |
191 |
181 \sa connectToHost(), disconnected() |
192 \sa connectToHost(), disconnected() |
182 */ |
193 */ |
183 |
194 |
184 /*! |
195 /*! |
349 */ |
360 */ |
350 |
361 |
351 #include "qabstractsocket.h" |
362 #include "qabstractsocket.h" |
352 #include "qabstractsocket_p.h" |
363 #include "qabstractsocket_p.h" |
353 |
364 |
|
365 #include "private/qhostinfo_p.h" |
|
366 |
354 #include <qabstracteventdispatcher.h> |
367 #include <qabstracteventdispatcher.h> |
355 #include <qdatetime.h> |
368 #include <qdatetime.h> |
356 #include <qhostaddress.h> |
369 #include <qhostaddress.h> |
357 #include <qhostinfo.h> |
370 #include <qhostinfo.h> |
358 #include <qmetaobject.h> |
371 #include <qmetaobject.h> |
518 #endif |
531 #endif |
519 |
532 |
520 Q_Q(QAbstractSocket); |
533 Q_Q(QAbstractSocket); |
521 #if defined (QABSTRACTSOCKET_DEBUG) |
534 #if defined (QABSTRACTSOCKET_DEBUG) |
522 QString typeStr; |
535 QString typeStr; |
523 if (q->socketType() == QAbstractSocket::TcpSocket) typeStr = "TcpSocket"; |
536 if (q->socketType() == QAbstractSocket::TcpSocket) typeStr = QLatin1String("TcpSocket"); |
524 else if (q->socketType() == QAbstractSocket::UdpSocket) typeStr = "UdpSocket"; |
537 else if (q->socketType() == QAbstractSocket::UdpSocket) typeStr = QLatin1String("UdpSocket"); |
525 else typeStr = "UnknownSocketType"; |
538 else typeStr = QLatin1String("UnknownSocketType"); |
526 QString protocolStr; |
539 QString protocolStr; |
527 if (protocol == QAbstractSocket::IPv4Protocol) protocolStr = "IPv4Protocol"; |
540 if (protocol == QAbstractSocket::IPv4Protocol) protocolStr = QLatin1String("IPv4Protocol"); |
528 else if (protocol == QAbstractSocket::IPv6Protocol) protocolStr = "IPv6Protocol"; |
541 else if (protocol == QAbstractSocket::IPv6Protocol) protocolStr = QLatin1String("IPv6Protocol"); |
529 else protocolStr = "UnknownNetworkLayerProtocol"; |
542 else protocolStr = QLatin1String("UnknownNetworkLayerProtocol"); |
530 #endif |
543 #endif |
531 |
544 |
532 resetSocketLayer(); |
545 resetSocketLayer(); |
533 socketEngine = QAbstractSocketEngine::createSocketEngine(q->socketType(), proxyInUse, q); |
546 socketEngine = QAbstractSocketEngine::createSocketEngine(q->socketType(), proxyInUse, q); |
534 if (!socketEngine) { |
547 if (!socketEngine) { |
871 { |
884 { |
872 Q_Q(QAbstractSocket); |
885 Q_Q(QAbstractSocket); |
873 if (state != QAbstractSocket::HostLookupState) |
886 if (state != QAbstractSocket::HostLookupState) |
874 return; |
887 return; |
875 |
888 |
|
889 if (hostLookupId != -1 && hostLookupId != hostInfo.lookupId()) { |
|
890 qWarning("QAbstractSocketPrivate::_q_startConnecting() received hostInfo for wrong lookup ID %d expected %d", hostInfo.lookupId(), hostLookupId); |
|
891 } |
|
892 |
876 addresses = hostInfo.addresses(); |
893 addresses = hostInfo.addresses(); |
877 |
894 |
878 #if defined(QABSTRACTSOCKET_DEBUG) |
895 #if defined(QABSTRACTSOCKET_DEBUG) |
879 QString s = "{"; |
896 QString s = QLatin1String("{"); |
880 for (int i = 0; i < addresses.count(); ++i) { |
897 for (int i = 0; i < addresses.count(); ++i) { |
881 if (i != 0) s += ", "; |
898 if (i != 0) s += QLatin1String(", "); |
882 s += addresses.at(i).toString(); |
899 s += addresses.at(i).toString(); |
883 } |
900 } |
884 s += '}'; |
901 s += QLatin1Char('}'); |
885 qDebug("QAbstractSocketPrivate::_q_startConnecting(hostInfo == %s)", s.toLatin1().constData()); |
902 qDebug("QAbstractSocketPrivate::_q_startConnecting(hostInfo == %s)", s.toLatin1().constData()); |
886 #endif |
903 #endif |
887 |
904 |
888 // Try all addresses twice. |
905 // Try all addresses twice. |
889 addresses += addresses; |
906 addresses += addresses; |
1360 // the proxy supports connection by name, so use it |
1377 // the proxy supports connection by name, so use it |
1361 d->startConnectingByName(hostName); |
1378 d->startConnectingByName(hostName); |
1362 return; |
1379 return; |
1363 #endif |
1380 #endif |
1364 } else { |
1381 } else { |
1365 if (d->threadData->eventDispatcher) |
1382 if (d->threadData->eventDispatcher) { |
1366 d->hostLookupId = QHostInfo::lookupHost(hostName, this, SLOT(_q_startConnecting(QHostInfo))); |
1383 // this internal API for QHostInfo either immediatly gives us the desired |
|
1384 // QHostInfo from cache or later calls the _q_startConnecting slot. |
|
1385 bool immediateResultValid = false; |
|
1386 QHostInfo hostInfo = qt_qhostinfo_lookup(hostName, |
|
1387 this, |
|
1388 SLOT(_q_startConnecting(QHostInfo)), |
|
1389 &immediateResultValid, |
|
1390 &d->hostLookupId); |
|
1391 if (immediateResultValid) { |
|
1392 d->hostLookupId = -1; |
|
1393 d->_q_startConnecting(hostInfo); |
|
1394 } |
|
1395 } |
1367 } |
1396 } |
1368 |
1397 |
1369 #if defined(QABSTRACTSOCKET_DEBUG) |
1398 #if defined(QABSTRACTSOCKET_DEBUG) |
1370 qDebug("QAbstractSocket::connectToHost(\"%s\", %i) == %s%s", hostName.toLatin1().constData(), port, |
1399 qDebug("QAbstractSocket::connectToHost(\"%s\", %i) == %s%s", hostName.toLatin1().constData(), port, |
1371 (d->state == ConnectedState) ? "true" : "false", |
1400 (d->state == ConnectedState) ? "true" : "false", |
1676 |
1705 |
1677 \snippet doc/src/snippets/code/src_network_socket_qabstractsocket.cpp 0 |
1706 \snippet doc/src/snippets/code/src_network_socket_qabstractsocket.cpp 0 |
1678 |
1707 |
1679 If msecs is -1, this function will not time out. |
1708 If msecs is -1, this function will not time out. |
1680 |
1709 |
1681 Note: This function may wait slightly longer than \a msecs, |
1710 \note This function may wait slightly longer than \a msecs, |
1682 depending on the time it takes to complete the host lookup. |
1711 depending on the time it takes to complete the host lookup. |
|
1712 |
|
1713 \note Multiple calls to this functions do not accumulate the time. |
|
1714 If the function times out, the connecting process will be aborted. |
1683 |
1715 |
1684 \sa connectToHost(), connected() |
1716 \sa connectToHost(), connected() |
1685 */ |
1717 */ |
1686 bool QAbstractSocket::waitForConnected(int msecs) |
1718 bool QAbstractSocket::waitForConnected(int msecs) |
1687 { |
1719 { |
1716 QHostInfo::abortHostLookup(d->hostLookupId); |
1748 QHostInfo::abortHostLookup(d->hostLookupId); |
1717 d->hostLookupId = -1; |
1749 d->hostLookupId = -1; |
1718 d->_q_startConnecting(QHostInfo::fromName(d->hostName)); |
1750 d->_q_startConnecting(QHostInfo::fromName(d->hostName)); |
1719 } |
1751 } |
1720 if (state() == UnconnectedState) |
1752 if (state() == UnconnectedState) |
1721 return false; |
1753 return false; // connect not im progress anymore! |
1722 |
1754 |
1723 bool timedOut = true; |
1755 bool timedOut = true; |
1724 #if defined (QABSTRACTSOCKET_DEBUG) |
1756 #if defined (QABSTRACTSOCKET_DEBUG) |
1725 int attempt = 1; |
1757 int attempt = 1; |
1726 #endif |
1758 #endif |