Last active
December 10, 2015 11:19
-
-
Save hecomi/4426931 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <boost/asio.hpp> | |
#include <boost/bind.hpp> | |
#include <boost/function.hpp> | |
#include <boost/thread.hpp> | |
#include <boost/system/system_error.hpp> | |
#include <iostream> | |
using namespace std; | |
namespace asio = boost::asio; | |
using boost::asio::ip::tcp; | |
class Client { | |
typedef boost::function<void(const string&, const string&)> callback; | |
callback callback_; | |
string host_; | |
string html_; | |
asio::io_service& io_service_; | |
tcp::socket socket_; | |
tcp::resolver resolver_; | |
asio::streambuf buf_; | |
public: | |
Client(asio::io_service& io_service) | |
: io_service_(io_service), | |
socket_(io_service), | |
resolver_(io_service) | |
{} | |
void get(const string& host, callback callback) | |
{ | |
host_ = host; | |
callback_ = callback; | |
html_ = ""; | |
tcp::resolver::query query(host, "http"); | |
resolver_.async_resolve( | |
query, | |
boost::bind( | |
&Client::on_resolve, | |
this, | |
asio::placeholders::error, | |
asio::placeholders::iterator)); | |
boost::thread t(boost::bind(&asio::io_service::run, &io_service_)); | |
t.detach(); | |
} | |
private: | |
void on_resolve(const boost::system::error_code& error, | |
tcp::resolver::iterator endpoint_iterator) | |
{ | |
if (has_error(error)) return; | |
async_connect( | |
socket_, | |
endpoint_iterator, | |
boost::bind(&Client::on_connect, this, asio::placeholders::error)); | |
} | |
void on_connect(const boost::system::error_code& error) | |
{ | |
if (has_error(error)) return; | |
buf_.consume(buf_.size()); | |
ostream s(&buf_); | |
s << "GET / HTTP/1.0\r\n"; | |
s << "Host: " << host_ << "\r\n"; | |
s << "\r\n"; | |
async_write( | |
socket_, | |
buf_, | |
boost::bind(&Client::on_write, this, asio::placeholders::error)); | |
} | |
void on_write(const boost::system::error_code& error) | |
{ | |
if (has_error(error)) return; | |
buf_.consume(buf_.size()); | |
async_read( | |
socket_, | |
buf_, | |
asio::transfer_at_least(1), | |
boost::bind(&Client::on_receive, this, asio::placeholders::error)); | |
} | |
void on_receive(const boost::system::error_code& error) | |
{ | |
if (error.message().find("End of file") != std::string::npos) { | |
callback_("", html_); | |
return; | |
} | |
if (has_error(error)) return; | |
const string data(asio::buffer_cast<const char*>(buf_.data()), buf_.size()); | |
buf_.consume(buf_.size()); | |
html_ += data; | |
async_read( | |
socket_, | |
buf_, | |
asio::transfer_at_least(1), | |
boost::bind(&Client::on_receive, this, asio::placeholders::error)); | |
} | |
bool has_error(const boost::system::error_code& error) | |
{ | |
if (error) { | |
callback_(error.message(), html_); | |
return true; | |
} | |
return false; | |
} | |
}; | |
int main() | |
{ | |
asio::io_service io_service; | |
Client client(io_service); | |
const string url = "www.google.co.jp"; | |
client.get(url, [](const string& error, const string& html) { | |
if (!error.empty()) { | |
std::cerr << error << std::endl; | |
return; | |
} | |
cout << html << endl; | |
}); | |
// 何か処理 | |
boost::this_thread::sleep_for(boost::chrono::seconds(5)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment