Correct way to free up QTcpSocket* when connecting fails
-
Here is a simple code I am using in my class which is derived from QThread (I have performed moveToThread(this) in the constructor):
while(true) { QTcpSocket* mySocket = new QTcpSocket(this); connect(mySocket, SIGNAL(disconnected()), SLOT(deleteLater()) ); connect(mySocket,SIGNAL(error(QAbstractSocket::SocketError)),mySocket,SLOT(deleteLater())); mySocket->connectToHost(QHostAddress::LocalHost, 10010); if(mySocket->waitForConnected(2000)) { mySocket->write("OK"); mySocket->waitForBytesWritten(1000); mySocket->disconnectFromHost(); } // Sleep for 1 second QThread::msleep(1000); // Processing pending events in the thread QCoreApplication::processEvents();
}
When the waitForConnected succeeds, the socket will be correctly freed and the number of open files doesn't increase.
The problem is when is the connecting fails (e.g. server is unavailable). In this case, the number of open files (reported by /proc/<pid>/fd) increases for each attempt.
What is the clean way to free up QTcpSocket in this situtaion?
-
I think the simplest solution is :
if(mySocket->waitForConnected(2000)) { mySocket->write("OK"); mySocket->waitForBytesWritten(1000); mySocket->disconnectFromHost(); } else { // Server is not available: Maybe put the commands "msleep" and "processEvents" in the if clause mySocket->disconnectFromHost(); }
Other solutions with "QAbstractSocket::connected()" signal and "QAbstractSocket::state()" are possible too - depends on your needs.
-
@BERGLE said:
I think the simplest solution is :
if(mySocket->waitForConnected(2000)) { mySocket->write("OK"); mySocket->waitForBytesWritten(1000); mySocket->disconnectFromHost(); } else { // Server is not available: Maybe put the commands "msleep" and "processEvents" in the if clause mySocket->disconnectFromHost(); }
I have tried this solution, but it doesn't free the socket. I guess as we are not actually connected to the host, the "disconnected()" doesn't get fired by calling this function, hence the socket isn't freed.
Other solutions with "QAbstractSocket::connected()" signal and "QAbstractSocket::state()" are possible too - depends on your needs.
The stateChanged(socketState) signal could be helpful but I am not sure which stated should be checked to detect failure in connecting. The relevant states seems to be:
- QAbstractSocket::UnconnectedState: The socket is not connected.
- QAbstractSocket::ClosingState: The socket is about to close (data may still be waiting to be written).
But they probably occur when there is NOT a failure too.
-
Hello,
Few issues with Your code:- QThread constructor moveToThread( this); is error. QThread class is just control object and is not actually a separate thread. You should move class base on QObject (with would be wrapper for QTcpSocket communication) or QTcpSocket to separate thread.
2.. Don't know if this is Ui application but You are using blocking approach (may be ok for Your case)
- Error handing :
connect (QTcpSocket, SIGNAL( error(QAbstractSocket::SocketError socketError)), this, SLOT( error(QAbstractSocket::SocketError socketError)));
to handle connection error.
- Close socket via QTcpSocket::close() or abort() + close()