Last active
December 10, 2015 11:28
-
-
Save hecomi/4427622 to your computer and use it in GitHub Desktop.
Boost.Thread + Boost.Asio で thread 中で io_service.run() すると落ちる…;;
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
// | |
// ViewController.m | |
// AsioTest | |
// | |
// Created by hecomi on 2012/12/31. | |
// Copyright (c) 2012年 hecomi. All rights reserved. | |
// | |
#import "ViewController.h" | |
#include <dispatch/dispatch.h> | |
#include <boost/asio.hpp> | |
#include <boost/bind.hpp> | |
#include <boost/thread.hpp> | |
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) | |
{ | |
std::cout << "get\n"; | |
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.join(); | |
} | |
private: | |
void on_resolve(const boost::system::error_code& error, | |
tcp::resolver::iterator endpoint_iterator) | |
{ | |
std::cout << "on_resolve\n"; | |
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) | |
{ | |
std::cout << "on_connect\n"; | |
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) | |
{ | |
std::cout << "on_write\n"; | |
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) | |
{ | |
std::cout << "on_receive\n"; | |
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) | |
{ | |
std::cout << "has_error\n"; | |
if (error) { | |
std::cerr << error.message() << std::endl; | |
callback_(error.message(), html_); | |
return true; | |
} | |
return false; | |
} | |
}; | |
@interface ViewController () | |
@end | |
@implementation ViewController | |
- (void)setText:(NSString *)str | |
{ | |
_textView.text = str; | |
} | |
- (void)viewDidLoad | |
{ | |
asio::io_service io_service; | |
Client client(io_service); | |
const string url = "www.boost.org"; | |
client.get(url, [&](const string& error, const string& html) { | |
std::cout << "callback\n"; | |
if (!error.empty()) { | |
std::cerr << error << std::endl; | |
return; | |
} | |
NSString* str = [[NSString alloc] initWithCString:html.c_str() encoding:NSUTF8StringEncoding]; | |
[self performSelectorOnMainThread:@selector(setText:) withObject:str waitUntilDone:NO]; | |
}); | |
} | |
- (void)didReceiveMemoryWarning | |
{ | |
[super didReceiveMemoryWarning]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment