我是 C++ 的新手,我只是想使用 Boost ASIO Sync Http Client 实现一个简单的 HTTP Client;我从 Boost 的站点复制了示例,只是对其进行了修改以将响应作为字符串返回,而不是写入控制台。
我的代码正在调用电话并返回响应,但它是部分的 - 它在第 10 行后中断......我很困惑有人可以帮助我吗?
这是我的代码,如果您设置了 Boost,您应该能够复制/粘贴并运行它。
我在 Windows 7 上,使用带有 Boost 1.47 的 Visual Studio 2010。
提前致谢。
-塞尔坎
#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:00pm" “AIG”,23.85,“2011 年 11 月 11 日”,“下午 4:01” “MSFT”,26.91,“11/11/2011”,“下午 4:00” “摩根大通”,33.28,“2011 年 11 月 11 日”,“下午 4:01” “WFC”,25.65,“11/11/2011”,“下午 4:00” “BAC”,6.21,“11/11/2011”,“下午 4:00” “C”,29.33,“11/11/2011”,“下午 4:00” “GS”,101.66,“11/11/2011”,“下午 4:00” “USB”,25.94,“11/11/2011”,“下午 4:00” “AXP”,50.37,“11/11/2011”,“下午 4:00” “MS”,16.36,“11/11/2011”,“下午 4:00” “遇见”,33.07,“11/11/2011”,“下午 4:00” “BK”,21.51,“11/11/2011”,“下午 4:00” “PNC”,53.87,“2011 年 11 月 11 日”,“下午 4:01” “PRU”,54.05,“11/11/2011”,“下午 4:01” "SPG",127.97,"11/11/2011","4:02pm" “AFL”,44.87,“11/11/2011”,“下午 4:01” “TRV”,58.43,“11/11/2011”,“下午 4:04” “COF”,45.02,“2011 年 11 月 11 日”,“下午 4:01” “STT”,41.24,“11/11/2011”,“下午 4:02” “王牌”,71.24,“11/11/2011”,“下午 4:01” “BBT”,23.58,“11/11/2011”,“下午 4:00” “CME”,263.57,“11/11/2011”,“下午 4:00” "SCHW",12.36,"11/11/2011","4:00pm"
但它返回:
日期:2011 年 11 月 12 日星期六 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 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE GOV” 缓存控制:私有(private) 连接:关闭 内容类型:应用程序/八位字节流
"AAPL",384.62,"11/11/2011","4:00pm" “AIG”,23.85,“2011 年 11 月 11 日”,“下午 4:01” “MSFT”,26.91,“11/11/2011”,“下午 4:00” “摩根大通”,33.28,“2011 年 11 月 11 日”,“下午 4:01” "WFC",25.65,"11/11/
最佳答案
你已经注释掉了这一行
//std::cout << &response;
现在,我知道您不希望函数打印出结果而是返回它。但是,包含该注释掉的行的循环会读出响应的其余部分,现在您只是将其丢弃。您需要将其捕获到您的返回值变量中。一个简单的解决方法是用
替换注释掉的行std::ostringstream oss;
oss << &response;
res += oss.str();
但这不是最简洁的方法 - 您可能应该让这些东西在 response
中累积并在最后将其转换为字符串。
关于c++ - 为什么我的 C++ Boost ASIO HTTP 客户端返回不完整的响应?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8106566/