Russian Qt Forum

Qt => Общие вопросы => Тема начата: kadr от Январь 26, 2010, 09:34



Название: QHttp
Отправлено: kadr от Январь 26, 2010, 09:34
Привет всем, народ есть задачка, надо отправить файл по http протоколу, методом post :
Исходя из справки:
Код:
http.setHost("http://192.168.1.223");
http.post("/farma/file_load.php", &file_tr);
Но ничего не получается!
Содержимое файла file_load.php
Код:
<?php 
// Загрузка файлов на сервер
// Если register_globals=Off

// Если upload файла
/*if(isset($_FILES["myfile"]))
{ */
$myfile = $_FILES["myfile"]["tmp_name"];
$myfile_name = $_FILES["myfile"]["name"];
$myfile_size = $_FILES["myfile"]["size"];
$myfile_type = $_FILES["myfile"]["type"];
$error_flag = $_FILES["myfile"]["error"];

// Если ошибок не было
if($error_flag == 0)
{
print("Имя файла на нашем сервере (во время запроса): ".$myfile."<br>");
print("Имя файла на компьютере пользователя: ".$myfile_name."<br>");
print("MIME-тип файла: ".$myfile_type."<br>");
print("Размер файла: ".$myfile_size."<br><br>");

$catalog = "/work/one/transfer/med_uch/".$myfile_name;
print("Каталог файла: ".$catalog."<br>");
copy($myfile, $catalog);
// Получаем содержимое файла
$fp = fopen($myfile,"r");
$content = fread($fp, filesize($myfile));
fclose($fp);

// Вывод содержимого файла
//print($content);

//} // end of if 2
} // end of if 1
?>
Если делать чере веб интерфейс:
Код:
<HTML>
<TITLE>Post metod</TITLE>
<BODY>
<FORM ENCTYPE="multipart/form-data" ACTION="file_load.php" METHOD=POST>
Paste the file: <INPUT NAME="myfile" TYPE="file"><br>
<p><input type="submit"></p>
</form>
</BODY>
</HTML>
то нормально все работает, файлик отправляется куда нужно, а через прогу не хочет!


Название: Re: QHttp
Отправлено: SimpleSunny от Январь 26, 2010, 10:05
Необходимо переходить на QNetworkAccessManager, так как QHttp больше не поддерживается.

А если по вопросу, то где-то так:
Код:
    QHttpRequestHeader header;
    QHttp http;
...
    QByteArray boundary("*ANT34ONN5dbAS56uTA*");
    QByteArray data("MY_FILE");
    //запрос
    QByteArray byte;

    byte.append("--").append(boundary).append("\r\nContent-Disposition: form-data; name=\"method\"\r\n\r\n");
    byte.append("post\r\n--").append(boundary).append("\r\n");
    byte.append("Content-Disposition: form-data; name=\"file\"; filename=\"all.jpg\"\r\n");
    byte.append("Content-Type: image/jpeg\r\n\r\n");
    byte.append(data).append("\r\n--").append(boundary).append("--");

    header.setValue("Content-Type", QString("multipart/form-data; boundary=").append(boundary));

    http.request(header, byte);


Название: Re: QHttp
Отправлено: Sahab от Январь 26, 2010, 10:28
"This class is obsolete. It is provided to keep old source code working. We strongly advise against using it in new code."
Вообще-то поддерживается... хоть и рекомендуют пользоваться новым


Название: Re: QHttp
Отправлено: kibsoft от Январь 26, 2010, 10:39
Цитировать
"This class is obsolete. It is provided to keep old source code working. We strongly advise against using it in new code."
Вообще-то поддерживается... хоть и рекомендуют пользоваться новым
Вообще-то он предоставляется, но больше не поддерживается :)


