Я пишу приложение для загрузки файла с использованием 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, загрузки застряли навсегда без обратного вызова ошибки. Эти ситуации
- Выньте кабель LAN (Интернет) и быстро вставьте его обратно в течение 20 секунд.
- Переключение с проводного на 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.
Взгляните на класс 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();
Ты можешь использовать QNetworkConfigurationManager :: onlineStateChanged (bool isOnline) сигнал для отслеживания, подключены ли вы к сети или нет.