////Async_client.cpp// ~~~~~~~~~~~~~~~~//an asynchronous HTTP client that is very similar to synchronization. The difference is the last point where the loop is synchronized//Copyright (c) 2003-2013 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 atHttp://www.boost.org/LICENSE_1_0.txt)//#include<iostream>#include<istream>#include<ostream>#include<string>#include<boost/asio.hpp>#include<boost/bind.hpp>usingboost::asio::ip::tcp;//Client Clients Classclassclient{ Public: Client (Boost::asio::io_service&Io_service,ConstSTD::string& Server,ConstSTD::string&path): Resolver_ (Io_service), socket_ (io_service) {//Form the request. We Specify the "Connection:close" header so, the//server would close the socket after transmitting the response. this would//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. //asynchronously resolves DNS and returns a listTcp::resolver::query Query (server,"http"); Resolver_.async_resolve (Query, Boost::bind (&client::handle_resolve, This, Boost::asio::p laceholders::error, Boost::asio::p laceholders::iterator)); }Private: voidHandle_resolve (Constboost::system::error_code&err, Tcp::resolver::iterator endpoint_iterator) { if(!err) { //attempt a connection to all endpoint in the list until we//successfully establish a connection. //is this every attempt to connect? Boost::asio::async_connect (socket_, Endpoint_iterator, Boost::bind (&client::handle_connect, This, Boost::asio::p laceholders::error)); } Else{std::cout<<"Error:"<< err.message () <<"\ n"; } } voidHandle_connect (Constboost::system::error_code&err) { if(!err) { //The connection was successful. Send the request. //attempt to connect after successful connectionBoost::asio::async_write (socket_, Request_, Boost::bind (&client::handle_write_request, This, Boost::asio::p laceholders::error)); } Else{std::cout<<"Error:"<< err.message () <<"\ n"; } } voidHandle_write_request (Constboost::system::error_code&err) { if(!err) { //Read the response status line. The Response_ streambuf would//automatically grow to accommodate, the entire line. The growth may//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::p laceholders::error)); } Else{std::cout<<"Error:"<< err.message () <<"\ n"; } } voidHandle_read_status_line (Constboost::system::error_code&err) { if(!err) { //Check that response is OK.Std::istream Response_stream (&response_); STD::stringhttp_version; Response_stream>>http_version; unsignedintStatus_code; Response_stream>>Status_code; STD::stringStatus_message; Std::getline (Response_stream, status_message); if(!response_stream | | http_version.substr (0,5) !="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 is 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::p laceholders::error)); } Else{std::cout<<"Error:"<< Err <<"\ n"; } } voidHandle_read_headers (Constboost::system::error_code&err) { if(!err) { //Process The response headers.Std::istream Response_stream (&response_); STD::stringheader; while(Std::getline (Response_stream, header) && header! ="\ r") Std::cout<< Header <<"\ n"; Std::cout<<"\ n"; //Write Whatever content we already has to output. if(Response_.size () >0) Std::cout<< &Response_; //Start reading remaining data until EOF.Boost::asio::async_read (socket_, Response_, Boost::asio::transfer_at_least (1), Boost::bind (&client::handle_read_content, This, Boost::asio::p laceholders::error)); } Else{std::cout<<"Error:"<< Err <<"\ n"; } } voidHandle_read_content (Constboost::system::error_code&err) { if(!err) { //The Write all of the data is been read so far.Std::cout << &Response_; //Continue reading remaining data until EOF.Boost::asio::async_read (socket_, Response_, Boost::asio::transfer_at_least (1), Boost::bind (&client::handle_read_content, This, Boost::asio::p laceholders::error)); } //read EOF to exit? 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_;};intMainintargcChar*argv[]) { Try { if(ARGC! =3) {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 1; } Boost::asio::io_service Io_service; Client C (Io_service, argv[1], argv[2]); //will it stop the end? End without an asynchronous taskIo_service.run (); } Catch(std::exception&e) {std::cout<<"Exception:"<< e.what () <<"\ n"; } return 0;}
ASIO example HTTP client, asynchronous example Async_client.cpp