Название: Re: QHttp
Отправлено: kadr от Январь 26, 2010, 10:42
Хорошо, я внял совету и полазил в интернете в поисках описалова по QNetworkAccessManager, кое что нашел:
Код:
  QNetworkAccessManager manager;
    QUrl apiUrl;
    QFile file_tr(seting.value("id_uch").toString().trimmed()+"_nomenklatura.csv");
    if (file_tr.open(QIODevice::ReadOnly))
    {
        apiUrl = "http://192.168.1.223/farma/file_load.php";
        requestString = "method=getQuote&format=csv";
        QNetworkRequest request(apiUrl);
        reply = manager.post(request, requestString);
        connect(reply, SIGNAL(finished()),this, SLOT(getReplyFinished()));
        connect(reply, SIGNAL(readyRead()), this, SLOT(readyReadReply()));

    }
void nomkl_num::getReplyFinished()
{
    reply->deleteLater();
}

void nomkl_num::readyReadReply()
{
    QString answer = QString::fromUtf8(reply->readAll());
}
Проверил дебагером, соединения вообще не происходит, скажите, как можно передать файл по http протоколу!


Название: Re: QHttp
Отправлено: kibsoft от Январь 26, 2010, 10:52
Код:
qDebug()<<connect(reply, SIGNAL(finished()),this, SLOT(getReplyFinished()));
qDebug()<<connect(reply, SIGNAL(readyRead()), this, SLOT(readyReadReply()));
А ты так проверь есть соединение или нет..если будет true, то просто сигналы не высылаются..а следовательно не выполняется условие, при котором они должны высылаться..


Название: Re: QHttp
Отправлено: Sahab от Январь 26, 2010, 10:53
($QTDIR)\examples\network\downloadmanager\


Название: Re: QHttp
Отправлено: kadr от Январь 26, 2010, 10:55
Код:
qDebug()<<connect(reply, SIGNAL(finished()),this, SLOT(getReplyFinished()));
qDebug()<<connect(reply, SIGNAL(readyRead()), this, SLOT(readyReadReply()));
А ты так проверь есть соединение или нет..если будет true, то просто сигналы не высылаются..а следовательно не выполняется условие, при котором они должны высылаться..
Да вышло true!


Название: Re: QHttp
Отправлено: kadr от Январь 26, 2010, 11:05
($QTDIR)\examples\network\downloadmanager\
В целом тоже самое что и у меня!


Название: Re: QHttp
Отправлено: kadr от Январь 26, 2010, 11:10
Дело в том, что там описано как скачать что, от куда-то, а мне надо передать файл!


Название: Re: QHttp
Отправлено: Sahab от Январь 26, 2010, 11:21
а где в Вашем коде идет передача содержимого файла?


Название: Re: QHttp
Отправлено: Sahab от Январь 26, 2010, 11:23
QNetworkReply * QNetworkAccessManager::post ( const QNetworkRequest & request, const QByteArray & data )
This is an overloaded function.

Sends the contents of the data byte array to the destination specified by request.
 
+

http://ru.wikipedia.org/wiki/HTTP


Название: Re: QHttp
Отправлено: kadr от Январь 26, 2010, 11:36
 apiUrl = "http://192.168.1.223/farma/file_load.php";
        QNetworkRequest request(apiUrl);
        reply = manager.post(request, &myfile);
        qDebug()<< connect(reply, SIGNAL(finished()),this, SLOT(getReplyFinished()));
        qDebug()<< connect(reply, SIGNAL(readyRead()), this, SLOT(readyReadReply()));
        qDebug()<< reply->errorString();


Название: Re: QHttp
Отправлено: voronElf от Январь 26, 2010, 11:40
По теме SimpleSunny +1

подход все по протоколу, а через QHttp или через QMetworkmanager отсылать разницы нету, кроме того что QHttp нестабилен )))

Для kadr, в коде с QNetworkAccessManager непонятно немного, видно QNetworkAccessManager создается на стеке, но сигналы со слотами связываются по this. Можт в этом и трабла, что ответов сервака не получаешь. Нужно чтобы менеджер существовал все время пока ходят запросы и приходят-отрабатываются ответы http.

