2011-11-12 69 views
2

我是C++的新手,我只是試圖使用Boost ASIO Sync Http Client來實現一個簡單的HTTP客戶端;我從Boost的站點複製了這個例子,只是將它修改爲以字符串形式返回響應而不是寫入控制檯。爲什麼我的C++ Boost ASIO HTTP客戶端返回不完整的響應?

我的代碼正在進行調用,它返回一個響應,但它是部分 - 它在第10行後切斷......我很困惑有人能幫我嗎?

這是我的代碼,如果你有升壓設置,你應該能夠複製/粘貼並運行它。

我在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」 「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「 「WFC」,25.65,「11/11/2011」,「4:00 pm」 「BAC」,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「 」MET「,33.07,」11/11/2011「,」4:00 pm「 」BK「,21.51,」11/11/2011「,」4:00 pm「 「PNC」,53.87,「11/11/2011」,「4:01 pm」 「PRU」,54.05,「11/11/2011」,「4:01 pm」 「SPG」,127.97,「11/「2011年11月」,「下午4:02」 「AFL」,44.87,「11/11/2011」,「下午4:01」 「TRV」,58.43,「11/11/2011」,「下午4:04」 「ACE」,71.24,「11/2011」,「下午4點02」 「2011年11月」,「下午4:01」 「BBT」,23.58,「11/11/2011」,「4:00 pm」 「CME」,263.57,「11/11/2011」,「 「SCHW」,12.36 「11/11/2011」, 「4:00」

但它返回:

日期:星期六,2011年11月12日21時34分二十三秒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 OI DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE GOV 「 緩存控制:私人 連接:關閉 內容類型:應用/八位字節流

」AAPL「,384.62 」11/11/2011「,」 下午4:00 「 」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」 「WFC」,25.65, 11/

回答

0

註釋掉行

//std::cout << &response; 

現在,我知道你不想要的功能,打印出的結果,但歸還。但是,包含該註釋行的循環會讀出其餘的響應,現在您只是將其扔掉。您需要將其捕獲到您的返回值變量中。一個簡單的解決方法是用

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

更換註釋掉的行但是,這不是做–你應該只是讓東西在response積累,並將其轉換成在最後一個字符串,最徹底的方法。

+0

謝謝ibid,我刪除了空頭,並評論說我實際上不需要控制檯打印 - 而是我想讓函數返回響應。在我的原始文章中,我只有3個股票代碼的工作正常,但當我添加更多代碼時(當響應變得更長)時,它會被切斷。我糾正了main()代碼,我想知道你是否可以再試一次?最好的祝願 – serkanozel

+0

這基本上是一樣的問題,所以我只是編輯它以更好地對應你的問題。 – ibid

相關問題