Mac — обнаружение отключения сети с помощью Qt

Я пишу приложение для загрузки файла с помощью Qt. Фрагмент кода

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);

Он работает нормально, но при некоторых обстоятельствах на Mac загрузка постоянно зависает без обратного вызова ошибки. Эти ситуации

  1. Вытяните кабель LAN (интернет) и быстро вставьте его обратно в течение 20 секунд.
  2. Переключение с проводного на WiFi в течение 10-20 секунд и наоборот

Загрузка файлов зависает в вышеупомянутых сценариях. Хотя частота этой проблемы составляет один раз в 20 раз (5%). Чтобы смягчить это, я написал обходной код, чтобы проверять, работает ли сеть, используя TCP Socket, и опрашивать ее каждые 30 секунд.

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;
}               

Это работало хорошо до определенной степени. Но даже при этом, если в течение 30 секунд происходит «вытащить и вставить карту LAN», загрузка снова останавливается. Таким образом, этот обходной путь не мог полностью решить мою проблему. Опрос с очень коротким интервалом не выглядит правильным решением, так как для любого более короткого интервала времени может возникнуть состояние гонки.

Я застрял здесь, чтобы найти способ решить эту загрузку, застрявшую посередине. Может ли кто-нибудь из вас помочь найти способ мгновенного уведомления о загрузках при отключении сети?

Версия Qt, которую я использую, — 5.3.1, а Mac OS — 10.9.


person Gokulakrishnan Gopalakrishnan    schedule 28.07.2014    source источник
comment
Пробовали ли вы QNetworkSession: qt-project.org/doc/qt-4.8/qnetworksession .html ?   -  person Leo Chapiro    schedule 28.07.2014
comment
Спасибо @duDE. Я попытался реализовать qnetworksession, но когда происходит отключение сети, не вызываются слоты для таких сигналов, как Closed(), stateChanged(..).   -  person Gokulakrishnan Gopalakrishnan    schedule 30.07.2014
comment
@duDE Я нашел полезным метод networkAccessible() в классе QNetworkAccessManager. Единственная проблема заключается в том, что у нас есть опрос метода, когда он t секунд.   -  person Gokulakrishnan Gopalakrishnan    schedule 30.07.2014


Ответы (2)


Взгляните на класс QNetworkSession: http://doc.qt.digia.com/qtmobility/qnetworksession.html#State-enum

void QNetworkSession::stateChanged ( состояние QNetworkSession::State ) [сигнал]

Этот сигнал испускается всякий раз, когда изменяется состояние сетевого сеанса. Параметр состояния — это новое состояние.

Пример:

// 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();
person Leo Chapiro    schedule 30.07.2014
comment
Спасибо за код. Я реализовал точно такой же, но мои СЛОТЫ не вызываются, когда я отключаю и снова отключаю провод локальной сети. В последнее время я заметил, что stateChanged(...) SLOTs вызывались, когда я выполнял командную строку для отключения сетевой карты (ifconfig en0 down). не уверен, в чем разница между ними. В любом случае спасибо за помощь. - person Gokulakrishnan Gopalakrishnan; 30.07.2014

Вы можете использовать сигнал QNetworkConfigurationManager::onlineStateChanged(bool isOnline), чтобы отслеживать, вы подключены к сети или нет.

person rightaway717    schedule 12.03.2016