У меня была подобная задача  давненько уже, жаль совета подобного коду от SimpleSunny не увидел в нужное время а сделал так: брал данные файла, совал в пост без изменений, с Content-type: application/octet-stream  (чтоб разбора пост на сервере не было перед выполнением скрипта-приемщика). Скрипт-приемщик писал сам, брал $_HTTP_RAW_POST_DATA и все нормально проканывало.

P.S. можт потому что немного не по протоколу поступал, в Qt 4.5.2 при такой отправке через прокси запрос не проходил до сервака, а без прокси нормально ходил.


Название: Re: QHttp
Отправлено: Sahab от Январь 26, 2010, 11:52
а это к чему было?
...
requestString = "method=getQuote&format=csv";
...

и м.б.
QNetworkAccessManager *manager = new QNetworkAccessManager(this); ?


Название: Re: QHttp
Отправлено: kadr от Январь 26, 2010, 11:55
а это к чему было?
...
requestString = "method=getQuote&format=csv";
...
Это я в нете пример нашел! Так и написал, попробовал!


Название: Re: QHttp
Отправлено: SimpleSunny от Январь 26, 2010, 12:08
Тут написано как именно отправляют в таком случае файлы, есть даже ссылка на RFC.
http://www.intuit.ru/department/internet/html/17/11.html

А если поиском по форуму "multipart/form-data", то тоже можно найти множество примеров.


Название: Re: QHttp
Отправлено: kadr от Январь 29, 2010, 08:48
Народ, как скачать много файлов с сервера, у меня получатся скачать только один первый!
Код:
void nomkl_num::getfiles()
{
    int i = 0;

    QStringList st;
    QString str,file_str;
    str = http_sp->readAll();
    st = str.split("\n");
    while (i !=  st.count())
    {
        file_str = st.value(i);
        if (file_str != "..")
        {
            if (file_str != ".")
            {
                if (file_str != "")
                {
                    sp.append(file_str);
                }
            }           
        }
        i++;
    }

   i = 0;

   while(i != sp.count())
   {
        QHttpRequestHeader header("GET", "/farma/zagruz/"+sp.value(i));
        header.setValue("Host", "192.168.1.223");
        header.setValue("Content-type", "multipart/form-data; boundary=1BEF0A57BE110FD467A\r\n");
        header.setValue( "User-Agent", "User Agent");
        header.setContentType("application/x-www-form-urlencoded");
        http_save = new QHttp(this);
        connect(http_save, SIGNAL(done(bool)), this, SLOT(savefiles()));
        http_save->setHost("192.168.1.223");
        http_save->request(header);
        i++;
    }
}

void nomkl_num::savefiles()
{
    QDir dir;
    bool ok;

    QFile file("files/"+sp.value(zakaz));
    zakaz++;
    file.open(QIODevice::WriteOnly);
    file.write(http_save->readAll().trimmed());
    file.close(); 
}


Название: Re: QHttp
Отправлено: kadr от Февраль 01, 2010, 12:30
Народ, ну подскажите, как мне лучше скачать файли с сервака, посоветуйте чем, qhttp, или может лучше qftp, пожалуста! Изрыл весь инет, перепробовал все что там нашел, все равно не получается!


Название: Re: QHttp
Отправлено: Alex Custov от Февраль 02, 2010, 00:33
Ты сначала разбери свой код, например, что делает этот слот. Объясни так подробно как сможешь.

Код
C++ (Qt)
void nomkl_num::savefiles()
{
   QDir dir;
   bool ok;
 
   QFile file("files/"+sp.value(zakaz));
   zakaz++;
   file.open(QIODevice::WriteOnly);
   file.write(http_save->readAll().trimmed());
   file.close();  
}
 


Название: Re: QHttp
Отправлено: kadr от Февраль 02, 2010, 11:18
Ты сначала разбери свой код, например, что делает этот слот. Объясни так подробно как сможешь.

