使用asio进行异步下载http
下面是官方demo, 给人耳目一新的感觉,以前是总是把c++当成有类功能的C,看完这个感觉不用自己造轮子了,还是要跟上时代的步伐
//
// async_client.cpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// #include <iostream>
#include <istream>
#include <ostream>
#include <string>
#include <boost/asio.hpp>
#include <boost/bind.hpp> using boost::asio::ip::tcp; class client
{
public:
client(boost::asio::io_context& io_context,
const std::string& server, const std::string& path)
: resolver_(io_context),
socket_(io_context)
{
// 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.
std::ostream request_stream(&request_);
request_stream << "GET " << path << " HTTP/1.0\r\n";
request_stream << "Host: " << server << "\r\n";
request_stream << "Accept: */*\r\n";
request_stream << "Connection: close\r\n\r\n"; // Start an asynchronous resolve to translate the server and service names
// into a list of endpoints.
resolver_.async_resolve(server, "http",
boost::bind(&client::handle_resolve, this,
boost::asio::placeholders::error,
boost::asio::placeholders::results));
} private:
void handle_resolve(const boost::system::error_code& err,
const tcp::resolver::results_type& endpoints)
{
if (!err)
{
// Attempt a connection to each endpoint in the list until we
// successfully establish a connection.
boost::asio::async_connect(socket_, endpoints,
boost::bind(&client::handle_connect, this,
boost::asio::placeholders::error));
}
else
{
std::cout << "Error: " << err.message() << "\n";
}
} void handle_connect(const boost::system::error_code& err)
{
if (!err)
{
// The connection was successful. Send the request.
boost::asio::async_write(socket_, request_,
boost::bind(&client::handle_write_request, this,
boost::asio::placeholders::error));
}
else
{
std::cout << "Error: " << err.message() << "\n";
}
} void handle_write_request(const boost::system::error_code& err)
{
if (!err)
{
// 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::async_read_until(socket_, response_, "\r\n",
boost::bind(&client::handle_read_status_line, this,
boost::asio::placeholders::error));
}
else
{
std::cout << "Error: " << err.message() << "\n";
}
} void handle_read_status_line(const boost::system::error_code& err)
{
if (!err)
{
// 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(, ) != "HTTP/")
{
std::cout << "Invalid response\n";
return;
}
if (status_code != )
{
std::cout << "Response returned with status code ";
std::cout << status_code << "\n";
return;
} // Read the response headers, which are terminated by a blank line.
boost::asio::async_read_until(socket_, response_, "\r\n\r\n",
boost::bind(&client::handle_read_headers, this,
boost::asio::placeholders::error));
}
else
{
std::cout << "Error: " << err << "\n";
}
} void handle_read_headers(const boost::system::error_code& err)
{
if (!err)
{
// Process the response headers.
std::istream response_stream(&response_);
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() > )
std::cout << &response_; // Start reading remaining data until EOF.
boost::asio::async_read(socket_, response_,
boost::asio::transfer_at_least(),
boost::bind(&client::handle_read_content, this,
boost::asio::placeholders::error));
}
else
{
std::cout << "Error: " << err << "\n";
}
} void handle_read_content(const boost::system::error_code& err)
{
if (!err)
{
// Write all of the data that has been read so far.
std::cout << &response_; // Continue reading remaining data until EOF.
boost::asio::async_read(socket_, response_,
boost::asio::transfer_at_least(),
boost::bind(&client::handle_read_content, this,
boost::asio::placeholders::error));
}
else if (err != boost::asio::error::eof)
{
std::cout << "Error: " << err << "\n";
}
} tcp::resolver resolver_;
tcp::socket socket_;
boost::asio::streambuf request_;
boost::asio::streambuf response_;
}; int main(int argc, char* argv[])
{
try
{
if (argc != )
{
std::cout << "Usage: async_client <server> <path>\n";
std::cout << "Example:\n";
std::cout << " async_client www.boost.org /LICENSE_1_0.txt\n";
return ;
} boost::asio::io_context io_context;
client c(io_context, argv[], argv[]);
io_context.run();
}
catch (std::exception& e)
{
std::cout << "Exception: " << e.what() << "\n";
} return ;
}
直接拿来使用也是没有问题的,太爽了
使用asio进行异步下载http的更多相关文章
- Android多线程分析之五:使用AsyncTask异步下载图像
		
