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

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

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

Я использую версию Qt 5.3.1, а Mac OS — 10.9.

3

Решение

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

void QNetworkSession :: stateChanged (QNetworkSession :: State 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();
1

Другие решения

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

0

По вопросам рекламы [email protected]