diff options
author | Martin Petersson <Martin.Petersson@nokia.com> | 2012-07-12 12:52:17 +0200 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-07-30 10:43:50 +0200 |
commit | 4d38a3b2dabda9c89c1b257820911aa987f04d2b (patch) | |
tree | 46c0e5697e204f43f49804208e5cf8370afdb5c5 /src/network/socket | |
parent | ada38c75cccb33947107212c08e7b080e6b54f84 (diff) |
QtNetwork: Better detection of connection failures on Windows
If the error code from WSAConnect is WSAEWOULDBLOCK, then the
operation proceeds but the outcome is not known at that time. We then
check SO_ERROR's value to detect errors. But if that call returns 0
this could indicate that the value is still not know. In this case
we try one more time to increase the chance of getting the correct
value.
This fixed the tst_QNetworkReply::getFromUnreachableIp auto test
on Windows.
Change-Id: I25008aca062b2f823e3d93ebb0ae456d7e4a6ecc
Reviewed-by: Shane Kearns <shane.kearns@accenture.com>
Diffstat (limited to 'src/network/socket')
-rw-r--r-- | src/network/socket/qnativesocketengine_win.cpp | 62 |
1 files changed, 41 insertions, 21 deletions
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index 59e851714f..aebb9dc40e 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -683,28 +683,48 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &address, quin // unfinished operation. int value = 0; QT_SOCKLEN_T valueSize = sizeof(value); - if (::getsockopt(socketDescriptor, SOL_SOCKET, SO_ERROR, (char *) &value, &valueSize) == 0) { - if (value == WSAECONNREFUSED) { - setError(QAbstractSocket::ConnectionRefusedError, ConnectionRefusedErrorString); - socketState = QAbstractSocket::UnconnectedState; - break; + bool tryAgain = false; + bool errorDetected = false; + int tries = 0; + do { + if (::getsockopt(socketDescriptor, SOL_SOCKET, SO_ERROR, (char *) &value, &valueSize) == 0) { + if (value == WSAECONNREFUSED) { + setError(QAbstractSocket::ConnectionRefusedError, ConnectionRefusedErrorString); + socketState = QAbstractSocket::UnconnectedState; + errorDetected = true; + break; + } + if (value == WSAETIMEDOUT) { + setError(QAbstractSocket::NetworkError, ConnectionTimeOutErrorString); + socketState = QAbstractSocket::UnconnectedState; + errorDetected = true; + break; + } + if (value == WSAEHOSTUNREACH) { + setError(QAbstractSocket::NetworkError, HostUnreachableErrorString); + socketState = QAbstractSocket::UnconnectedState; + errorDetected = true; + break; + } + if (value == WSAEADDRNOTAVAIL) { + setError(QAbstractSocket::NetworkError, AddressNotAvailableErrorString); + socketState = QAbstractSocket::UnconnectedState; + errorDetected = true; + break; + } + if (value == NOERROR) { + // When we get WSAEWOULDBLOCK the outcome was not known, so a + // NOERROR might indicate that the result of the operation + // is still unknown. We try again to increase the chance that we did + // get the correct result. + tryAgain = !tryAgain; + } } - if (value == WSAETIMEDOUT) { - setError(QAbstractSocket::NetworkError, ConnectionTimeOutErrorString); - socketState = QAbstractSocket::UnconnectedState; - break; - } - if (value == WSAEHOSTUNREACH) { - setError(QAbstractSocket::NetworkError, HostUnreachableErrorString); - socketState = QAbstractSocket::UnconnectedState; - break; - } - if (value == WSAEADDRNOTAVAIL) { - setError(QAbstractSocket::NetworkError, AddressNotAvailableErrorString); - socketState = QAbstractSocket::UnconnectedState; - break; - } - } + tries++; + } while (tryAgain && (tries < 2)); + + if (errorDetected) + break; // fall through } case WSAEINPROGRESS: |