使用boost库实现的 http get操作

/*
 * HttpBoostCL.h
 *
 *  Created on: 2018年4月10日
 *      Author: Administrator
 */


#ifndef BOOSTSTUDY_HTTPBOOSTCL_H_
#define BOOSTSTUDY_HTTPBOOSTCL_H_
#include <boost/asio.hpp>
using boost::asio::ip::tcp;


class BoostHttpClient
{
public:
BoostHttpClient();
~BoostHttpClient();
static int boost_http_sync_client(const std::string& server, const std::string& port, const std::string& path,
   std::string& out_response_status_line, std::string& out_response_header, std::string& out_response_data);
static int parse_url(const std::string& url, std::string& out_server, std::string& out_port, std::string& out_path);
static int get_url_response(const std::string& url, std::string& out_response_data);
};


#endif /* BOOSTSTUDY_HTTPBOOSTCL_H_ */



/*
 * HttpBoostCL.cpp
 *
 *  Created on: 2018年4月10日
 *      Author: Administrator
 */


#include <iostream>
#include <istream>
#include <ostream>
#include <string>
#include "HttpBoostCL.h"


int64_t getTimeMsec()
{
    struct  timeval    tv;
    gettimeofday(&tv,NULL);
    return tv.tv_sec * 1000 + tv.tv_usec / 1000;
}


BoostHttpClient::BoostHttpClient()
{


}
BoostHttpClient::~BoostHttpClient()
{


}


int BoostHttpClient::boost_http_sync_client(const std::string& server,
const std::string& port, const std::string& path,
std::string& out_response_status_line, std::string& out_response_header,
std::string& out_response_data)
{
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(server, port/*"http"*/);
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);


// Try each endpoint until we successfully establish a connection.
tcp::socket socket_(io_service);
boost::asio::connect(socket_, endpoint_iterator);


boost::asio::streambuf request;
std::ostream request_stream(&request);
request_stream << "GET " << path/*argv[2]*/<< " HTTP/1.0\r\n";
request_stream << "Host: " << server/*argv[1]*/<< "\r\n";
request_stream << "Accept: */*\r\n";
request_stream << "Connection: close\r\n\r\n";
std::cout << "write begin" << getTimeMsec() << std::endl;
// Send the request.
boost::asio::write(socket_, request);
std::cout << "write end" << getTimeMsec() << std::endl;
// Read the response status line. The response streambuf will automatically
// grow to accommodate the entire line. The growth may be limited by passing
// a maximum size to the streambuf constructor.
boost::asio::streambuf response;
boost::asio::read_until(socket_, response, "\r\n");


if (true)
{
boost::asio::streambuf::const_buffers_type cbt = response.data();
std::string temp_data(boost::asio::buffers_begin(cbt),
boost::asio::buffers_end(cbt));
std::size_t idx = temp_data.find('\n');
idx == std::string::npos ? temp_data.size() : idx;
out_response_status_line = temp_data.substr(0, idx + 1);
}


// 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";
return 1;
}
if (status_code != 200)
{
std::cout << "Response returned with status code " << status_code
<< "\n";
return 1;
}


// Read the response headers, which are terminated by a blank line.
boost::asio::read_until(socket_, response, "\r\n\r\n");
if (true)
{
boost::asio::streambuf::const_buffers_type cbt = response.data();
std::string temp_data(boost::asio::buffers_begin(cbt),
boost::asio::buffers_end(cbt));
std::size_t idx = temp_data.find("\r\n\r\n");
idx == std::string::npos ? temp_data.length() : idx;
out_response_header = temp_data.substr(0, idx + 2);
}


// Process the response headers.
std::string header;
while (std::getline(response_stream, header) && header != "\r")
;    //std::cout << header << "\n";
//std::cout << "\n";


// Write whatever content we already have to output.
//if (response.size() > 0)
//    std::cout << &response;
if (true)
{
boost::asio::streambuf::const_buffers_type cbt = response.data();
out_response_data = std::string(boost::asio::buffers_begin(cbt),
boost::asio::buffers_end(cbt));
}


// Read until EOF, writing data to output as we go.
boost::system::error_code error;
while (boost::asio::read(socket_, response,
boost::asio::transfer_at_least(1), error))
//std::cout << &response;
{
boost::asio::streambuf::const_buffers_type cbt = response.data();
out_response_data += std::string(boost::asio::buffers_begin(cbt),
boost::asio::buffers_end(cbt));
}
if (error != boost::asio::error::eof)
throw boost::system::system_error(error);
//socket_.cancel();
} catch (std::exception& e)
{
std::cout << "Exception: " << e.what() << "\n";
return -1;
}


return 0;
}

int BoostHttpClient::parse_url(const std::string& url,
std::string& out_server, std::string& out_port, std::string& out_path)
{
const std::string http___ = "http://";
const std::string https___ = "https://";
std::string temp_data = url;


if (temp_data.find(http___) == 0)
temp_data = temp_data.substr(http___.length());
else if (temp_data.find(https___) == 0)
temp_data = temp_data.substr(https___.length());
else
return -1;


std::size_t idx = temp_data.find('/');
if (std::string::npos == idx)
{
out_path = "/";
idx = temp_data.size();
}
else
{
out_path = temp_data.substr(idx);
}


out_server = temp_data.substr(0, idx);
idx = out_server.find(':');
if (std::string::npos == idx)
{
out_port = "http";
out_port = "80";
}
else
{
out_port = out_server.substr(idx + 1);
out_server = out_server.substr(0, idx);
}
return 0;
}
//
int BoostHttpClient::get_url_response(const std::string& url, std::string& out_response_data)
{
int rv = 0;
do
{
std::string server;
std::string port;
std::string path;
rv = parse_url(url, server, port, path);
if (rv)  break;
std::string out_response_status_line;
std::string out_response_header;
rv = boost_http_sync_client(server, port, path, out_response_status_line, out_response_header, out_response_data);
if (rv)  break;
} while (false);
return rv;
}

int main()
{
    int rv = 0;
    std::string url = "http://hq.sinajs.cn/list=sh204001";

    while(1)
    {
        int64_t timeBegin = getTimeMsec();
        std::string response_data;

        rv = BoostHttpClient::get_url_response(url, response_data);
        int64_t timeEnd = getTimeMsec();
        if (rv)  return -1;
        std::cout << "timeuse:"<< timeEnd-timeBegin << "res:"<< response_data << std::endl;
        sleep(1);
   }
    return 0;
}
//g++ HttpBoostCL.cpp -o httptest -lpthread -lboost_system



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值