PDA

View Full Version : Wait for socket to connect without application hang?



hakermania
10th September 2011, 16:31
Hello, that's the code:


QTcpSocket sock;
sock.connectToHost("www.gamato.info", 80);
if (sock.waitForConnected(15000))
qDebug("Connected!");
else
qDebug("Not connected!");

I chose gamato.info as it is an unresponsive server and I noticed that the whole application hangs for 15 seconds.
The function in which this runs is static and cannot be run through QtConcurrentRun!
The actual problem is checking if internet connection is established or not, but this way I take the non-rare situation in which internet connection may be established locally but modem not connected etc.
I need a way :(

Talei
10th September 2011, 22:43
It's no surprise that app hangs for 15 seconds because You designed it that way.
I personally would use code posted by You only in situation when I need measure proxy speed with wait condition set to i.e. 250 ms. And even in that situation better way is to use timer and signal/slot mechanism, because using it in thread is just pain.

Use signal and slot mechanism (i.e. socket->hostFound or better socket->stateChanged) to implement non-blocking socket!

hakermania
11th September 2011, 09:29
Thanks, this was helpful and quite easy to implement, but I have a problem, this is my boolean function that is called from another pieces of code. It is to return true if there's connection (it manages to connect to the specified host) and is to return false if it doesn't manage to connect to the specified host.
This *was* the code that hanged but worked fine (I had the opportunity to return true or false)


bool Global::connected_to_internet(){
QTcpSocket sock;
sock.connectToHost("www.gamato.info", 80);
if (sock.waitForConnected(15000))
return true;
else
return false;
}


The piece of code using your suggestion will be:


bool Global::connected_to_internet(){
sock = new QTcpSocket(this);
QObject::connect(sock, SIGNAL(stateChanged(QAbstractSocket::SocketState)) , this, SLOT(check_what_happened(QAbstractSocket::SocketTy pe)) );
sock.connectToHost("www.gamato.info", 80);
}

void Global::check_what_happened(QAbstractSocket::Socke tType socktype){ //< it goes through this function while the bollean is over

switch(socktype){

case QAbstractSocket::hostFound():

//etc

}
}


I don't know how to work this out. I need my boolean function to return true or false and by calling another void function (maybe can it be boolean and somehow grab true or false or to emit a signal?) I cannot alert somehow if I could connect to the host or not... :/

Talei
11th September 2011, 21:50
This is strict alog. implementation issue and can be resolved in many ways.
I would make global var bool m_gotConnection = false;, then change that variable on sign. socket->stateChange, i.e gotConnection = true; then I would create QTimer and on timeout i would check if gotConnection i true or not and see how many ms passed out.

Pseudo code:

bool m_gotConn = false;
bool Global::connected_to_internet()
{
QTcpSocket *sock = new QTcpSocket(this);
QTimer *timer = new QTimer(this);

connect(sock, SIGNAL(stateChanged(QAbstractSocket::SocketState)) , this, SLOT(check_what_happened(QAbstractSocket::SocketTy pe)) );
connect( timer, SIGNAL(timeout()), this, SLOT( checkConnState() ));
m_gotConn = false;
timer->setInterval( 15000 );

sock.connectToHost("www.gamato.info", 80);
timer->start();
}

void Global::check_what_happened(QAbstractSocket::Socke tType socktype)
{
switch(socktype){
case QAbstractSocket::hostFound(): {
m_gotConn = true;
// host connected, stop timer
timer->stop();
}break;

//etc

}
}

void Global::checkConnState()
{
//Not connected after 15 sec
if( !m_gotConn ) {
socket->abort();
}else{
//Connected after 15 sec
// this should be never reached in curr. impl but just to show idea
}
}

hakermania
8th October 2011, 23:21
one word: QNetworkConfigurationManager::isOnline();

wysota
9th October 2011, 12:03
one word: QNetworkConfigurationManager::isOnline();

This won't tell you if you're connected to the Internet. It will only tell you whether the link is up or down.