Boost.Asioは、Proactorパターンのスタイルの他に、Reactorパターンのスタイルもサポートしています。
以下、Reactorスタイルの例:
#include <iostream> #include <vector> #include <boost/asio.hpp> #include <boost/bind.hpp> #include <boost/range/algorithm/for_each.hpp> namespace asio = boost::asio; class Client { asio::io_service& io_service_; asio::ip::tcp::socket socket_; public: Client(asio::io_service& io) : io_service_(io), socket_(io) {} void connect() { namespace ip = asio::ip; socket_.connect(ip::tcp::endpoint( ip::address::from_string("127.0.0.1"), 31400)); } void start_read() { socket_.non_blocking(true); socket_.async_read_some( asio::null_buffers(), boost::bind(&Client::read_handler, this, _1)); } private: void read_handler(const boost::system::error_code& error) { if (error) { std::cout << "Error: " << error.message() << std::endl; return; } std::vector<char> buf(socket_.available()); socket_.read_some(asio::buffer(buf)); std::cout << std::string(buf.begin(), buf.end()) << std::endl; } }; int main() { asio::io_service io_service; Client client(io_service); client.connect(); client.start_read(); io_service.run(); }
Proactorスタイルでは、非同期関数を実行する際にバッファへの参照を渡し、完了ハンドラでバッファを参照しますが、Reactorスタイルでは、非同期関数に渡すハンドラが「準備ができたら呼ばれる関数」を意味するようになり、ハンドラ内で同期関数を改めて呼び出し、準備ができた分だけ処理します。
参照:
Reactor-Style Operations - Boost Asio Library