Закрытие соединений, обрабатываемых QNetworkAccessManager

Итак, я разрабатываю веб-приложение для встроенных устройств, которое использует QNetworkAccessManager для получения информации с веб-сервера. Каждый запрос представляет собой запрос GET, вызывающий страницу PHP с некоторыми параметрами в URL-адресе. Вывод PHP-скрипта — это информация, которую запрашивает мое приложение.

Весь процесс очень прост и может быть упрощен до следующих строк кода:

void fetch() {
    Q_ASSERT(m_reply == 0);
    QUrl url = QUrl("http://subdomain.myserver.com/info.php?param1=1&param2=2");
    m_reply = m_qnam->get(url);

    connect (m_reply, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
    connect (m_reply, SIGNAL(finished()), this, SLOT(onFinished()));
}

void onReadyRead() {
    m_contents.append(m_reply->readAll());
}

void onFinished() {
    m_reply->deleteLater();
    m_reply = 0;
    // do something with the contents
    m_contents.clear();

   // fetch again
   fetch();
}

m_qnam — это экземпляр QNetworkAccessManager, а m_contents — это QByteArray.

Это прекрасно работает, однако я сталкиваюсь с проблемами при попытке выполнить сотни таких запросов, в результате которых я получаю ошибку 429 (слишком много подключений с одного и того же IP) с сервера (Apache). Чтобы оправиться от этого, мне нужно отключиться от Интернета и снова подключиться (что дает мне новый IP-адрес).

Я мог бы увеличить максимальное количество подключений к Apache, однако я считаю, что TCP-соединения должны быть закрыты, как только QNetworkReply будет удален, но, похоже, это не так. Поскольку я загружаю только постоянное количество запросов за раз (это контролируется системой очередей в моем приложении, а QNetworkAccessManager также имеет максимальное количество одновременных загрузок), я не верю, что настройка Apache - это ответ.

Кажется, что соединения TCP не закрываются должным образом.

Итак, мой вопрос:

как убедиться, что каждое соединение с моим сервером закрывается должным образом после завершения загрузки. Должен ли QNetworkAccessManager справиться с этим? Это ошибка? Должен ли я создать свое собственное TCP-соединение с моим сервером и поддерживать определенное количество соединений в течение всего приложения? Если да, то с чего мне начать?

Спасибо, любая помощь будет оценена.

Qt 5.3/OS X/iOS

Примечание: изменил мой вопрос, чтобы он соответствовал комментарию Павла. Активен только один запрос.


person Konstantinos Gaitanis    schedule 07.07.2014    source источник
comment
Как вы храните переменную reply, которая используется в слотах? Если вы сохраните все объекты ответа в одной переменной, вы потеряете все указатели, кроме последнего, поэтому первые ответы не будут прочитаны и удалены. Вы можете использовать слоты QNetworkAccessManager с аргументами QNetworkReply или использовать sender() внутри слотов для получения правильного объекта ответа.   -  person Pavel Strakhov    schedule 07.07.2014


Ответы (1)


Отвечая на мой собственный вопрос: QNetworkAccessManager правильно закрывает все соединения после удаления QNetworkReply или вызова методов abort() или close(). Конечно, это происходит асинхронно.

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

person Konstantinos Gaitanis    schedule 18.09.2014