Russian Qt Forum

Qt => Работа с сетью => Тема начата: phpCoder от Январь 26, 2015, 13:42



Название: Синхронный QNetworkAccessManager
Отправлено: phpCoder от Январь 26, 2015, 13:42
Добрый день.
Можно ли как-нибудь сделать синхронную работу QNetworkAccessManager для post-запроса? Т.е. не ждать сигнал finished в другой слот и в нем продолжать работать, а ждать выполнение непосредственно в исходном методе? Не хочу дробить метод класса на две части: часть, которая отправляет запрос и часть, которая принимает его.

Не понятно тогда что и зачем возвращает метод post().


Название: Re: Синхронный QNetworkAccessManager
Отправлено: Bepec от Январь 26, 2015, 13:56
Читайте документацию там разжёвано что оно возвращает.
Да, можно как нибудь сделать синхронную работу QNAMa с помощью EventLoop. Десятки таких тем, даже пара прог моих там валяется с примером.

В поиск :)


Название: Re: Синхронный QNetworkAccessManager
Отправлено: phpCoder от Январь 26, 2015, 14:27
Если бы понятно, не писал бы тут.

На то и форум! Пример в студию.


Название: Re: Синхронный QNetworkAccessManager
Отправлено: ecspertiza от Январь 26, 2015, 14:59
Пример синхронной работы

Код:
    QUrl url(m_url);

    QNetworkRequest request;
    request.setUrl(url);

    QEventLoop loop;

    QNetworkAccessManager manager;

    connect(&manager,SIGNAL(finished(QNetworkReply*)),&loop,SLOT(quit()));

    QNetworkReply *reply = manager.get(request);
    loop.exec();

    QByteArray data = reply->readAll();

post() ровно как и get() возвращает QNetworkReply, по сути в нем хранится вся информация о ответе сервера, ошибки, заголовки, а так же тело. Если вы обрабатываете сигнал finished, то вы получаете QNetworkReply целиком, со всей информацией которая только может быть. Но иногда возникают ситуации когда ответ слишком большой, например при загрузке файла. Тогда лучше использовать метод readyRead класса QNetworkReply(указатель на экземпляр которого вы уже будете иметь) для того что бы ответ читать по частям, ну не гоже все таки, файл в 1ГБ хранить в оперативной памяти. Это как пример, зачем возвращать указатель на этот объект сразу.


Название: Re: Синхронный QNetworkAccessManager
Отправлено: phpCoder от Январь 26, 2015, 16:36
Гениально!


Название: Re: Синхронный QNetworkAccessManager
Отправлено: kibsoft от Январь 26, 2015, 23:07
Стоит еще сразу предупредить, что работа синхронно с QNAM не рекомендуется, т.к. программа может повиснуть.

Код:
QNetworkReply *reply = manager.get(request);
loop.exec();
Зависание может произойти в случае, если сигнал finished() будет выслан до запуска цикла событий (например, когда отсутствует сеть, сигнал будет выслан практически сразу). Такие случаи происходят не часто, но не исключены.
Поэтому, чтобы обезопасить себя, либо делать еще таймер и убивать цикл по таймауту, либо от греха подальше работать асинхронно.