Код
C++ (Qt)
void nomkl_num::savefiles()
{
   QDir dir;
   bool ok;
 
   QFile file("files/"+sp.value(zakaz));
   zakaz++;
   file.open(QIODevice::WriteOnly);
   file.write(http_save->readAll().trimmed());
   file.close();  
}
 
В этом слоте я пытался сохранять содержимое http_save в локальную копию файла. Одним словом при старте программы у меня происходит чтение всех файлов на серваке, для этого использую файлик написанный на php, который лежит на сервере spisok_files.php:
Код:
QHttpRequestHeader header("GET", "/farma/spisok_files.php");
    header.setValue("Host", "192.168.1.223");
    header.setValue("Content-type", "multipart/form-data; boundary=1BEF0A57BE110FD467A\r\n");
    header.setValue( "User-Agent", "User Agent");
    header.setContentType("application/x-www-form-urlencoded");
    http_sp = new QHttp(this);
    connect(http_sp, SIGNAL(done(bool)), this, SLOT(getfiles()));
    http_sp->setHost("192.168.1.223");
    http_sp->request(header);

Происходит конект со слотом getfiles(), в котором в дальнейшем происходит соединение со слотом savefiles():
Код:
int i = 0;
    QStringList st;
    QString str,file_str;
    str = http_sp->readAll();
    st = str.split("\n");
    while (i !=  st.count())
    {
        file_str = st.value(i);
        if (file_str != "..")
        {
            if (file_str != ".")
            {
                if (file_str != "")
                {
                    sp.append(file_str);
                }
            }            
        }
        i++;
    }

   i = 0;

while(i != sp.count())
   {
        QHttpRequestHeader header("GET", "/farma/zagruz/"+sp.value(i));
        header.setValue("Host", "192.168.1.223");
        header.setValue("Content-type", "multipart/form-data; boundary=1BEF0A57BE110FD467A\r\n");
        header.setValue( "User-Agent", "User Agent");
        header.setContentType("application/x-www-form-urlencoded");
        http_save = new QHttp(this);
        connect(http_save, SIGNAL(done(bool)), this, SLOT(savefiles()));
        http_save->setHost("192.168.1.223");
        http_save->request(header);
    }
То есть, читается общее количество файлов и пытаюсь в цикле сохранить содержимое всех файлов на серваке в отдельные файлы на локальном компьютер. Но получается, что сохраняется только первый файл!
Скажите, вообще есть смысл использовать http протокол для скачивания файлов с сервера, общим количеством в 30 - 33 файла, или есть смысл использовать что то иное, например ftp протокол, или еще что то?  
Основная задача: тупо скачать все файлы с сервака на локальный компьютер!


Название: Re: QHttp
Отправлено: Alex Custov от Февраль 02, 2010, 14:54
В этом слоте я пытался сохранять содержимое http_save в локальную копию файла. Одним словом при старте программы у меня происходит чтение всех файлов на серваке, для этого использую файлик написанный на php, который лежит на сервере spisok_files.php:

То есть, читается общее количество файлов и пытаюсь в цикле сохранить содержимое всех файлов на серваке в отдельные файлы на локальном компьютер. Но получается, что сохраняется только первый файл!
Скажите, вообще есть смысл использовать http протокол для скачивания файлов с сервера, общим количеством в 30 - 33 файла, или есть смысл использовать что то иное, например ftp протокол, или еще что то?  
Основная задача: тупо скачать все файлы с сервака на локальный компьютер!

Ты так и не увидел ничего зазороного? До этого ты в цикле делаешь

Код
C++ (Qt)
http_save = new QHttp(this);
У тебя создаётся например 20 QHttp объектов, завязанных на один слот. А в слоте ты читаешь этот указатель

Код
C++ (Qt)
file.write(http_save->readAll().trimmed());
 

И который же из 20-ти QHttp объектов тут будет всё время вызываться? Самый последний созданный! Слот как минимум надо переделать в

Код
C++ (Qt)
void nomkl_num::savefiles(bool err)
{
   if(err)
   {
       qDebug("Error occured");
       return;
   }
 
   QHttp *http = qobject_cast<QHttp *>(sender());
 
   if(!http)
   {
       qDebug("Cannot cast to QHttp");
       return;
   }
 
   // если zakaz == 1, это не означает что скачался файл sp.value(1)
   QFile file("files/"+sp.value(zakaz));
 
   zakaz++;
 
   if(!file.open(QIODevice::WriteOnly))
   {
       qDebug("Cannot open file for writing");
       return;
   }
 
   file.write(http->readAll().trimmed());
   file.close();  
}
 

Косяков там ещё хватает...


Название: Re: QHttp
Отправлено: kadr от Февраль 03, 2010, 14:09
Переделал, сделал так как написали, он создает все файлы на локальном компе, но в файлах вот что:

Bad Request

Your browser sent a request that this server could not understand.

------------------------------------
Apache/2.2.3 (CentOS) Server at 192.168.1.223 Port 80
во всех!


Название: Re: QHttp
Отправлено: kadr от Февраль 03, 2010, 14:47
Никак не вкурю, как скачивать файлы с http сервака, начну сначала по этапно:
1. По нажатию на кнопку происходить следущее:
Код:
void nomkl_num::on_get_files_triggered()
{
    QHttpRequestHeader header("GET", "/farma/spisok_files.php");
    header.setValue("Host", "192.168.1.223");
    header.setValue("Content-type", "multipart/form-data; boundary=1BEF0A57BE110FD467A\r\n");
    header.setValue( "User-Agent", "User Agent");
    header.setContentType("application/x-www-form-urlencoded");
    http_sp = new QHttp(this);
    connect(http_sp, SIGNAL(done(bool)), this, SLOT(getfiles()));
    http_sp->setHost("192.168.1.223");
    http_sp->request(header);
}
2. Затем из через connect переходим к следующему слоту getfiles(), в котором я получаю список файлов на серваке, и запихиваю этот список в переменную, а также в этом слоте, в цикле происходит считивание содержимого каждого файла по отдельности и передача этого содержимого в следующий слот savefiles(bool):
Код:
void nomkl_num::getfiles()
{
    int i = 0;    
    QStringList st;
    QString str,file_str;
    str = http_sp->readAll();
    st = str.split("\n");
    while (i !=  st.count())
    {
        file_str = st.value(i);
        if (file_str != "..")
        {
            if (file_str != ".")
            {
                if (file_str != "")
                {
                    sp.append(file_str);
                }
            }
        }
        i++;
    }
   i = 0;
   while (i != sp.count())
   {
        QHttpRequestHeader header_s("GET", "farma/"+sp.value(i));
        header_s.setValue("Host", "192.168.1.223");
        header_s.setValue("Content-type", "multipart/form-data; boundary=1BEF0A57BE110FD467A\r\n");
        header_s.setValue( "User-Agent", "User Agent");
        header_s.setContentType("application/x-www-form-urlencoded");
        http = new QHttp(this);
        http->setHost("192.168.1.223");
        connect(http, SIGNAL(done(bool)), this, SLOT(savefiles(bool)));
        http->request(header_s);
        i++;
   }
}
далее слот savefiles(bool err)
Код:
void nomkl_num::savefiles(bool err)
{
    if(err)
        {
            qDebug() << "Error occured";
            return;
        }

        QHttp *http = qobject_cast<QHttp *>(sender());

        if(!http)
        {
            qDebug() << "Cannot cast to QHttp";
            return;
        }

        // если zakaz == 1, это не означает что скачался файл sp.value(1)

        QFile file("files/"+sp.value(zakaz));

        zakaz++;

        if(!file.open(QIODevice::WriteOnly))
        {
            qDebug() << "Cannot open file for writing";
            return;
        }

        file.write(http->readAll().trimmed());
        file.close();
}
Вот впринципе и все, и на выходе получаю, что файлы как бы скачаны, то есть названия у всех правильные, но содержимое всех файлов одинаковое и вот что там написано:
Bad Request
Your browser sent a request that this server could not understand.
------------------------------------
Apache/2.2.3 (CentOS) Server at 192.168.1.223 Port 80