Android多线程分析之五:使用AsyncTask异步下载图像 罗朝辉 (http://www.cnblogs.com/kesalin) CC 许可,转载请注明出处 在本系列文章的第一篇<An ...
 - Android多线程分析之一:使用Thread异步下载图像
		
Android多线程分析之一:使用Thread异步下载图像 罗朝辉 (http://www.cnblogs.com/kesalin) CC 许可,转载请注明出处 打算整理一下对 Android F ...
 - WebClient.DownloadFile(线程机制,异步下载文件)
		
线程机制(避免卡屏),异步下载文件. 我做网站的监控,WebClient.DownloadFile这个方法是我经常用到的,必要的时候肯定是要从网上下载些什么(WebRequest 也可以下载网络文件, ...
 - iOS异步下载下载进度条显示
		
说到http异步下载,首先要知道其中的关键类. 关键类是NSURLConnection NSURLRequest NSMutableURLRequest 委托是 NSURLConnectionDo ...
 - unity下载文件三(http异步下载)
		
异步下载,顾名思义就是不影响你主线程使用客户端的时候,人家在后台搞你的明堂. 直接入主题,既然要下载,首先得请求,请求成功之后进行回调,这就是一个异步过程,异步回调的时间不可控. 1.首先请求下载. ...
 - Android 中的异步下载
		
网上提到最多的就是利用AsyncTask进行异步下载,用android-async-http第三方库的也比较多.这里写点注意事项. 先说说android-async-http,这个库发送请求利用thr ...
 - FtpWebRequest FTP异步下载、异步上传文件
		
异步下载: public interface IPrimaryKey<T> { T GetKey(); } public class DownloadInfo : IPrimaryKey& ...
 - Android异步下载图片并且缓存图片到本地
		
Android异步下载图片并且缓存图片到本地 在Android开发中我们经常有这样的需求,从服务器上下载xml或者JSON类型的数据,其中包括一些图片资源,本demo模拟了这个需求,从网络上加载XML ...
 - android  AsyncTask异步下载并更新进度条
		
AsyncTask异步下载并更新进度条 //如果不是很明白请看上篇文章的异步下载 AsyncTask<String, Integer, String> 第一个参数:String 传入 ...
 
随机推荐
- scala新版本学习(3)
			
1.REPL:读取->求值->打印->循环.Scala程序将输入的内容快速的编译成为字节码,然后字节码文件交给Java虚拟机进行执行. 2.val是值不可变,var值可变.在变量声明 ...
 - java网络编程+通讯协议的理解
			
参考: http://blog.csdn.net/sunyc1990/article/details/50773014 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很 ...
 - 自定义zabbix中的普通KEY及LLD KEY
			
普通类型KEY 1.agent端: 编写自定义脚本,脚本需要有输出值返回给zabbix-server,并且给对应脚本赋予zabbix用户可执行权限 zabbix-agnet 且定义key名称和comm ...
 - 因xhost命令和DISPLAY环境变量操作不当导致无法启动Oracle图形化安装界面
			
在redhat操作系统上安装Oracle 11.1时,遇到在执行runInstaller后无法启动安装图像化界面,甚是郁闷. 问题现象: 使用Xmanager2.0软件登陆AIX桌面,root用户可以 ...
 - linux命令详解——lsof
			
lsof全名list opened files,也就是列举系统中已经被打开的文件.我们都知道,linux环境中,任何事物都是文件, 设备是文件,目录是文件,甚至sockets也是文件.所以,用好lso ...
 - 【异常】Reason: Executor heartbeat timed out after 140927 ms
			
1 详细异常 ERROR scheduler.JobScheduler: Error running job streaming job ms. org.apache.spark.SparkExcep ...
 - 修改phpMyAdmin 导入MySQL数据库文件大小限制
			
默认情况下,phpMyAdmin导入MySQL数据库文件大小为2M. 很多朋友对网站进行搬家的时候,网站数据进行导入时会出现一些问题,提示超出导入大小限制. 默认MYSQL只能导入最大2MB的数据,于 ...
 - [uboot] (番外篇)uboot relocation介绍(转)
			
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/ooonebook/article/det ...
 - vue history模式下的微信支付,及微信支付授权目录的填写,处理URL未注册
			
微信公众号配置网页授权域名:填写网址域名 微信开发者平台配置url: 访问url:http://www.baidu.com/pay/ment 支付授权目录:http://www.baidu.com/p ...
 - 对abel 转译 class 过程的研究----------------------引用
			
作为当下最流行的 JavaScript 编译器,Babel 替我们转译 ECMAScript 语法,而我们不用再担心如何进行向后兼容. 零.前言 虽然在 JavaScript 中对象无处不在,但这门语 ...