3

I'm writing an application to download a file using Qt. The code snippet is

QNetworkAccessManager nam = new QNetworkAccessManager();

QNetworkRequest request;
request.setUrl(kUrl);

QNetworkReply reply;
//connect error(), finished(), downloadProgress(b,t) signal of reply object
reply = nam.get(request);

It works fine but under some circumstances in Mac, the downloads are stuck permanently without an error callback. Those situations are

  1. Pull out the LAN(internet) cable and insert it back quickly within 20 seconds
  2. Switch from Wired to WiFi within 10-20 seconds and viceversa

File Downloads are stuck in the above mentioned scenarios. Though, the frequency of this issue is once in 20 times(5%). To mitigate this, I wrote a workaround code to check whether network is up or down using TCP Socket and to poll it every 30 seconds.

bool check()
{
std::auto_ptr<QTcpSocket> sock(new QTcpSocket);
sock->connectToHost(kHostname, kConnectPort);
bool connected = sock->waitForConnected(30000);

if (!connected)
{
    sock->abort();
    return false;
}
sock->close();
return true;
}               

It worked well for certain extent. But even with this, if 'LAN card pull and insert back' happens within 30 seconds, downloads are getting stuck again. So, this workaround couldn't solve my issue completely. Polling in very shorter interval doesn't looks like a proper solution as for any shorter time interval, there can be a race condition.

I'm stuck here in finding out a way to solve this downloads stuck in the middle. Can anyone of you please help in figuring out a way to notify the downloads instantaneously when network goes off?

The Qt version which I'm using is 5.3.1 and Mac OS is 10.9.

2 Answers2

1

Take a look at QNetworkSession Class: http://doc.qt.digia.com/qtmobility/qnetworksession.html#State-enum

void QNetworkSession::stateChanged ( QNetworkSession::State state ) [signal]

This signal is emitted whenever the state of the network session changes. The state parameter is the new state.

Example:

// Set Internet Access Point
QNetworkConfigurationManager manager;

// Is there default access point, use it
QNetworkConfiguration cfg = manager.defaultConfiguration();

// Open session
m_session = new QNetworkSession(cfg);
connect(m_session, SIGNAL(closed()), this, SLOT(closed()));
connect(m_session, SIGNAL(stateChanged(QNetworkSession::State)), this, SLOT(stateChanged(QNetworkSession::State)));
connect(m_session, SIGNAL(error(QNetworkSession::SessionError)), this, SLOT(error(QNetworkSession::SessionError)));
m_session->open();
// Waits for session to be open and continues after that
m_session->waitForOpened();
Leo Chapiro
  • 13,678
  • 8
  • 61
  • 92
  • Thanks for the code. I implemented exact same one but my SLOTS are not called when I remove my LAN wire off and on. Lately what I noticed was, stateChanged(...) SLOTs was called when I did the command prompt way to disabling the ethernet card( ifconfig en0 down). not sure what is the difference between the two. Anyhow thanks for the help. – Gokulakrishnan Gopalakrishnan Jul 30 '14 at 11:19
0

You can use QNetworkConfigurationManager::onlineStateChanged(bool isOnline) signal to track whether you are connected to network or not.

rightaway717
  • 2,631
  • 3
  • 29
  • 43