Почему мой клиент C ++ Boost ASIO HTTP возвращает неполный ответ? - PullRequest
2 голосов
/ 12 ноября 2011

Я новичок в C ++, и я просто пытаюсь реализовать простой HTTP-клиент с помощью Boost ASIO Sync Http Client; Я скопировал пример с сайта Boost, просто изменил его, чтобы он возвращал ответ в виде строки, а не записывал в консоль.

Мой код звонит и возвращает ответ, но он неполный - он обрывается после 10-й строки ... Я озадачен, может кто-нибудь помочь мне?

Вот мой код, и если у вас настроен Boost, вы сможете просто скопировать / вставить и запустить его.

Я на Windows 7, использую Visual Studio 2010 с Boost 1.47.

Заранее спасибо.

-serkan

#include <iostream>
#include <istream>
#include <ostream>
#include <string>

#include <boost/asio.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/assign/list_inserter.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>

using boost::asio::ip::tcp;

typedef boost::gregorian::date Calendar;



std::string httpClient(std::string host, std::string path){
    std::string res = "";

    try{
        boost::asio::io_service io_service;

        // Get a list of endpoints corresponding to the server name.
        tcp::resolver resolver(io_service);
        tcp::resolver::query query(host, "http");
        tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
        tcp::resolver::iterator end;

        // Try each endpoint until we successfully establish a connection.
        tcp::socket socket(io_service);
        boost::system::error_code error = boost::asio::error::host_not_found;
        while(error && endpoint_iterator != end){
            socket.close();
            socket.connect(*endpoint_iterator++, error);
        }

        if(error){ throw boost::system::system_error(error); }

        // Form the request. We specify the "Connection: close" header so that the server will close the socket 
        // after transmitting the response. This will allow us to treat all data up until the EOF as the content.
        boost::asio::streambuf request;
        std::ostream request_stream(&request);
        request_stream << "GET " << path << " HTTP/1.0\r\n";
        request_stream << "Host: " << host << "\r\n";
        request_stream << "Accept: */*\r\n";
        request_stream << "Connection: close\r\n\r\n";

        // Send the request.
        boost::asio::write(socket, request);

        // Read the response status line.
        boost::asio::streambuf response;
        boost::asio::read_until(socket, response, "\r\n");

        // Check that response is OK.
        std::istream response_stream(&response);

        std::string http_version;
        response_stream >> http_version;

        unsigned int status_code;
        response_stream >> status_code;

        std::string status_message;
        std::getline(response_stream, status_message);
        if(!response_stream || http_version.substr(0, 5) != "HTTP/"){
            std::cout << "Invalid response\n";
        }
        if(status_code != 200){
            std::cout << "Response returned with status code " << status_code << "\n";
        }

        // Read the response headers, which are terminated by a blank line.
        boost::asio::read_until(socket, response, "\r\n\r\n");

        // Write whatever content we already have to output.
        if(response.size() > 0){
            std::ostringstream oss;
            oss << &response;
            res = oss.str();
        }

        // Read until EOF, writing data to output as we go.
        while(boost::asio::read(socket, response, boost::asio::transfer_at_least(1), error)){
            //std::cout << &response; // don't want to print just return
        }

        if(error != boost::asio::error::eof){ throw boost::system::system_error(error); }

    }catch(std::exception& e){
        std::cout << "Exception: " << e.what() << "\n";
    }

    return res;
}


int main(int argc, char* argv[]){
    std::cout << httpClient("download.finance.yahoo.com", "/d/quotes.csv?s=aapl,aig,msft,jpm,WFC,BAC,C,GS,USB,AXP,MS,MET,BK,PNC,PRU,SPG,AFL,TRV,COF,STT,ACE,BBT,CME,SCHW&f=sl1d1t1");

    return 0;
}

Возвращается:

"AAPL", 384,62, "11.11.2011", "4:00 PM" "AIG", 23,85, "11.11.2011", "4:01 PM" "MSFT", 26,91, "11.11.2011", "4:00 PM" "JPM", 33,28, "11.11.2011", "4:01 PM" "ВЛК", 25,65, "11.11.2011", "4:00 PM" "БАК", 6,21, "11.11.2011", "4:00 PM" "C", 29,33, "11.11.2011", "4:00 PM" "GS", 101,66, "11.11.2011", "4:00 PM" "USB", 25,94, "11.11.2011", "4:00 PM" "AXP", 50,37, "11.11.2011", "4:00 PM" "MS", 16,36, "11.11.2011", "4:00 PM" "МЕТ", 33,07, "11.11.2011", "4:00 PM" "БК", 21,51, "11.11.2011", "4:00 PM" "PNC", 53,87, "11.11.2011", "4:01 PM" "НР", 54,05, "11.11.2011", "4:01 PM" "SPG", 127,97, "11.11.2011", "4:02 PM" "AFL", 44,87, "11.11.2011", "4:01 PM" "ТРВ", 58,43, "11.11.2011", "4:04 PM" "КОФ", 45,02, "11.11.2011", "4:01 PM" "СТТ", 41,24, "11.11.2011", "4:02 PM" "ACE", 71,24, "11.11.2011", "4:01 PM" "ББТ", 23,58, "11.11.2011", "4:00 PM" "CME", 263,57, "11.11.2011", "4:00 PM" "SCHW", 12,36, "11.11.2011", "4:00 PM"

Но возвращается:

Дата: сб, 12 ноября 2011 21:34:23 GMT P3P: policyref = "http://p3p.yahoo.com/w3c/p3p.xml", CP =" CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONI TELO OTPi НАШИ ДЕЛИ САМИ ОТРИ UNRi PUBI IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE GOV " Cache-Control: приватный Подключение: закрыть Тип контента: application / octet-stream

"AAPL", 384,62, "11.11.2011", "4:00 PM" "AIG", 23,85, "11.11.2011", "4:01 PM" "MSFT", 26,91, "11.11.2011", "4:00 PM" "JPM", 33,28, "11.11.2011", "4:01 PM" "ВЛК", 25,65, "11/11 /

1 Ответ

0 голосов
/ 12 ноября 2011

Вы прокомментировали строку

//std::cout << &response;

Теперь я понимаю, что вы хотите, чтобы функция не выводила результат, а возвращала его. Однако цикл, содержащий эту закомментированную строку, считывает остаток ответа, и теперь вы просто отбрасываете его. Вам нужно записать его в переменную возвращаемого значения. Простое исправление - заменить закомментированную строку на

std::ostringstream oss;
oss << &response;
res += oss.str();

Но это не самый чистый способ сделать это - ndash; вам, вероятно, следует просто позволить материалу накапливаться в response и преобразовывать его в строку в конце.

...