Как прочитать содержимое изображения из ответа HTTP-сервера с помощью Poco C++?

Я пишу HTTP-клиент на С++ с Poco, и возникает ситуация, когда сервер отправляет ответ с содержимым изображения jpeg (в байтах). Мне нужно, чтобы клиент обработал ответ и сгенерировал файл изображения jpg из этих байтов.

Я искал в библиотеке Poco подходящие функции, но ничего не нашел. Кажется, что единственный способ сделать это вручную.

Это часть моего кода. Он принимает ответ и заставляет входной поток начинаться с начала содержимого изображения.

    /* Get response */
    HTTPResponse res;
    cout << res.getStatus() << " " << res.getReason() << endl;

    istream &is = session.receiveResponse(res);

    /* Download the image from the server */
    char *s = NULL;
    int length;
    std::string slength;

    for (;;) {
        is.getline(s, '\n');
        string line(s);

        if (line.find("Content-Length:") < 0)
            continue;

        slength = line.substr(15);
        slength = trim(slength);
        stringstream(slength) >> length;

        break;
    }

    /* Make `is` point to the beginning of the image content */
    is.getline(s, '\n');

Как действовать?


person Ori Popowski    schedule 14.01.2012    source источник


Ответы (2)


Ниже приведен код для получения тела ответа в виде строки. Вы также можете записать его прямо в файл с помощью ofstream (см. ниже).

    #include <iostream>
    #include <sstream>
    #include <string>

    #include <Poco/Net/HTTPClientSession.h>
    #include <Poco/Net/HTTPRequest.h>
    #include <Poco/Net/HTTPResponse.h>
    #include <Poco/Net/Context.h>
    #include <Poco/Net/SSLManager.h>
    #include <Poco/StreamCopier.h>
    #include <Poco/Path.h>
    #include <Poco/URI.h>
    #include <Poco/Exception.h>


    ostringstream out_string_stream;

    // send request
    HTTPRequest request( HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1 );
    session.sendRequest( request );

    // get response
    HTTPResponse response;
    cout << response.getStatus() << " " << response.getReason() << endl;

    // print response
    istream &is = session.receiveResponse( response );
    StreamCopier::copyStream( is, out_string_stream );

    string response_body = out_string_stream.str();

Чтобы писать непосредственно в файл, вы можете использовать это:

    // print response
    istream &is = session->receiveResponse( response );

    ofstream outfile;
    outfile.open( "myfile.jpg" );

    StreamCopier::copyStream( is, outfile );

    outfile.close();
person Homer6    schedule 24.07.2012
comment
Мне пришлось написать в двоичном формате, чтобы это работало правильно: outfile.open(myfile.jpg, ios_base::binary); - person ryatkins; 16.09.2013
comment
@ryatkins ты на винде? - person Homer6; 16.09.2013
comment
Да, на винде. В противном случае мои загрузки изображений были повреждены. Как вы думаете, это особенность Windows? - person ryatkins; 16.09.2013

Не изобретайте велосипед. Правильно выполнять HTTP сложно. Используйте существующую библиотеку, такую ​​как libcurl.

person Julian Reschke    schedule 14.01.2012
comment
Я не изобретаю велосипед, я использую Poco. - person Ori Popowski; 14.01.2012
comment
Лейф, если Poco содержит библиотеку HTTP, и вы будете ее использовать, вам не придется анализировать Content-Length. - person Julian Reschke; 15.01.2012
comment
Если вы знаете метод нахождения Content-Length с помощью Poco без разбора вручную, то почему бы вам не сказать мне, что это такое? - person Ori Popowski; 18.01.2012
comment
Потому что я не знаю Поко. Но определение длины полезной нагрузки — это одна из вещей, которые HTTP-библиотека делает за вас, в противном случае это не HTTP-библиотека (обратите внимание, что это может означать, что библиотека не знает, и вам нужно прочитать полезную нагрузку до конца; это происходит, когда полезная нагрузка использует фрагментированное кодирование). При этом: pocoproject.org/docs/Poco.Net.HTTPMessage.html# 13185 - person Julian Reschke; 18.01.2012
comment
Джулиан, я согласен с твоим мнением, но разве это не должно быть комментарием? - person Mahmoud Al-Qudsi; 24.07.2012