PDA

View Full Version : QSslSocket reconnect to host



Mandymo
13th October 2010, 22:25
If I am trying to connect to an invalid host, and, after the connection fails, I try to connect to a valid host, the connection still fails.


void testSoc::test()
{
switch (state)
{
case 0:
case 2:
case 4:
qDebug ("Connecting to a valid host. Should be Ok");
timeout->start(10000);
soc->connectToHost(VALID_HOST, VALID_PORT);
break;
case 1:
qDebug ("Connecting to a invalid port. Should fail");
timeout->start(10000);
soc->connectToHost(VALID_HOST, INVALID_PORT);
break;
case 3:
qDebug ("Connecting to a invalid host. Should fail");
timeout->start(10000);
soc->connectToHost(INVALID_HOST, VALID_PORT);
break;
}
}
void testSoc::checkConnection()
{
timeout->stop();
if (soc->state() == QAbstractSocket::ConnectedState)
{
connected();
} else {
qDebug ("Connection failed");
soc->disconnectFromHost();
if (soc->state() != QAbstractSocket::UnconnectedState)
soc->waitForDisconnected();
soc->close();
//delete soc;
//soc = new QSslSocket;
state ++;
test();
}
}

* and of course there is

connect (soc, SIGNAL(connected()),
this, SLOT(connected()));
connect (timeout, SIGNAL(timeout()),
this, SLOT(checkConnection()));

In this code, all gives the expected results, except for case 4 (including case 2, reconnecting after trying to connect to a valid host, with invalid port)

deleting and re-creating the socket does not help
(using Qt 4.4.3)

mraction
15th December 2019, 19:59
Hi,

did you find a solution for your problem?

stryga42
28th December 2019, 16:46
I have no experience with QSslSocket, but for QTcpSocket I never managed to establish a connection after an initial failure. I usually delete the failed QTcpSocket and create a new one for the next try. This seems to work fine without excessive overhead.
For some reason I can't remember right now I disconnected the socket before deleting. Here the snippet from my code wich trigger the reconnect attempt:

if(socket->state()!=QAbstractSocket::ConnectedState)
{
disconnect(socket, nullptr, nullptr, nullptr);
socket->close();
socket->deleteLater();
socket=nullptr;
lastErr_=1002;
lastErrStr_=QString("NetCon: connection attempt timed out after %1 ms").arg(toCon_);
qWarning()<<lastErrStr_;
emit errorSig(lastErr_);
emit readySig(false);
if(!isServer_)
{
if(testOnly)
qInfo()<<"test only - canceling reconnect attempt";
if(toCon_<86400000)
toCon_*=2; // will level off at 2^27 ~= 37h retry inteval
qWarning()<<"NetCon: retry to connect to"<<address_.toString();
start();
}
}

ChrisW67
29th December 2019, 03:17
Not pretty, but this variation on the original code works fine for me without recreating sockets etc.:

#ifndef TESTSOC_H
#define TESTSOC_H

#include <QTimer>
#include <QTcpSocket>
#include <QDebug>


class testSoc: public QObject {
Q_OBJECT
int state;
QTcpSocket *soc;
QTimer *timeout;
public:
explicit testSoc(QObject *p = nullptr);
~testSoc();
void test();

private slots:
void connected();
void handleError(QAbstractSocket::SocketError socketError);
void handleTimeout();

private:
void nextState();
};

#endif // TESTSOC_H


#include "testSoc.h"

#define VALID_HOST "www.google.com"
#define VALID_PORT 80
#define INVALID_HOST "localhost"
#define INVALID_PORT 81
#define TIMEOUT 3000

testSoc::testSoc(QObject *p):
QObject(p),
state(0),
soc(nullptr),
timeout(nullptr)
{
soc = new QTcpSocket(this);
connect (soc, SIGNAL(connected()), this, SLOT(connected()));
connect (soc, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(handleError(QAbstractSocket::SocketError)));

timeout = new QTimer(this);
timeout->setSingleShot(true);
timeout->setInterval(TIMEOUT);
connect (timeout, SIGNAL(timeout()), this, SLOT(handleTimeout()));
}

testSoc::~testSoc() {
}

void testSoc::test()
{
switch (state)
{
case 0:
case 2:
case 4:
qDebug () << "State" << state << "Connecting to a valid host. Should be Ok";
timeout->start();
soc->connectToHost(VALID_HOST, VALID_PORT);
break;
case 1:
qDebug () << "State" << state << "Connecting to a invalid port. Should fail";
timeout->start();
soc->connectToHost(VALID_HOST, INVALID_PORT);
break;
case 3:
qDebug () << "State" << state << "Connecting to a invalid host. Should fail";
timeout->start();
soc->connectToHost(INVALID_HOST, VALID_PORT);
break;
}
}

void testSoc::connected() {
timeout->stop();
qDebug() << "State" << state << "Connected to" << soc->peerName() << "port" << soc->peerPort();
// do some work here
soc->disconnectFromHost();
nextState();
}

void testSoc::handleError(QAbstractSocket::SocketError socketError) {
timeout->stop();
qDebug() << "State" << state << "Error reported" << socketError;
nextState();
}

void testSoc::handleTimeout()
{
timeout->stop();
qDebug () << "State" << state << "Connection time out";
// Using disconnectFromHost() on a host that was never connected
// just causes a long pause for some internal timeout.
soc->abort();
nextState();
}

void testSoc::nextState()
{
state = (state + 1) % 5;
test();
}


#include <QApplication>
#include "testSoc.h"

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
testSoc t;
t.test();
return a.exec();
}