欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

使用boost.asio实现网络通讯

程序员文章站 2022-05-27 22:30:00
参考资料: 跨平台c++/boost/asio 简单的HTTP POST请求 客户端模型http://www.cnblogs.com/linbc/p/5034286.html C++ Post/Get请求(Boost.Asio库)https://blog.csdn.net/csnd_ayo/arti ......
#include <boost/asio.hpp>

#define using_ssl   //是否加密

#ifdef using_ssl
#include <boost/asio/ssl.hpp>  
#endif

using boost::asio::ip::tcp;
using std::string;

int post(const string& host, const string& port, const string& page, const string& data, string& reponse_data)
{
  try
  {
    boost::asio::io_service io_service;
    //如果io_service存在复用的情况
   // if(io_service.stopped())
   //   io_service.reset();

    // 从dns取得域名下的所有ip
    tcp::resolver resolver(io_service);
    tcp::resolver::query query(host, port);
    tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
 
	// 尝试连接到其中的某个ip直到成功 
#ifdef using_ssl
	boost::asio::ssl::context context(boost::asio::ssl::context::sslv23); 
	context.set_default_verify_paths(); 
	boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket(io_service, context); 
	socket.set_verify_mode(boost::asio::ssl::context::verify_none);
	boost::asio::connect(socket.lowest_layer(), endpoint_iterator);
	socket.handshake(boost::asio::ssl::stream_base::client);
#else
	tcp::socket socket(io_service);
	boost::asio::connect(socket, endpoint_iterator);
#endif

    // 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 << "post " << page << " http/1.1\r\n";
    request_stream << "host: " << host << "\r\n";
    request_stream << "content-length: " << data.length() << "\r\n";
    // content-type: 视实际情况修改,or“application/octet-stream”
    request_stream << "content-type: application/json; charset=utf-8\r\n";
	request_stream << "accept: */*\r\n";
    request_stream << "connection: close\r\n\r\n";
    request_stream << data;

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

    // 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");

    // 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/")
    {
      reponse_data = "invalid response";
      return -2;
    }
    // 如果服务器返回非200都认为有错,不支持301/302等跳转
    if (status_code != 200)
    {
		std::stringstream oss;
		oss << "response returned with status code" << " : " << status_code;
		reponse_data = oss.str();
        return -3;
    }

    // 传说中的包头可以读下来了
    std::string header;
    std::vector<string> headers;        
//		string content_length_header("content-length: ");
//		size_t content_length = 0;
    while (std::getline(response_stream, header) && header != "\r")
	{
		/*	if(string::npos != header.find(content_length_header))
			{
				string tmp(header.substr(content_length_header.size()));
				stringstream ss;
				ss << tmp;
				ss >> content_length;
			}*/
      headers.push_back(header);
	  //std::cout << header << std::endl;
	}

    // 读取所有剩下的数据作为包体
    boost::system::error_code error;
    while (boost::asio::read(socket, response,
        boost::asio::transfer_at_least(1), error))
    {           
    }

	// 返回值为eof,认为是正确的
	if (error != boost::asio::error::eof && error.value() != 0x140000db)
	{
		std::stringstream oss;
		oss << error.value() << " : " <<  error.message();
		reponse_data = oss.str();
		return -4;
	}

    //响应有数据
    if (response.size())
    {
      std::istream response_stream(&response);
      std::istreambuf_iterator<char> eos;
      reponse_data = string(std::istreambuf_iterator<char>(response_stream), eos);                        
    }
  }
  catch(std::exception& e)
  {
    reponse_data = e.what();
      return -1;  
  }
  return 0;
}

 

参考资料:

跨平台c++/boost/asio 简单的http post请求 客户端模型
http://www.cnblogs.com/linbc/p/5034286.html

c++ post/get请求(boost.asio库)
https://blog.csdn.net/csnd_ayo/article/details/64437935

 boost::asio ssl

https://blog.csdn.net/aalbertini/article/details/38300757

 基于boost asio实现的支持ssl的通用socket框架

https://www.xuebuyuan.com/2178001.html