src/network/socket/qabstractsocket.cpp
changeset 7 f7bc934e204c
parent 3 41300fa6a67c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
     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