Russian Qt Forum
Ноябрь 23, 2024, 19:56 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Запрос HTTP заголовков  (Прочитано 5086 раз)
Aso Renji
Гость
« : Май 12, 2012, 01:26 »

Стоит задача получить заголовки страницы. В крайнем случае получить информацию о том, что вместо заголовков сервер присылает фигу. Для этого создается QNetworkAccessManager, у которого пинается head. Потом программа ловит сигнал finished от QNetworkAccessManager и сигнал error от QNetworkReply. Так вот, при попытке обратиться к http://www.miracle-train.tv/ ни один из слотов вообще не вызывается (да, error тоже не ловится). Хотя, если стучаться на какой ни будь там http://ya.ru/ - все нормально. Что делать и кто виноват?

И, собственно, тестовый код максимально урезанный для локализации глюка:
Код:
class browser:public QObject
{
    Q_OBJECT
public:
    browser(QObject*parent):QObject(parent),NAM(this)
    {
        QObject::connect(&NAM,SIGNAL(finished(QNetworkReply*)),this,SLOT(loadFinished(QNetworkReply*)));
        QNetworkRequest request(QUrl("http://www.miracle-train.tv/"));
        QNetworkReply*reply=NAM.head(request);
        QObject::connect(reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(error(QNetworkReply::NetworkError)));
    }
private:
    QNetworkAccessManager NAM;
private slots:
    void error(QNetworkReply::NetworkError code)
    {
        qDebug()<<"error";
    }
    void loadFinished(QNetworkReply*reply)
    {
        qDebug()<<"ok";
        reply->deleteLater();
    }
};
Выполняется под Дебианом, который в свою очередь работает под VirtualBox. Остальные приложения работающие с сетью в глюках незамечены.
Записан
fuCtor
Гость
« Ответ #1 : Май 12, 2012, 06:34 »

Проблема в сервере, на запрос HEAD он тупо ничего не отдает и просто висит. Проверил через Fiddler под Windows.
Записан
Aso Renji
Гость
« Ответ #2 : Май 12, 2012, 13:28 »

Ок, что тогда в этой ситуации делать? Убивать зависшее соединение руками несколько неудобно. Где выставить таймаут для ожидания ответа сервера я тоже не нашел. А если соединение предоставить само себе, оно так и висит до бесконечности в ожидании ответа сервера, который никогда не будет отправлен.
Записан
SimpleSunny
Гость
« Ответ #3 : Май 13, 2012, 13:40 »

Создайте таймер.
На сигнал timeout() reply->abort(); и прийдет сигнал error.
Если запрос закончился раньше, то останавливайте его.
Еще на readyRead() можно поставить restart таймера.
Записан
Aso Renji
Гость
« Ответ #4 : Май 13, 2012, 14:27 »

Тогда следующий вопрос - можно ли как-то скрестить таймер и QNetworkReply, на случай если соединений больше одного и каждому свой таймер нужен? Я уже пробовал создавать наследника QNetworkAccessManager, перегружать в нем createRequest и возвращать потомка QNetworkReply с таймером. Но выяснил что в QNetworkReply не реализован abort (он pure virtual). А делать таймер отдельным объектом, это все же некоторый дополнительный геморрой. Хотя и не смертельный.
Записан
fuCtor
Гость
« Ответ #5 : Май 20, 2012, 08:33 »

Если соединений много, то имеет смысл сделать такую схему:
1) завести один таймер и выставить в нем интервал в 1с.
2) т.к. QNetworkReply потомок QObject, то в нем можно хранить динамические свойства => помещаем в него свойство, которое назовем условно TTL.
3) если нужно централизовать все это то наследуемся от QNetworkAccessManager и храним этот таймер там.
4) при создании запроса, запоминаем где-то QNetworkReply, лучше через связку QPointer< QNetworkReply >, и инициализируем наше динамическое свойство, например выставляем в 5с
5) при срабатывании таймера пробегаем по всем сохраненным объектам и уменьшаем TTL (если есть) на единицу, если TTL = 0, то убиваем его ( вызываем close() )
6) если список пуст, таймер можно остановить, при появлении новых запросов запустить снова.
7) если ответ получить, свойство TTL лучше удалить (присвоив ему QVariant()) во избежание удаления по таймеру.

для надежности можно прицепить с сигналу destroyed слот, чтобы удаленный объект убрать из списка.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.048 секунд. Запросов: 20.