ããã¯ç§ã®æåã®æçš¿ãªã®ã§ãå³å¯ã«å€æããªãã§ãã ããã John Torjoã®æ¬Boost.Asio C ++ Network Programmingã®ç¡æç¿»èš³ãéå§ãããã®ã§ãããããã«ãªã³ã¯ããããŸãã
å 容ïŒ
- 第1ç« ïŒBoost.Asioã®äœ¿çšéå§
- 第2ç« ïŒBoost.Asioã®åºæ¬
- 第3ç« ïŒãšã³ãŒãµãŒããŒ/ã¯ã©ã€ã¢ã³ã
- 第4ç« ïŒã¯ã©ã€ã¢ã³ããšãµãŒããŒ
- 第5ç« ïŒåæãšéåæ
- 第6ç« ïŒBoost.Asio-ãã®ä»ã®æ©èœ
- 第7ç« ïŒBoost.Asio-远å ãããã¯
ãŸããBoost.Asioã®æŠèŠãçµã¿ç«ãŠæ¹æ³ãããã³ããã€ãã®äŸãèŠãŠã¿ãŸãããã Boost.Asioã¯ãããã¯ãŒã¯ã©ã€ãã©ãªä»¥äžã®ãã®ã§ããããšãããããŸãã Boost.Asio-
io_service
äžå¿ã«ããæãéèŠãªã¯ã©ã¹ã«ã€ããŠãåŠã³ãŸãã
Boost.Asioãšã¯äœã§ããïŒ
ã€ãŸããBoost.Asioã¯ãã»ãšãã©ã®å Žåãããã°ã©ãã³ã°ãããã¯ãŒã¯ããã®ä»ã®äœã¬ãã«I / Oããã°ã©ã çšã®ã¯ãã¹ãã©ãããã©ãŒã C ++ã©ã€ãã©ãªã§ãã
ãããã¯ãŒã¯ã®åé¡ã解決ããããã®å®è£ ã¯æ°å€ããããŸãããBoost.Asioã¯ãããããã¹ãŠäžåããŸããã 2005幎ã«Boostã«ãã£ãŠæ¡çšããããã®åŸã倿°ã®BoostãŠãŒã¶ãŒã«ãã£ãŠãã¹ããããæ¬¡ã®ãããªå€ãã®ãããžã§ã¯ãã§äœ¿çšãããŠããŸãã
- Remoboã䜿çšãããšãç¬èªã®IPNãäœæã§ããŸã
- libtorrentã¯ãBittorrentã¯ã©ã€ã¢ã³ããå®è£ ããã©ã€ãã©ãªã§ã
- PokerTHã¯ãLANããã³ã€ã³ã¿ãŒãããããµããŒãããããŒã«ãŒã²ãŒã ã§ã
Boost.Asioã¯ããããã¯ãŒã¯ã ãã§ãªããã·ãªã¢ã«COMããŒãããã¡ã€ã«ãªã©ã«ãæ©èœããå ¥åºåã®æŠå¿µãããŸãæœè±¡åããŸãã ããã«ãå ¥åãŸãã¯åºåããã°ã©ãã³ã°ãåæãŸãã¯éåæã«ããããšãã§ããŸãã
read(stream, buffer [, extra options]) async_read(stream, buffer [, extra options], handler) write(stream, buffer [, extra options]) async_write(stream, buffer [, extra options], handler)
åã®ã³ãŒãã¹ããããã§èŠãããšãã§ããããã«ã颿°ã¯ã¹ããªãŒã ã®ã€ã³ã¹ã¿ã³ã¹ãåãå ¥ããŸããããã¯äœã§ãããŸããŸããïŒãœã±ããã ãã§ãªããèªã¿åããšæžã蟌ã¿ãå¯èœã§ãïŒã
ãã®ã©ã€ãã©ãªã¯ç§»æ€æ§ããããã»ãšãã©ã®ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã§å®è¡ããã1000ãè¶ ããåææ¥ç¶ã§ååã«æ¡åŒµã§ããŸãã ãããã¯ãŒã¯éšåã¯ãBSDïŒBerkeley Software DistributionïŒãœã±ããã®ãã©ãã¯ãŒã§ããã TCPïŒäŒéå¶åŸ¡ãããã³ã«ïŒãœã±ãããUDPïŒãŠãŒã¶ãŒããŒã¿ã°ã©ã ãããã³ã«ïŒãœã±ãããIMCPïŒã€ã³ã¿ãŒãããå¶åŸ¡ã¡ãã»ãŒãžãããã³ã«ïŒãœã±ãããæäœããããã®APIãæäŸãããŸããã©ã€ãã©ãªãæ¡åŒµå¯èœãªãããå¿ èŠã«å¿ããŠç¬èªã®ãããã³ã«ã«é©åã§ããŸãã ã
ç©èª
Boost.Asioã¯ã2003幎ã®éçºéå§åŸã2005幎12æã«Boost 1.35ã§æ¡çšãããŸããã åäœè ã¯Christopher M. Kohlhoffã§ãããchris @ kohlhoff.comã§é£çµ¡ã§ããŸãã
ã©ã€ãã©ãªã¯ã次ã®ãã©ãããã©ãŒã ãšã³ã³ãã€ã©ã§ãã¹ããããŠããŸãã
- Visual C ++ 7.1以éã䜿çšãã32ãããããã³64ãããã®Windows
- MinGWã䜿çšããWindows
- Cygwinã䜿çšããWindowsïŒ
__USE_232_SOCKETS
å®çŸ©ãããŠããããšã確èªããŠ__USE_232_SOCKETS
ïŒ - g ++ 3.3以éã䜿çšãã2.4ããã³2.6ã«ãŒãã«ããŒã¹ã®Linux
- g ++ 3.3以éã䜿çšããSolaris
- g ++ 3.3以éã䜿çšããMAC OS X 10.4+
ãŸããAIX 5.3ãHP-UX 11i v3ãQNX Neutrino 6.3ãSolarisãªã©ã®ãã©ãããã©ãŒã ã§åäœããSun Studio 11 +ãTrue64 v5.1ãWindowsãBorland C ++ 5.9.2+ïŒ www詳现ã«ã€ããŠã¯.boost.org ïŒã
äŸåé¢ä¿
Boost.Asioã¯æ¬¡ã®ã©ã€ãã©ãªã«äŸåããŠããŸãã
- Boost.SystemïŒãã®ã©ã€ãã©ãªã¯ãBoostã©ã€ãã©ãªïŒhttp://www.boost.org/doc/libs/1_51_0/doc/html/boost_system/index.htmlïŒã®ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãµããŒããæäŸããŸãã
- Boost.RegexïŒãã®ã©ã€ãã©ãªïŒãªãã·ã§ã³ïŒã¯ã
boost::regex
ãã©ã¡ãŒã¿ãŒãåãread_until()
ãŸãã¯async_read_until()
ã䜿çšããå Žåã«äœ¿çšãããŸã - Boost.DateTimeïŒãã®ã©ã€ãã©ãªïŒãªãã·ã§ã³ïŒã¯ãBoost.Asioã¿ã€ããŒã䜿çšããå Žåã«äœ¿çšãããŸã
- OpenSSLïŒãã®ã©ã€ãã©ãªïŒãªãã·ã§ã³ïŒã¯ãBoost.AsioãæäŸããSSLãµããŒãã䜿çšããããšã«ããå Žåã«äœ¿çšãããŸãã
Buost.Asioãã«ã
Boost.Asioã¯çŽç²ãªããããŒã©ã€ãã©ãªã§ãã ãã ããã³ã³ãã€ã©ãšããã°ã©ã ã®ãµã€ãºã«ãã£ãŠã¯ãBoost.AsioããœãŒã¹ãã¡ã€ã«ãšããŠäœæããããšãéžæã§ããŸãã ããã«ãããã³ã³ãã€ã«æéãççž®ã§ããŸãã ããã¯ãæ¬¡ã®æ¹æ³ã§å®è¡ã§ããŸãã
-
#include <boost/asio/impl/src.hpp>
ã䜿çšãããã¡ã€ã«ã®1#include <boost/asio/impl/src.hpp>
ïŒSSLã䜿çšããå Žåã¯#include <boost/asio/ssl/impl/src.hpp>
ïŒ - ãã¹ãŠã®ãœãŒã¹ãã¡ã€ã«ã§
#define BOOST_ASIO_SEPARATE_COMPILATION
ã䜿çšãã
Boost.Asioã¯Boost.Systemã«äŸåããå¿ ãããBoost.Regexã«äŸåããããã§ã¯ãªãããšã«æ³šæããŠãã ããããããã£ãŠãå°ãªããšã次ã®ã³ãŒãã䜿çšããŠããŒã¹ãã©ã€ãã©ãªãæ§ç¯ããå¿ èŠããããŸãã
bjam âwith-system âwith-regex stage
ãã¹ãããã«ãããå Žåã¯ã次ã®ã³ãŒãã䜿çšããå¿ èŠããããŸãã
bjam âwith-system âwith-thread âwith-date_time âwith-regex âwithserialization stage
ã©ã€ãã©ãªã«ã¯ãæ¬æžã§æäŸãããŠããäŸãšãšãã«ããã§ãã¯ã¢ãŠãã§ããå€ãã®äŸãä»å±ããŠããŸãã
éèŠãªãã¯ã
èšå®ãããŠããå Žåã¯
BOOST_ASIO_DISABLE_THREADS
䜿çšããŸãã Boostãã¹ããªãŒã ãµããŒãä»ãã§ã³ã³ãã€ã«ãããŠãããã©ããã«é¢ä¿ãªããBoost.Asioã®ã¹ããªãŒã ãµããŒããç¡å¹ã«ããŸãã
åævséåæ
ãŸããéåæããã°ã©ãã³ã°ã¯åæããã°ã©ãã³ã°ãšã¯å€§ããç°ãªããŸãã åæããã°ã©ãã³ã°ã§ã¯ããœã±ããSããã®èªã¿åãïŒèŠæ±ïŒããœã±ãããžã®æžã蟌ã¿ïŒå¿çïŒãªã©ããã¹ãŠã®æäœãé çªã«å®è¡ããŸãã åæäœããããã¯ãããŠããŸãã æäœã¯ãããã¯ããŠããããããœã±ããã®èªã¿åããŸãã¯æžã蟌ã¿äžã«ã¡ã€ã³ããã°ã©ã ãäžæããªãããã«ãéåžžãå ¥å/åºåãœã±ãããåŠçãã1ã€ä»¥äžã®ã¹ã¬ãããäœæããŸãã ãããã£ãŠãåæãµãŒããŒ/ã¯ã©ã€ã¢ã³ãã¯éåžžãã«ãã¹ã¬ããã§ãã
äžæ¹ãéåæããã°ã©ã ã¯ã€ãã³ãé§ååã§ãã æäœãéå§ããŸããããã€çµäºãããããããŸããã æäœã®å®äºæã«æäœã®çµæãšãšãã«APIã«ãã£ãŠåŒã³åºããã
callback
颿°ãæäŸã
callback
ã ã°ã©ãã£ã«ã«ãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ãŒã¹ã¢ããªã±ãŒã·ã§ã³ãäœæããããã®ããã¢ã®ã¯ãã¹ãã©ãããã©ãŒã ã©ã€ãã©ãªã§ããQTã®è±å¯ãªçµéšãæã€ããã°ã©ããŒã«ãšã£ãŠãããã¯2çªç®ã®æ§è³ªã§ãã ãããã£ãŠãéåæããã°ã©ãã³ã°ã§ã¯ãè€æ°ã®ã¹ã¬ãããçšæããå¿ èŠã¯ãããŸããã
ãããžã§ã¯ãã®åææ®µéïŒã§ããã°æåïŒã§ãã©ã¡ãã®ã¢ãããŒãã䜿çšããããæ±ºå®ããå¿ èŠããããŸããåæã®åãæ¿ããšéåæã®åãæ¿ãã¯ãéäžã§ã®åãæ¿ããé£ããããšã©ãŒãçºçããããããã§ãã APIã倧ããç°ãªãã ãã§ãªããããã°ã©ã ã®ã»ãã³ãã£ã¯ã¹ãå€§å¹ ã«å€æŽãããŸãïŒéåžžãéåæãããã¯ãŒã¯ã¯åæãããã¯ãŒã¯ããããã¹ããšãããã°ãå°é£ã§ãïŒã ããããã³ã°åŒã³åºããšå€ãã®ã¹ã¬ããïŒéåžžã¯åæãç°¡åïŒãŸãã¯å°æ°ã®ã¹ã¬ãããšã€ãã³ãïŒéåžžã¯éåæãããè€éïŒã䜿çšããåã«èããŠãã ããã
åæã¯ã©ã€ã¢ã³ãã®ç°¡åãªäŸã次ã«ç€ºããŸãã
using boost::asio; io_service service; ip::tcp::endpoint ep( ip::address::from_string("127.0.0.1"), 2001); ip::tcp::socket sock(service); sock.connect(ep);
ãŸããããã°ã©ã ã«ã¯
io_service
ã€ã³ã¹ã¿ã³ã¹ãå¿ èŠã§ãã Boost.Asioã¯
io_service
ã䜿çšããŠããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã®I / OãµãŒãã¹ãšéä¿¡ããŸãã éåžžã
io_service
ã€ã³ã¹ã¿ã³ã¹ã¯1ã€ã§ååã§ãã æ¬¡ã«ãæ¥ç¶ããã¢ãã¬ã¹ãšããŒããäœæããŸãã ãœã±ãããäœæããŸãã ãœã±ãããã¢ãã¬ã¹ãšããŒãã«æ¥ç¶ããŸãã
//Here is a simple synchronous server:using boost::asio; typedef boost::shared_ptr<ip::tcp::socket> socket_ptr; io_service service; ip::tcp::endpoint ep( ip::tcp::v4(), 2001)); // listen on 2001 ip::tcp::acceptor acc(service, ep); while ( true) { socket_ptr sock(new ip::tcp::socket(service)); acc.accept(*sock); boost::thread( boost::bind(client_session, sock)); } void client_session(socket_ptr sock) { while ( true) { char data[512]; size_t len = sock->read_some(buffer(data)); if ( len > 0) write(*sock, buffer("ok", 2)); } }
ç¹°ãè¿ããŸãããæåã®ããã°ã©ã ã«ã¯å°ãªããšã1ã€ã®
io_service
ã€ã³ã¹ã¿ã³ã¹ãå¿ èŠã§ãã æ¬¡ã«ããªãã¹ã³ããããŒããæå®ããŠãã¢ã¯ã»ãã¿ãŒïŒã¬ã·ãŒããŒïŒãäœæããŸããããã¯ãã¯ã©ã€ã¢ã³ãæ¥ç¶ãåãå ¥ãã1ã€ã®ãªããžã§ã¯ãã§ãã
次ã®ã«ãŒãã§ã¯ããããŒãœã±ãããäœæããã¯ã©ã€ã¢ã³ããæ¥ç¶ããã®ãåŸ ã¡ãŸãã æ¥ç¶ã確ç«ããããããã®æ¥ç¶ãåŠçããã¹ã¬ãããäœæããŸãã
ã¹ããªãŒã ã®
client_session
颿°ã§ã¯
client_session
ã¯ã©ã€ã¢ã³ãã®ãªã¯ãšã¹ãããªãã¹ã³ããããããè§£éããŠå¿çããŸãã
åçŽãªéåæã¯ã©ã€ã¢ã³ããäœæããã«ã¯ã次ã®ãããªããšãè¡ããŸãã
using boost::asio; io_service service; ip::tcp::endpoint ep( ip::address::from_string("127.0.0.1"), 2001); ip::tcp::socket sock(service); sock.async_connect(ep, connect_handler); service.run(); void connect_handler(const boost::system::error_code & ec) { // here we know we connected successfully // if ec indicates success }
ããã°ã©ã ã«ã¯ãå°ãªããšã1ã€ã®
io_service
ã€ã³ã¹ã¿ã³ã¹ãå¿ èŠã§ãã ãœã±ãããæ¥ç¶ããŠäœæããå Žæãæå®ããŸãã ãã®åŸãæ¥ç¶ã確ç«ããããšããã«ãéåæã§ã¢ãã¬ã¹ãšããŒãã«æ¥ç¶ãããŸãïŒããããã³ãã©ãŒã®å®äºã§ãïŒãã€ãŸãã
connect_handler
ãåŒã³åºãããŸãã
connect_handler
åŒã³åºããåŸããšã©ãŒã³ãŒãïŒ
ec
ïŒã確èªããæåããå Žåã¯ããµãŒããŒã«éåæã§æžã蟌ãããšãã§ããŸãã
service.run()
éåææäœãããéãã
service.run()
ã«ãŒããå®è¡ãããããšã«æ³šæããŠãã ããã åã®äŸã§ã¯ããã®ãããªæäœã¯
async_connect
ãœã±ããã®ã¿ã§ãã ãã®åŸã
service.run()
ã¯çµäºããŸãã
åéåææäœã«ã¯ãæäœã®å®äºæã«åŒã³åºããã颿°ã§ãããã¬ãŒãªã³ã°ãã³ãã©ãŒããããŸãã
次ã®ã³ãŒãã¯ãåçŽãªéåæãµãŒããŒã§ãã
using boost::asio; typedef boost::shared_ptr<ip::tcp::socket> socket_ptr; io_service service; ip::tcp::endpoint ep( ip::tcp::v4(), 2001)); // listen on 2001 ip::tcp::acceptor acc(service, ep); socket_ptr sock(new ip::tcp::socket(service)); start_accept(sock); service.run(); void start_accept(socket_ptr sock) { acc.async_accept(*sock, boost::bind( handle_accept, sock, _1) ); } void handle_accept(socket_ptr sock, const boost::system::error_code & err) { if ( err) return; // at this point, you can read/write to the socket socket_ptr sock(new ip::tcp::socket(service)); start_accept(sock); }
åã®ã³ãŒãã¹ããããã§ã¯ããŸãã
io_service
ã€ã³ã¹ã¿ã³ã¹ãäœæããŸãã æ¬¡ã«ããªãã¹ã³ããããŒããæå®ããŸãã æ¬¡ã«ãã¢ã¯ã»ãã¿ãŒïŒã¯ã©ã€ã¢ã³ãæ¥ç¶ãåä¿¡ããããã®ãªããžã§ã¯ãïŒãäœæãããããŒãœã±ãããäœæããŠã¯ã©ã€ã¢ã³ãæ¥ç¶ãéåæã«åŸ æ©ããŸãã
æåŸã«ãéåæã®
service.run()
ã«ãŒããå®è¡ããŸãã ã¯ã©ã€ã¢ã³ããæ¥ç¶ãããšã
handle_accept
ã
handle_accept
ïŒ
async_accept
ãåŒã³åºãæåŸã®ãã³ãã©ãŒïŒã ãšã©ãŒããªããã°ããã®ãœã±ãããèªã¿åã/æžãèŸŒã¿æäœã«äœ¿çšã§ããŸãã
ãœã±ããã䜿çšããåŸãæ°ãããœã±ãããäœæãã
start_accept()
å床åŒã³åºããŸããããã«ããããã¯ã©ã€ã¢ã³ããæ¥ç¶ããã®ãåŸ ã€ãåæ§ã®éåææäœã远å ããã
service.run()
ãµã€ã¯ã«ãããžãŒã®ãŸãŸã«ãªããŸãã
ãšã©ãŒã³ãŒãã®äŸå€
Boost.Asioã§ã¯ãäŸå€ãšãšã©ãŒã³ãŒãã®äž¡æ¹ã䜿çšã§ããŸãã ãã¹ãŠã®åæé¢æ°ã«ã¯ããšã©ãŒã®çµæãšããŠäŸå€ãã¹ããŒãããããšã©ãŒã³ãŒããè¿ããããããªãŒããŒããŒãããããŸãã 颿°ãã¯ã©ãã·ã¥ãããšã
boost::system::system_error
ãšã©ãŒãã¹ããŒãããŸãã
using boost::asio; ip::tcp::endpoint ep; ip::tcp::socket sock(service); sock.connect(ep); // Line 1 boost::system::error_code err; sock.connect(ep, err); // Line 2
åã®ã³ãŒãã§ã¯ã
sock.connect(ep)
ã¯ãšã©ãŒã®å Žåã«äŸå€ãã¹ããŒãã
sock.connect(ep, err)
ã¯ãšã©ãŒã³ãŒããè¿ããŸãã
次ã®ã³ãŒãã¹ãããããã芧ãã ããã
try { sock.connect(ep); } catch(boost::system::system_error e) { std::cout << e.code() << std::endl; }
次ã®ã³ãŒãã¹ããããã¯ãåã®ãã®ãšäŒŒãŠããŸãã
boost::system::error_code err; sock.connect(ep, err); if ( err) std::cout << err << std::endl;
éåæé¢æ°ã䜿çšããå Žåããããã¯ãã¹ãŠãã³ãŒã«ããã¯é¢æ°ã§ãã§ãã¯ã§ãããšã©ãŒã³ãŒããè¿ããŸãã éåæé¢æ°ã¯äŸå€ãã¹ããŒããããšã¯ãªãããããè¡ãæå³ã¯ãããŸããã ãããŠã誰ã圌ãæãŸããã§ããããïŒ
åæé¢æ°ã§ã¯ãäŸå€ãšãšã©ãŒã³ãŒãã®äž¡æ¹ïŒå¿ èŠãªæ¹ïŒã䜿çšã§ããŸãããè€æ°äœ¿çšã§ããŸãã ããããæ··åšããããšãåé¡ãçºçããããã¯ã©ãã·ã¥ãããããå¯èœæ§ããããŸãïŒèª€ã£ãŠäŸå€ã®åŠçãå¿ããå ŽåïŒã ã³ãŒããè€éãªå ŽåïŒãœã±ãããžã®èªã¿åã/æžãèŸŒã¿æ©èœãåŒã³åºãããïŒãããããäŸå€ã䜿çšãã
try {} catch
ãããã¯ã§èªã¿åãããã³æžãèŸŒã¿æ©èœãå®è¡ããããšããå§ãããŸãã
void client_session(socket_ptr sock) { try { ... } catch ( boost::system::system_error e) { // handle the error } }
ãšã©ãŒã³ãŒãã䜿çšãããšã次ã®ã³ãŒããã©ã°ã¡ã³ãã«ç€ºãããã«ãæ¥ç¶ããã€éããããããæç¢ºã«ç¢ºèªã§ããŸãã
char data[512]; boost::system::error_code error; size_t length = sock.read_some(buffer(data), error); if (error == error::eof) return; // Connection closed
Boost.Asioã®ãã¹ãŠã®ãšã©ãŒã³ãŒãã¯ã
boost::asio::error
åå空éã«ãããŸãïŒé害ãèŠã€ããããã«å®å šãªæ€çŽ¢ãè¡ãããå ŽåïŒã 詳现ã«ã€ããŠã¯ã
boost/asio/error.hpp
ãåç §ã§ããŸãã
Boost.Asioã®ã¹ããªãŒã
Boost.Asioã®ã¹ããªãŒã ã«é¢ããŠã¯ã次ã®ããšã«ã€ããŠè©±ãå¿ èŠããããŸãã
-
io_service
ïŒio_service
ã¯ã©ã¹ã¯ã¹ã¬ããã»ãŒãã§ãã è€æ°ã®ã¹ã¬ãããio_service::run()
åŒã³åºãããšãã§ããŸãã ã»ãšãã©ã®å Žåãããããåäžã®ã¹ã¬ããããio_service::run()
åŒã³åºãããã颿°ã¯ãã¹ãŠã®ããããã³ã°éåæé¢æ°ãå®è¡ããããŸã§åŸ æ©ããŸãã ãã ããè€æ°ã®ã¹ã¬ããããio_service::run()
åŒã³åºãããšãã§ããŸãã ããã«ãããio_service::run()
ãåŒã³åºããã¹ãŠã®ã¹ã¬ããããããã¯ãããŸãã ãã¹ãŠã®ã³ãŒã«ããã¯é¢æ°ã¯ãio_service::run()
ãåŒã³åºããã¹ã¬ããã®ãã€ã«ã¹ããŒã³ã®ã³ã³ããã¹ãã§åŒã³åºãããŸãã ãŸãã1ã€ã®ã¹ã¬ããã§ã®ã¿io_service::run()
ãåŒã³åºããå Žåããã¹ãŠã®ã³ãŒã«ããã¯é¢æ°ãç¹å®ã®ã¹ã¬ããã®ã³ã³ããã¹ãã§åŒã³åºãããããšãæå³ããŸãã -
socket
ïŒsocket
ã¯ã©ã¹ã¯ã¹ã¬ããã»ãŒãã§ã¯ãããŸããã ãããã£ãŠãããã¹ããªãŒã ã®ãœã±ããããã®èªã¿åããå¥ã®ã¹ããªãŒã ãžã®æžã蟌ã¿ãªã©ã®ç¶æ³ãåé¿ããå¿ èŠããããŸãïŒBoost.Asioã¯ãã¡ããããããäžè¬çã«æšå¥šãããŸãïŒã -
utility
ïŒutility
ã¯ã©ã¹ã¯éåžžãè€æ°ã®ã¹ã¬ããã§äœ¿çšããæå³ããªããã¹ã¬ããã»ãŒãã§ã¯ãããŸããã ãããã®ã»ãšãã©ã¯çæé䜿çšãããåŸãç¯å²å€ã«ãªããŸãã
Boost.Asioã©ã€ãã©ãªèªäœã¯ããŠãŒã¶ãŒã®ã¹ã¬ãã以å€ã«ãè€æ°ã®ã¹ã¬ããã䜿çšã§ããŸããããããã®ã¹ã¬ããããã³ãŒããåŒã³åºãããªãããšãä¿èšŒãããŠããŸãã ããã¯ãã³ãŒã«ããã¯é¢æ°ãã
io_service::run()
åŒã³åºãããã¹ã¬ããã§ã®ã¿åŒã³åºãããããšãæå³ããŸãã
ãããã¯ãŒã¯ã ãã§ãªã
Boost.Asioã¯ããããã¯ãŒã¯ã«å ããŠä»ã®I / Oãªããžã§ã¯ããæäŸããŸãã
Boost.Asioã§ã¯ã
SIGTERM
ïŒããã°ã©ã ã®çµäºïŒã
SIGINT
ïŒã·ã°ãã«ã®äžæïŒãSIGSEGVïŒã»ã°ã¡ã³ãã®éåïŒãªã©ã®
SIGTERM
ã䜿çšã§ããŸãã
signal_set
ã®ã€ã³ã¹ã¿ã³ã¹ãäœæããéåæçã«åŸ æ©ããã·ã°ãã«ãæå®ããŸãããã®ãã¡ã®1ã€ãçºçãããšãéåæãã³ãã©ãŒãåŒã³åºãããŸãã
void signal_handler(const boost::system::error_code & err, int signal) { // log this, and terminate application } boost::asio::signal_set sig(service, SIGINT, SIGTERM); sig.async_wait(signal_handler);
SIGINT
çæããããšã
signal_handler
ãã³ãã©ãŒã«å°éããŸãã
Boost.Asioã䜿çšãããšãã·ãªã¢ã«ããŒãã«ç°¡åã«æ¥ç¶ã§ããŸãã Windowsã§ã¯COM7ããŒãåãPOSIXãã©ãããã©ãŒã ã§ã¯/ dev / ttyS0ïŒ
io_service service; serial_port sp(service, "COM7");
éããåŸã次ã®ã³ãŒããã©ã°ã¡ã³ãã«ç€ºãããã«ãããŒãããŒã¿è»¢éé床ãããªãã£ãã¹ãããããããªã©ã®ãã©ã¡ãŒã¿ãŒãèšå®ã§ããŸãã
serial_port::baud_rate rate(9600); sp.set_option(rate);
ããŒããéããŠããå Žåã¯ãã¹ããªãŒã ã§åŠçã§ããŸããããã«ãã·ãªã¢ã«ããŒããžã®èªã¿åãããã³/ãŸãã¯æžã蟌ã¿çšã®ç¡æã®é¢æ°ã䜿çšããããšããå§ãããŸããããšãã°ã次ã®äŸïŒ
char data[512]; read(sp, buffer(data, 512));
Boost.Asioã§ã¯ã以äžã«ç€ºãããã«ãWindowsãã¡ã€ã«ã«æ¥ç¶ãã
read()
ã
asyn_read()
ãªã©ã®ç¡æã®é¢æ°ãåã³äœ¿çšããããšãã§ããŸãã
HANDLE h = ::OpenFile(...); windows::stream_handle sh(service, h); char data[512]; read(h, buffer(data, 512));
次ã®ãã©ã°ã¡ã³ãã®ããã«ããã€ããæšæºI / OãããŸããŸãªããã€ã¹ïŒéåžžã®ãã¡ã€ã«ã§ã¯ãªãïŒãªã©ã®POSIXãã¡ã€ã«èšè¿°åã§ãåãããšãã§ããŸãã
posix::stream_descriptor sd_in(service, ::dup(STDIN_FILENO)); char data[512]; read(sd_in, buffer(data, 512));
ã¿ã€ããŒ
äžéšã®I / Oæäœã«ã¯ãå®äºããæéã®å¶çŽãããå ŽåããããŸãã ããã¯éåææäœã«ã®ã¿é©çšã§ããŸãïŒåæããã¯ã«ã¯æéå¶éããªãããïŒã ããšãã°ãããŒãããŒããã®æ¬¡ã®ã¡ãã»ãŒãžã¯100ããªç§ã§å±ããŸãã
bool read = false; void deadline_handler(const boost::system::error_code &) { std::cout << (read ? "read successfully" : "read failed") << std::endl; } void read_handler(const boost::system::error_code &) { read = true; } ip::tcp::socket sock(service); ⊠read = false; char data[512]; sock.async_read_some(buffer(data, 512)); deadline_timer t(service, boost::posix_time::milliseconds(100)); t.async_wait(&deadline_handler); service.run();
åã®ã³ãŒããã©ã°ã¡ã³ãã§ã¯ãæéã®çµäºåã«ããŒã¿ãèªã¿åããšã
read
true
ã«èšå®ãããããŒãããŒã¯æééãã«å°çããŸããã ãã以å€ã®å Žåã
deadline_handler
ãåŒã³åºããããšã
read
ã¯
false
ã«èšå®ããããŸãŸã«ãªã
false
ãã€ãŸããå²ãåœãŠãããæéã®çµãããŸã§é£çµ¡ããããŸããã
Boost.Asioã§ã¯åæã¿ã€ããŒã䜿çšã§ããŸãããéåžžã¯åçŽãª
sleep
æäœãšåçã§ãã è¡ã®
boost::this_thread::sleep(500);
次ã®ã¹ããããã§ãåãããšãã§ããŸãã
deadline_timer t(service, boost::posix_time::milliseconds(500)); t.wait();
ã¯ã©ã¹io_service
Boost.Asioã䜿çšããã³ãŒãã®ã»ãšãã©ãio_serviceã®ã€ã³ã¹ã¿ã³ã¹ã䜿çšããããšãæ¢ã«èŠ
io_service
ã
io_service
ã¯ãã©ã€ãã©ãªã§æãéèŠãªã¯ã©ã¹ã§ããããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãåŠçãããã¹ãŠã®éåææäœã®çµäºãåŸ æ©ããå®äºãããšããã®ãããªåæäœã®ãã³ãã©ãŒãåŒã³åºããŸãã
ã¢ããªã±ãŒã·ã§ã³ãåæçã«äœæããå Žåããã®ã»ã¯ã·ã§ã³ã§èª¬æããå 容ãå¿é ããå¿ èŠã¯ãããŸããã
io_service
ã€ã³ã¹ã¿ã³ã¹
io_service
ããã€ãã®æ¹æ³
io_service
䜿çšã§ããŸãã æ¬¡ã®äŸã§ã¯ã3ã€ã®éåææäœã2ã€ã®æ¥ç¶ããããœã±ãããããã³åŸ æ©ã¿ã€ããŒããããŸãã
- 1ã€ã®
io_service
ã€ã³ã¹ã¿ã³ã¹ãš1ã€ã®ãã³ãã©ãŒãæã€1ã€ã®ã¹ã¬ããïŒ
io_service service_; // all the socket operations are handled by service_ ip::tcp::socket sock1(service_); // all the socket operations are handled by service_ ip::tcp::socket sock2(service_); sock1.async_connect( ep, connect_handler); sock2.async_connect( ep, connect_handler); deadline_timer t(service_, boost::posix_time::seconds(5)); t.async_wait(timeout_handler); service_.run();
- 1ã€ã®
io_service
ã€ã³ã¹ã¿ã³ã¹ãšè€æ°ã®ãã³ãã©ãŒãæã€å€ãã®ã¹ã¬ããïŒ
io_service service_; ip::tcp::socket sock1(service_); ip::tcp::socket sock2(service_); sock1.async_connect( ep, connect_handler); sock2.async_connect( ep, connect_handler); deadline_timer t(service_, boost::posix_time::seconds(5)); t.async_wait(timeout_handler); for ( int i = 0; i < 5; ++i) boost::thread( run_service); void run_service() { service_.run(); }
-
io_service
è€æ°ã®ã€ã³ã¹ã¿ã³ã¹ãšè€æ°ã®ãã³ãã©ãŒãæã€å€ãã®ã¹ã¬ããïŒ
io_service service_[2]; ip::tcp::socket sock1(service_[0]); ip::tcp::socket sock2(service_[1]); sock1.async_connect( ep, connect_handler); sock2.async_connect( ep, connect_handler); deadline_timer t(service_[0], boost::posix_time::seconds(5)); t.async_wait(timeout_handler); for ( int i = 0; i < 2; ++i) boost::thread( boost::bind(run_service, i)); void run_service(int idx) { service_[idx].run(); }
ãŸããåãã¹ã¬ããã«è€æ°ã®
io_service
ã€ã³ã¹ã¿ã³ã¹ã
io_service
ããšã¯ã§ããŸããã æ¬¡ã®ã³ãŒããèšè¿°ããããšã¯æå³ããããŸããã
for ( int i = 0; i < 2; ++i) service_[i].run();
åã®ã»ã¯ã·ã§ã³ã®ã³ãŒãã¯æå³ããããŸãããæåã®ãµãŒãã¹ãéãããšãã«
service_[1].run()
ã
service_[0].run()
ãå¿ èŠãšããããã§ãã ãã®ããããã¹ãŠã®éåæ
service_[1]
æäœã¯åŠçãåŸ æ©ããå¿ èŠããããŸãããããã¯ãå§ãã§ããŸããã
åè¿°ã®3ã€ã®äŸãã¹ãŠã§ã3ã€ã®éåææäœãå®äºããã®ãåŸ ã¡ãŸããã éãã説æããããã«ããã°ããããŠæäœ1ãçµäºããæäœ2ããã®çŽåŸã«çµäºãããšä»®å®ããŸãã
æåã®ã±ãŒã¹ã§ã¯ã1ã€ã®ã¹ã¬ããã§3ã€ã®æäœãã¹ãŠãå®äºããã®ãåŸ ã£ãŠããŸãã æåã®æäœãå®äºãããããã®ãã³ãã©ãŒãåŒã³åºããŸãã æäœ2ãæåã®æäœã®çŽåŸã«çµäºããå Žåã§ããæåã®æäœã®å®äºåŸããã³ãã©ãŒãåŒã³åºãããã«2ç§éåŸ æ©ããå¿ èŠããããŸãã
2çªç®ã®ã±ãŒã¹ã§ã¯ã2ã€ã®ã¹ã¬ããã§3ã€ã®æäœãå®äºããã®ãåŸ ã£ãŠããŸãã æåã®æäœã®å®äºåŸãæåã®ã¹ã¬ããã§ãã³ãã©ãŒãåŒã³åºããŸããæäœ2ãå®äºãããšããã«ãããã«2çªç®ã®ã¹ã¬ããã§ãã³ãã©ãŒãåŒã³åºããŸãïŒæåã®ã¹ã¬ãããããžãŒç¶æ ã§ããã³ãã©ãŒãæåã®æäœãå®äºããã®ãåŸ ã£ãŠããéã2çªç®ã®ã¹ã¬ããã¯ä»ã®æäœã®å®äºã«èªç±ã«å¿çã§ããŸãïŒã
åŸè ã®å Žåãæäœ1ã
connect
k
sock1
ã§æäœ2
connect
kã®
sock2
å Žåãã¢ããªã±ãŒã·ã§ã³ã¯2çªç®ã®å Žåãšåæ§ã«åäœããŸããæåã®ã¹ã¬ããã¯ã®ãã³ãã©
connect
ãåŠçã
sock1
ã2çªç®ã®ã¹ã¬ããã¯ã®ãã³ãã©
connect
ãåŠçã
sock2
ãŸãããã ããfrom
sock1
ãæäœ1ã§ãã¿ã€ã ã¢ãŠã
deadline_timer t
ãæäœ2ã®å Žåãæåã®ã¹ã¬ããã¯
connect
from ã®ãã³ãã©ãŒãåŠçã
sock1
ãŸãããããã£ãŠãã¿ã€ã ã¢ãŠããã³ãã©ãŒ
deadline_timer t
ã¯ããã³ãã©ãŒã®åäœãå®äºãããŸã§åŸ æ©ããå¿ èŠããããŸãã
connect
from
sock1
ïŒ1ç§åŸ æ©ïŒãæåã®ã¹ã¬ããã§ãã³ãã©ãŒãžã®æ¥ç¶
sock1
ãšã¿ã€ã ã¢ãŠããã³ãã©ãŒã®äž¡æ¹ãåŠçãããŸã
t
ã
åã®äŸããåŠã¶ã¹ãããšã¯æ¬¡ã®ãšããã§ãã
- åºæ¬çãªã¢ããªã±ãŒã·ã§ã³ã®ç¶æ³1ãè€æ°ã®ãã³ãã©ãŒãåæã«åŒã³åºãå¿ èŠãããå ŽåããŸãã¯ããããé çªã«åŒã³åºãå¿ èŠãããå Žåã¯ãåžžã«åé¡ãçºçããŸãã1ã€ã®ãã³ãã©ãŒã®çµäºã«æéããããå Žåãæ®ãã®ãã³ãã©ãŒã¯åŸ æ©ããå¿ èŠããããŸãã
- 2 . , . , . , -.
- 3 . , 2 . , (). , - (,
io_service::run()
)select/epoll
; , / . , , ( 1000 ).select/epoll
.
ã¢ããªã±ãŒã·ã§ã³ãç¶æ³3ã«ç§»è¡ãããšæãããå Žåã¯ãã³ãŒãã®ã»ã¯ã·ã§ã³ïŒãåŒã³åºãã³ãŒã
io_service::run()
ïŒãæ®ãã®ã³ãŒãããåé¢ãããŠããããšã確èªããŠãç°¡åã«å€æŽã§ããããã«ããŠãã ããã
æåŸã«ã
.run()
次ã®äŸã«ç€ºãããã«ãå¶åŸ¡ããæäœããã以äžãªãå Žåã¯åžžã«å®äºããããšãåžžã«å¿ããªãã§ãã ããã
io_service service_; tcp::socket sock(service_); sock.async_connect( ep, connect_handler); service_.run();
ãã®å Žåããœã±ãããæ¥ç¶ã確ç«ãããšããã«åŒã³åºãã
connect_handler
ãŠ
service.run()
çµäºããŸããä»äº
ã
service.run()
ç¶ãããå Žåã¯ã圌ã«ãã£ãšä»äºãæäŸããªããã°ãªããŸããããã®åé¡ã解決ããã«ã¯2ã€ã®æ¹æ³ããããŸãã1ã€ã®æ¹æ³ã¯ã
connect_handler
å¥ã®éåææäœãå®è¡ããŠè² è·ãå¢ããããšã§ãã
2çªç®ã®æ¹æ³ã¯ã次ã®ã³ãŒãã䜿çšããŠäœæ¥ã®äžéšãã·ãã¥ã¬ãŒãããããšã§ãã
typedef boost::shared_ptr<io_service::work> work_ptr; work_ptr dummy_work(new io_service::work(service_));
äžèšã®ã³ãŒã
service_.run()
ã¯ã
useservice_.stop()
ãŸãã¯ãåŒã³åºããŸã§ç¶ç¶ããŠåäœããŸã
dummy_work.reset(0); // destroy dummy_work
ã
ãŸãšã
Boost.Asioã¯ããããã¯ãŒã¯ããã°ã©ãã³ã°ãéåžžã«ç°¡åã«ããæŽç·Žãããã©ã€ãã©ãªã§ããçµã¿ç«ãŠã¯ç°¡åã§ãããã¯ãã®äœ¿çšãé¿ããéåžžã«ããŸãæ©èœããŸãããªã³/ãªããªãã·ã§ã³ãæå¹ã«ããããã«ããã€ãã®ãã¯ããæäŸãããŠããŸãããå¿ããŠã¯ãªããªãããšãããã€ããããŸãã
Boost.Asioã¯ãåæããã°ã©ãã³ã°ãšéåæããã°ã©ãã³ã°ã®äž¡æ¹ããµããŒãããŠããŸãããããã®2ã€ã®ã¢ãããŒãã¯éåžžã«ç°ãªããåãæ¿ãã¯éåžžã«è€éã§ãšã©ãŒãçºçãããããããã§ããã ãæ©ã1ã€ãéžæããå¿ èŠããããŸãã
åæã¢ãããŒããéžæããå ŽåãäŸå€ãšãšã©ãŒã³ãŒããéžæã§ããŸããäŸå€ãããšã©ãŒã³ãŒããžã®ç§»è¡ã¯éåžžã«ç°¡åã§ãã颿°åŒã³åºãïŒãšã©ãŒã³ãŒãïŒã«ãã1ã€ã®åŒæ°ã远å ããå¿ èŠããããŸãã
Boost.Asioã¯ãããã°ã©ãã³ã°ãããã¯ãŒã¯å°çšã§ã¯ãããŸããããã®ã©ã€ãã©ãªã«ã¯ãã·ã°ãã«ãã¿ã€ããŒãªã©ããã䟡å€ã®ããæ©èœãããã€ããããŸãã
次ã®ç« ã§ã¯ããããã¯ãŒã¯ãæäŸããBoost.Asioã®å€ãã®æ©èœãšã¯ã©ã¹ãæãäžããŸããããã«ãéåæããã°ã©ãã³ã°ã«é¢ããããã€ãã®ããªãã¯ãåŠã³ãŸãã
ããŠã仿¥ã¯ããã§ãã¹ãŠã§ããæ°ã«å ¥ã£ãå Žåã¯ã翻蚳ãç¶ããŸãããã¹ãŠã®ã³ã¡ã³ãã«ã€ããŠã¯ãã³ã¡ã³ããèšå ¥ããŠãã ããã
çããã«å¹žéãïŒ