Название: Re: QHttp
Отправлено: Alex Custov от Февраль 03, 2010, 18:41
Никак не вкурю, как скачивать файлы с http сервака, начну сначала по этапно:

Поэтапно это делается не так. Надо написать сначала самый простой пример, который скачивает один какой-то строго заданный файл, и разобраться сначала с ним. Потом уже качать список файлов. Сейчас сервер тебе говорит что ты передал неправильные параметры в запросе. Сделай запрос браузером, и поснифай что он отправляет и что отвечает сервер.


Название: Re: QHttp
Отправлено: kadr от Февраль 04, 2010, 09:35
Блин, я не пойму никак, почему вот этот запрос отрабатывает как надо:
Код:
void nomkl_num::on_get_files_triggered()
{
    QHttpRequestHeader header("GET", "/farma/spisok_files.php");
    header.setValue("Host", "192.168.1.223");
    header.setValue("Content-type", "multipart/form-data; boundary=1BEF0A57BE110FD467A\r\n");
    header.setValue( "User-Agent", "User Agent");
    header.setContentType("application/x-www-form-urlencoded");
    http_sp = new QHttp(this);
    connect(http_sp, SIGNAL(done(bool)), this, SLOT(getfiles()));
    http_sp->setHost("192.168.1.223");
    http_sp->request(header);
}
возвращает мне содержимое страницы spisok_files.php, а этот не срабатывает:
Код:
        QHttpRequestHeader header("GET", "farma/zagruzup00000000001.dlb");
        header.setValue("Host", "192.168.1.223");
        header.setValue("Content-type", "multipart/form-data; boundary=1BEF0A57BE110FD467A\r\n");
        header.setValue( "User-Agent", "User Agent");
        header.setContentType("application/x-www-form-urlencoded");
        http = new QHttp(this);
        connect(http, SIGNAL(done(bool)), this, SLOT(savefiles(bool)));
        http->setHost("192.168.1.223");        
        http->request(header);
не работает, в чем разница то, все тоже самое, только прошу отобразить содержимое файла!


Название: Re: QHttp
Отправлено: SimpleSunny от Февраль 04, 2010, 11:16
Попробуй добавить слеш
QHttpRequestHeader header("GET", "/farma/zagruzup00000000001.dlb");


Название: Re: QHttp
Отправлено: kadr от Февраль 04, 2010, 12:01
Пробывал, ругается, что такого файла вообще нет! И вообще я думаю что резонее использовать QNetworkAccessManager.
Вот код:
Код:
void nomkl_num::on_get_files_triggered()//нажатие кнопки в меню - загрузить
{


        QNetworkRequest request;  // Формируем запрос
        request.setUrl(QUrl("192.168.1.223/farma/zotchet.php"));
        QNetworkAccessManager manager;
        manager.moveToThread(QApplication::instance()->thread());
        reply = manager.get(request); //Отправляем запрос
        reply->moveToThread(QApplication::instance()->thread());
        connect(&manager, SIGNAL(finished(QNetworkReply*)),this, SLOT(replyFinished(QNetworkReply*)));
        connect(reply,SIGNAL(readyRead()),this,SLOT(readyRead()));


}

//------------------------------------------------------------------------------------------------------------------------------------------------------

void nomkl_num::readyRead()
{
    file.setFileName("files/123.txt");
    file.open(QIODevice::WriteOnly);

    qDebug() << reply->readAll();
    file.write(reply->readAll());

}

void nomkl_num::replyFinished(QNetworkReply *)
{
    if (reply->error())
       {
           qDebug() << "error download" << reply->errorString();
           QCoreApplication::quit();
       }else
       {
           qDebug() << "download complete";
           file.close();
           QCoreApplication::quit();
       }
}
и все равно не работает.


