Details
-
Bug
-
Resolution: Duplicate
-
P2: Important
-
None
-
5.0.0 Beta 1
-
None
-
{noformat}
$ uname -a
Linux sjinks 3.5.0-17-generic #28-Ubuntu SMP Tue Oct 9 19:31:23 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
$ lsb_release -rd
Description: Ubuntu 12.10
Release: 12.10
{noformat}
Description
Sample code:
#include <QtCore/QCoreApplication> #include <QtCore/QDebug> #include <QtNetwork/QHostAddress> #include <QtNetwork/QTcpSocket> #include "sockettester.h" SocketTester::SocketTester(QObject* parent) : QObject(parent), socket(new QTcpSocket()) { QObject::connect(socket, SIGNAL(connected()), this, SLOT(connected())); QObject::connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected())); QObject::connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error(QAbstractSocket::SocketError))); QObject::connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead())); QObject::connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(stateChanged(QAbstractSocket::SocketState))); } void SocketTester::run(void) { this->socket->bind(QHostAddress(QLatin1String("72.251.207.223")), 0); this->socket->connectToHost(QLatin1String("aspmx.l.google.com."), 25); } void SocketTester::connected(void) { qDebug() << "CONNECTED" << this->socket->localAddress() << this->socket->localPort(); } void SocketTester::disconnected(void) { qDebug() << "DISCONNECTED"; QCoreApplication::quit(); } void SocketTester::error(QAbstractSocket::SocketError e) { qDebug() << "ERROR" << e << this->socket->errorString(); } void SocketTester::readyRead(void) { static int f = 0; qDebug() << "READYREAD" << this->socket->readAll(); if (!f) { f = 1; this->socket->write("EHLO localhost\r\n"); } else if (1 == f) { this->socket->write("QUIT\r\n"); f = 2; } } void SocketTester::stateChanged(QAbstractSocket::SocketState s) { qDebug() << "STATECHANGED" << s << this->socket->localAddress() << this->socket->localPort(); }
Output (Qt built in debug mode):
QTcpSocket::QTcpSocket() QAbstractSocketPrivate::resetSocketLayer() QAbstractSocketPrivate::initSocketLayer(TcpSocket, IPv4Protocol) success QNativeSocketEnginePrivate::nativeBind(72.251.207.223, 0) == true QNativeSocketEnginePrivate::fetchConnectionParameters() local == 72.251.207.223:46140, peer == :0, socket == TcpSocket - IPv4Protocol STATECHANGED QAbstractSocket::BoundState QHostAddress( "72.251.207.223" ) 46140 QAbstractSocket::connectToHost("aspmx.l.google.com.", 25, 3)... STATECHANGED QAbstractSocket::HostLookupState QHostAddress( "" ) 0 QHostInfo::lookupHost("aspmx.l.google.com.", 0x17d0bb0, _q_startConnecting(QHostInfo)) QAbstractSocket::connectToHost("aspmx.l.google.com.", 25) == false (connection in progress) QAbstractSocketPrivate::canReadNotification() QNativeSocketEnginePrivate::nativeBytesAvailable() == 0 QAbstractSocketPrivate::readFromSocket() about to read 4096 bytes QHostInfoAgent::fromName(aspmx.l.google.com.) looking up... QNativeSocketEnginePrivate::nativeRead(0x17d2a40 "", 4096) == -1 QNativeSocketEngine::nativeClose() QAbstractSocketPrivate::readFromSocket() got -1 bytes, buffer size = 0 ERROR QAbstractSocket::NetworkError "Transport endpoint is not connected" QAbstractSocketPrivate::readFromSocket() read failed: Transport endpoint is not connected QAbstractSocketPrivate::resetSocketLayer() QAbstractSocketPrivate::canReadNotification() disconnecting socket QAbstractSocket::disconnectFromHost() QAbstractSocket::disconnectFromHost() but we're still connecting getaddrinfo node: flags: 32 family: 2 ai_socktype: 1 ai_protocol: 6 ai_addrlen: 16 getaddrinfo node: flags: 32 family: 2 ai_socktype: 2 ai_protocol: 17 ai_addrlen: 16 getaddrinfo node: flags: 32 family: 2 ai_socktype: 3 ai_protocol: 0 ai_addrlen: 16 QHostInfoAgent::fromName(): found 1 entries for "aspmx.l.google.com.": {173.194.65.26} QAbstractSocketPrivate::_q_startConnecting(hostInfo == {173.194.65.26}) STATECHANGED QAbstractSocket::ConnectingState QHostAddress( "" ) 0 QAbstractSocketPrivate::_q_connectToNextAddress(), connecting to 173.194.65.26:25, 1 left to try QAbstractSocketPrivate::resetSocketLayer() QAbstractSocketPrivate::initSocketLayer(TcpSocket, IPv4Protocol) success QNativeSocketEnginePrivate::nativeConnect() : 4 QNativeSocketEnginePrivate::nativeConnect(173.194.65.26, 25) == false (Connection in progress) QNativeSocketEnginePrivate::nativeConnect() : 4 QNativeSocketEnginePrivate::nativeConnect(173.194.65.26, 25) == true QNativeSocketEnginePrivate::fetchConnectionParameters() local == 78.30.235.66:49951, peer == 173.194.65.26:25, socket == TcpSocket - IPv4Protocol QAbstractSocketPrivate::connectionNotification() testing connection STATECHANGED QAbstractSocket::ConnectedState QHostAddress( "78.30.235.66" ) 49951 CONNECTED QHostAddress( "78.30.235.66" ) 49951 QAbstractSocketPrivate::fetchConnectionParameters() connection to 173.194.65.26:25 established QAbstractSocket::disconnectFromHost() QAbstractSocket::disconnectFromHost() emits stateChanged()(ClosingState) STATECHANGED QAbstractSocket::ClosingState QHostAddress( "78.30.235.66" ) 49951 QAbstractSocket::disconnectFromHost() disconnecting immediately QAbstractSocketPrivate::resetSocketLayer() QNativeSocketEngine::nativeClose() STATECHANGED QAbstractSocket::UnconnectedState QHostAddress( "78.30.235.66" ) 49951 DISCONNECTED QAbstractSocket::disconnectFromHost() disconnected!
A call to QAbstractSocketPrivate::resetSocketLayer() closes the socket and thus the binding is lost. QAbstractSocketPrivate::_q_connectToNextAddress() calls resetSocketLayer() again.
If we replace
this->socket->connectToHost(QLatin1String("aspmx.l.google.com."), 25);
with
this->socket->connectToHost(QLatin1String("173.194.65.26"), 25);
the binding will still be lost but the picture will be different ("Transport endpoint is not connected" error will be gone and we will actually be able to connect to the host):
QAbstractSocket::QAbstractSocket(TcpSocket, QAbstractSocketPrivate == 0x1599ba0, parent == 0x0) QTcpSocket::QTcpSocket() QAbstractSocketPrivate::resetSocketLayer() QAbstractSocketPrivate::initSocketLayer(TcpSocket, IPv4Protocol) success QNativeSocketEnginePrivate::nativeBind(72.251.207.223, 0) == true QNativeSocketEnginePrivate::fetchConnectionParameters() local == 72.251.207.223:40649, peer == :0, socket == TcpSocket - IPv4Protocol STATECHANGED QAbstractSocket::BoundState QHostAddress( "72.251.207.223" ) 40649 QAbstractSocket::connectToHost("173.194.65.26", 25, 3)... STATECHANGED QAbstractSocket::HostLookupState QHostAddress( "" ) 0 QAbstractSocketPrivate::_q_startConnecting(hostInfo == {173.194.65.26}) STATECHANGED QAbstractSocket::ConnectingState QHostAddress( "" ) 0 QAbstractSocketPrivate::_q_connectToNextAddress(), connecting to 173.194.65.26:25, 1 left to try QAbstractSocketPrivate::resetSocketLayer() QNativeSocketEngine::nativeClose() QAbstractSocketPrivate::initSocketLayer(TcpSocket, IPv4Protocol) success QNativeSocketEnginePrivate::nativeConnect() : 4 QNativeSocketEnginePrivate::nativeConnect(173.194.65.26, 25) == false (Connection in progress) QAbstractSocket::connectToHost("173.194.65.26", 25) == false (connection in progress) QNativeSocketEnginePrivate::nativeConnect() : 4 QNativeSocketEnginePrivate::nativeConnect(173.194.65.26, 25) == true QNativeSocketEnginePrivate::fetchConnectionParameters() local == 78.30.235.66:50044, peer == 173.194.65.26:25, socket == TcpSocket - IPv4Protocol QAbstractSocketPrivate::connectionNotification() testing connection STATECHANGED QAbstractSocket::ConnectedState QHostAddress( "78.30.235.66" ) 50044 CONNECTED QHostAddress( "78.30.235.66" ) 50044 QAbstractSocketPrivate::fetchConnectionParameters() connection to 173.194.65.26:25 established QAbstractSocketPrivate::canWriteNotification() flushing QAbstractSocketPrivate::flush() nothing to do: valid ? yes, writeBuffer.isEmpty() ? yes QAbstractSocketPrivate::canReadNotification() QNativeSocketEnginePrivate::nativeBytesAvailable() == 44 QAbstractSocketPrivate::readFromSocket() about to read 44 bytes QNativeSocketEnginePrivate::nativeRead(0x159b570 "220 mx.google.co...", 44) == 44 QAbstractSocketPrivate::readFromSocket() got 44 bytes, buffer size = 44 READYREAD "220 mx.google.com ESMTP n49si4070759eeo.97 " QAbstractSocket::writeData(0x40352d "EHLO localhost\r\n", 16) == 16 QAbstractSocketPrivate::canWriteNotification() flushing QNativeSocketEnginePrivate::nativeWrite(0x159b588 "EHLO localhost\r\n", 16) == 16 QAbstractSocketPrivate::flush() 16 bytes written to the network QAbstractSocketPrivate::canReadNotification() QNativeSocketEnginePrivate::nativeBytesAvailable() == 123 QAbstractSocketPrivate::readFromSocket() about to read 123 bytes QNativeSocketEnginePrivate::nativeRead(0x159b570 "250-mx.google.co...", 123) == 123 QAbstractSocketPrivate::readFromSocket() got 123 bytes, buffer size = 123 READYREAD "250-mx.google.com at your service, [78.30.235.66] 250-SIZE 35882577 250-8BITMIME 250-STARTTLS 250 ENHANCEDSTATUSCODES " QAbstractSocket::writeData(0x40353e "QUIT\r\n", 6) == 6 QAbstractSocketPrivate::canWriteNotification() flushing QNativeSocketEnginePrivate::nativeWrite(0x159b588 "QUIT\r\n", 6) == 6 QAbstractSocketPrivate::flush() 6 bytes written to the network QAbstractSocketPrivate::canReadNotification() QNativeSocketEnginePrivate::nativeBytesAvailable() == 49 QAbstractSocketPrivate::readFromSocket() about to read 49 bytes QNativeSocketEnginePrivate::nativeRead(0x159b570 "221 2.0.0 closin...", 49) == 49 QAbstractSocketPrivate::readFromSocket() got 49 bytes, buffer size = 49 READYREAD "221 2.0.0 closing connection n49si4070759eeo.97 " QAbstractSocketPrivate::canReadNotification() QNativeSocketEnginePrivate::nativeBytesAvailable() == 0 QAbstractSocketPrivate::readFromSocket() about to read 4096 bytes QNativeSocketEnginePrivate::nativeRead(0x159b570 "", 4096) == 0 QNativeSocketEngine::nativeClose() QAbstractSocketPrivate::readFromSocket() got -1 bytes, buffer size = 0 ERROR QAbstractSocket::RemoteHostClosedError "The remote host closed the connection" QAbstractSocketPrivate::readFromSocket() read failed: The remote host closed the connection QAbstractSocketPrivate::resetSocketLayer() QAbstractSocketPrivate::canReadNotification() disconnecting socket QAbstractSocket::disconnectFromHost() QAbstractSocket::disconnectFromHost() emits stateChanged()(ClosingState) STATECHANGED QAbstractSocket::ClosingState QHostAddress( "78.30.235.66" ) 50044 QAbstractSocket::disconnectFromHost() disconnecting immediately QAbstractSocketPrivate::resetSocketLayer() STATECHANGED QAbstractSocket::UnconnectedState QHostAddress( "78.30.235.66" ) 50044 DISCONNECTED QAbstractSocket::disconnectFromHost() disconnected!
The expected behavior is:
- when connecting to the host by name:
- we should not try to read from the not connected socket (resulting in "Transport endpoint is not connected" error)
- socket binding must be preserved
- we should eventually be able to connect to the host
- when connecting to the host by IP:
- socket binding must be preserved - QAbstractSocketPrivate::_q_connectToNextAddress() probably should not call resetSocketLayer()
Attachments
Issue Links
- relates to
-
QTBUG-26538 QUdpSocket: connectToHost() resets local port number specified by bind()
-
- Closed
-
For Gerrit Dashboard: QTBUG-27678 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
73492,3 | Retain bound port and address when QTcpSocket::connectToHost is called | stable | qt/qtbase | Status: ABANDONED | -1 | 0 |