Название: Re: QHttp
Отправлено: BRE от Февраль 04, 2010, 13:31
А как он может работать, если
QNetworkAccessManager manager;

определен на стеке и соответственно разрушается при выходе из метода?  :)


Название: Re: QHttp
Отправлено: kadr от Февраль 04, 2010, 13:38
о Спасибо!


Название: Re: QHttp
Отправлено: kadr от Февраль 04, 2010, 15:06
Но это еще не все, скачать один фаилик у меня получилось, вопрос, как мне скачать много файлов, загоняю в цикл:
Код:
while(i != sp.count())
    {
        file.setFileName("files/"+sp.value(i));
        file.open(QIODevice::WriteOnly);
        request.setUrl(QUrl("http://192.168.1.223/farma/zagruz/"+sp.value(i)));

        manager.moveToThread(QApplication::instance()->thread());
        reply = manager.get(request); //Отправляем запрос
        reply->moveToThread(QApplication::instance()->thread());
        connect(&manager, SIGNAL(finished(QNetworkReply*)),this, SLOT(replyFinished(QNetworkReply*)));
        connect(reply,SIGNAL(readyRead()),this,SLOT(readyRead()));
        i++;
    }
создаются файли и все пустые! В QStringList sp у меня храняться именя всех файлов на серваке! Полученные при загрузке программы!


Название: Re: QHttp
Отправлено: crossly от Февраль 04, 2010, 15:34
а как с слот readyRead определяет в какой файл писать??


Название: Re: QHttp
Отправлено: kadr от Февраль 04, 2010, 15:40
а как с слот readyRead определяет в какой файл писать??
file.setFileName("files/"+sp.value(i));
file.open(QIODevice::WriteOnly);


Название: Re: QHttp
Отправлено: crossly от Февраль 04, 2010, 15:45
ладно... по другому... как ты определяешь где заканчиваются данные одного файла и начинаются другого.... я не работал accessmanager'ом .... но что то мне подсказывает что работает это дело в асинхронном режиме...


Название: Re: QHttp
Отправлено: kadr от Февраль 04, 2010, 18:50
ладно... по другому... как ты определяешь где заканчиваются данные одного файла и начинаются другого.... я не работал accessmanager'ом .... но что то мне подсказывает что работает это дело в асинхронном режиме...

Вот за этим я суда и обратился, у меня получается скачать только 1 файл, а мне надо много, кто в курсе как это осуществить, помогите!


Название: Re: QHttp
Отправлено: voronElf от Февраль 05, 2010, 07:05
ну если проблема только в том, чтобы разделить файлы, а само скачивание файла реализовано, тогда можно предложить 2 подхода:

1. Для случая если ты из одного цикла запускаешь кучу закачек на все файлы, тогда надо формировать в памяти структуру соответствия экземпляра (адреса) QNetworkReply с именем файла. Например QMap<QNetworkReply*, QString> как внутренняя переменная класса (конечно не на стеке ее делать). Слот-приемщик данных по адресу QNetworkReply* будет определять в какой файл писать данные.

2. Качаешь файлы один за другим. Запускаешь скачивание первого файла, в слоте получения данных пишешь данные в текущий файл. Здесь же в слоте запускаешь скачивание второго файла и так далее пока список файлов не кончится.


Название: Re: QHttp
Отправлено: kadr от Февраль 05, 2010, 13:34
ну если проблема только в том, чтобы разделить файлы, а само скачивание файла реализовано, тогда можно предложить 2 подхода:

2. Качаешь файлы один за другим. Запускаешь скачивание первого файла, в слоте получения данных пишешь данные в текущий файл. Здесь же в слоте запускаешь скачивание второго файла и так далее пока список файлов не кончится.
Вот про второй можно маленько поподробнее! Как запустить скачивание второго и последующих файлов, не представляю!
Код:
void nomkl_num::readyRead()
{       
    file.setFileName("files/"+sp.value(zakaz));
    file.open(QIODevice::WriteOnly);
    file.write(reply->readAll());
    zakaz++;
}


Название: Re: QHttp
Отправлено: voronElf от Февраль 05, 2010, 14:30
я делал так: отдельный метод класса (назовем send() ), отправляющий запрос на очередной файл. В слоте повешенном на сигнал finished в самом конце после всех обработок делаю вызов send()


Название: Re: QHttp
Отправлено: kadr от Февраль 08, 2010, 16:16
Попробовал сделать так, выскакивает ошибка
Код:
void  nomkl_num::send_save_file()
{
        request.setUrl(QUrl("http://192.168.1.223/farma/zagruz/"+sp.value(zakaz)));
        manager.moveToThread(QApplication::instance()->thread());
        reply = manager.get(request); //Отправляем запрос
        reply->moveToThread(QApplication::instance()->thread());
        connect(reply,SIGNAL(readyRead()),this,SLOT(readyRead()));
        connect(&manager, SIGNAL(finished(QNetworkReply*)),this, SLOT(replyFinished(QNetworkReply*)));
}

void nomkl_num::readyRead()
{      
    QStringList sl;
    sl = reply->url().path().split("/");
    file.setFileName("files/"+sl.value(3));
    file.open(QIODevice::WriteOnly);
    file.write(reply->readAll());  
  
}

void nomkl_num::replyFinished(QNetworkReply *)
{
    if (reply->error())
       {
        QMessageBox::information(this,tr("error download"),reply->errorString(),QMessageBox::Ok);

       }
    else
       {
           //QMessageBox::information(this,tr("Сообщение"),tr("Загрузка завершена успешно"),QMessageBox::Ok);
           qDebug() << "download complete";
           file.close();
           zakaz++;
           send_save_file();
       }
}
После того как скачал 4 файла, не останавлиывается, и программа зависает, от того что он уходит в бесконечность, и почему то 1 файл не качает, сохраняет 3 из 4.


Название: Re: QHttp
Отправлено: voronElf от Февраль 09, 2010, 06:33
несколько моих имхо по коду:

1. зачем перемещать объекты в треды какие-то, запрос итак асинхронно выполняется в другом треде, это скрыто в реализации managera.

2. request у меня локальная переменная на стеке функции (ну тут большой разницы не должно быть).

3. коннект сигнала finished от manager достаточно сделать один раз (в конструкторе), а не при каждом вызове send ()

4. открывать файл в одном слоте и закрывать в другом не есть хорошо (файл может и не закрыться), мне проще reply->readAll() делать в finished  и писать в файл в этом же слоте.


Ну а теперь почему не останавливается - в коде не вижу условия на остановку процесса. Получается же своего рода рекурсия: 1-я функция порождает вызов второй, вторая в свою очередь явно вызывает первую. Если не прописать явного условия выхода - конечно бесконечный цикл получим. А условие выхода такое: в функции send() если список файлов закончился, то не отправлять очередной запрос, а возврат. Список файлов я так понимаю это sp, кстати имя скачанного файла как то эстетичнее из этого списка и брать (текущую позицию знаем), а не из url вырезать.

PS: поборешь зависание, там можт и видно станет, почему не все файлы скачивает


Название: Re: QHttp
Отправлено: kadr от Февраль 09, 2010, 15:12
Спасибо, вреде сделал, надо было этот send(), в моем случае send_save_file(), не на finished вешать, а на readyRead().
Код:
QStringList sl;
    sl = reply->url().path().split("/");
    file.setFileName("files/"+sl.value(3));
    file.open(QIODevice::WriteOnly);
    file.write(reply->readAll());
    file.close();
    sl.clear();
    zakaz++;
    kol++;
    send_save_file();

   if (kol == sp.count())
    {
       load();
    }


Название: Re: QHttp
Отправлено: voronElf от Февраль 10, 2010, 06:29
можно и все на readyRead повешать, можно на finished. Я предпочел 2-й вариант, из-за того что reply нужно удалять ручками. Тема поднималась тут (http://www.prog.org.ru/topic_11717_0.html)