ip::tcp::socket= basic_stream_socket
ip::udp::socket= basic_datagram_socket<ud
p>
ip::icmp::socket= basic_raw_socket
åææ©èœãšã©ãŒã³ãŒã
以äžã«ç€ºãããã«ããã¹ãŠã®åæé¢æ°ã«ã¯ãäŸå€ãã¹ããŒãããããšã©ãŒã³ãŒããè¿ããªãŒããŒããŒãããããŸãã
sync_func( arg1, arg2 ... argN);
ãã®ç« ã®æ®ãã®éšåã§ã¯ãå€ãã®åæé¢æ°ã«ã€ããŠèª¬æããŸãã ç©äºãåçŽã«ããããã«ããšã©ãŒã³ãŒããè¿ããªãŒããŒããŒãã®è¡šç€ºãçç¥ããŸãããããããã¯ååšããŸãã
ãœã±ããé¢æ°
ãã¹ãŠã®æ©èœã¯ããã€ãã®ã°ã«ãŒãã«åããããŸãã ãœã±ããã®çš®é¡ããšã«ãã¹ãŠã®æ©èœãå©çšã§ããããã§ã¯ãããŸããã ãã®ã»ã¯ã·ã§ã³ã®æåŸã«ãããªã¹ãã¯ãã©ã®æ©èœããœã±ããã®ã©ã®ã¯ã©ã¹ã«å±ããŠãããã瀺ããŸãã
ãã¹ãŠã®éåæé¢æ°ã¯å³åº§ã«å¿çããŸãããåæé¢æ°ã¯æäœãå®äºããåŸã«ã®ã¿å¿çããããšã«æ³šæããŠãã ããã
çµåãã€ã³ãã£ã³ã°é¢æ°
ãããã¯ãã¢ã¯ãã£ãã§ãããã©ããã«ãããããããœã±ããã«æ¥ç¶ãŸãã¯æ¥ç¶ãããœã±ãããåæããŠæ¥ç¶èŠæ±ãè¡ãé¢æ°ã§ãã
assign(protocol,socket)
ïŒãã®é¢æ°ã¯ãrawïŒèªç¶ïŒãœã±ããããœã±ããã€ã³ã¹ã¿ã³ã¹ã«å²ãåœãŠãŸãã ç¶æ¿ãããã³ãŒãã䜿çšããå ŽåïŒã€ãŸããçã®ãœã±ãããæ¢ã«äœæãããŠããå ŽåïŒã«äœ¿çšããŸããopen(protocol)
ïŒãã®é¢æ°ã¯ãæå®ãããIPãããã³ã«ïŒv4ãŸãã¯v6ïŒã§ãœã±ãããéããŸãã äž»ã«UDP / ICMPãœã±ãããŸãã¯ãµãŒããŒãœã±ããã«äœ¿çšããŸããbind(endpoint)
ïŒãã®é¢æ°ã¯ãã®ã¢ãã¬ã¹ã«é¢é£ä»ããããŠããŸããconnect(endpoint)
ïŒãã®é¢æ°ã¯ãã®ã¢ãã¬ã¹ã«åæçã«æ¥ç¶ããŸããasync_connect(endpoint)
ïŒãã®é¢æ°ã¯ããã®ã¢ãã¬ã¹ã«éåæçã«æ¥ç¶ããŸããis_open()
ïŒãœã±ãããéããŠããå Žåããã®é¢æ°ã¯trueãè¿ããŸããclose()
ïŒãã®é¢æ°ã¯ãœã±ãããéããŸãã ãã®ãœã±ããã®éåææäœã¯ããã«åæ¢ãã error::operation_aborted
ãšã©ãŒã³ãŒããè¿ããŸããshutdown(type_of_shutdown)
ïŒãã®é¢æ°ã¯ãåŒã³åºãã®çŽåŸã«send , receive
ãŸãã¯äž¡æ¹ã®æäœsend , receive
ç¡å¹ã«ããŸããcancel()
ïŒãã®é¢æ°ã¯ããã®ãœã±ããã®ãã¹ãŠã®éåææäœããã£ã³ã»ã«ããŸãã ãã®ãœã±ããã§ã®ãã¹ãŠã®éåææäœã¯ããã«å®äºãã error::operation_aborted
ãšã©ãŒã³ãŒããè¿ããŸãã
以äžã«å°ããªäŸã瀺ããŸãã
ip::tcp::endpoint ep( ip::address::from_string("127.0.0.1"), 80); ip::tcp::socket sock(service); sock.open(ip::tcp::v4()); sock.connect(ep); sock.write_some(buffer("GET /index.html\r\n")); char buff[1024]; sock.read_some(buffer(buff,1024)); sock.shutdown(ip::tcp::socket::shutdown_receive); sock.close();
èªã¿åã/æžã蟌ã¿æ©èœ
ãããã¯ããœã±ããã§å
¥åºåãå®è¡ããé¢æ°ã§ãã
éåæé¢æ°ã®å Žåããã³ãã©ãŒã«ã¯æ¬¡ã®ã·ã°ããã£void handler(const boost::system::error_code& e, size_t bytes);
ãã³ãã©ãŒããããŸãvoid handler(const boost::system::error_code& e, size_t bytes);
ã ããããæ©èœèªäœïŒ
async_receive(buffer, [flags,] handler)
ïŒãã®é¢æ°ã¯ããœã±ããããããŒã¿ãåä¿¡ããéåææäœãéå§ããŸããasync_read_some(buffer,handler)
ïŒãã®é¢æ°ã¯async_receive(buffer, handler)
ãšåçã§ããasync_receive_from(buffer, endpoint[, flags], handler)
ïŒãã®é¢æ°ã¯ãç¹å®ã®ã¢ãã¬ã¹ããã®ããŒã¿ã®éåæåä¿¡ãéå§ããŸããasync_send(buffer [, flags], handler)
ïŒãã®é¢æ°ã¯ããããã¡ãŒããã®éåæããŒã¿è»¢éã®æäœãéå§ããŸãasync_write_some(buffer, handler)
ïŒãã®é¢æ°ã¯async_send(buffer, handler)
ãšåçã§ããasync_send_to(buffer, endpoint, handler)
ïŒãã®é¢æ°ã¯ããããã¡ããç¹å®ã®ã¢ãã¬ã¹ã«ããŒã¿ãéåæçã«è»¢éããæäœãéå§ããŸããreceive(buffer [, flags])
ïŒãã®é¢æ°ã¯ããããã¡å
ã®ããŒã¿ãåæçã«åä¿¡ããŸãã ãã®æ©èœã¯ãããŒã¿ãå°çãå§ãããããšã©ãŒãçºçãããŸã§ãããã¯ãããŸããread_some(buffer)
ïŒãã®é¢æ°ã¯receive(buffer)
ãšåçã§ããreceive_from(buffer, endpoint [, flags])
ïŒãã®é¢æ°ã¯ããã®ãããã¡ãŒã®ç¹å®ã®ã¢ãã¬ã¹ããããŒã¿ãåæçã«åä¿¡ããŸãã ãã®é¢æ°ã¯ãããŒã¿ãå°çãå§ãããããšã©ãŒãçºçãããŸã§ãããã¯ãããŸããsend(buffer [, flags])
ïŒãã®é¢æ°ã¯ãããã¡ããããŒã¿ãåæçã«éä¿¡ããŸãã ããŒã¿ã®éä¿¡äžãŸãã¯ãšã©ãŒãçºçããå Žåããã®æ©èœã¯ãããã¯ãããŸããwrite_some(buffer)
ïŒãã®é¢æ°ã¯send(buffer)
ãšåçã§ããsend_to(buffer, endpoint [, flags])
ïŒãã®é¢æ°ã¯ããããã¡ãããã®ã¢ãã¬ã¹ã«ããŒã¿ãåæçã«è»¢éããŸãã ããŒã¿ã®éä¿¡äžãŸãã¯ãšã©ãŒãçºçããå Žåããã®æ©èœã¯ãããã¯ãããŸããavailable()
ïŒãã®é¢æ°ã¯ããããã¯ããã«åæçã«èªã¿åãããšãã§ãããã€ãæ°ãè¿ããŸãã
ãããã¡ã«ã€ããŠã¯è¿ãå°æ¥ã«èª¬æããŸãã ãã©ã°ãèŠãŠã¿ãŸãããã ãã©ã°ã®ããã©ã«ãå€ã¯0ã§ãããçµã¿åãããå¯èœã§ãã
ip::socket_type::socket::message_peek
ïŒãã®ãã©ã°ã¯ã¡ãã»ãŒãžã®ã¿ã調ã¹ãŸãã ã¡ãã»ãŒãžãè¿ãããŸããã次ã«ãããåŒã³åºããšãã¯ãã¡ãã»ãŒãžãèªãããã«åèªã¿åãããå¿
èŠããããŸããip::socket_type::socket::message_out_of_band
ïŒãã®ãã©ã°ã¯åž¯åå€ããŒã¿ãåŠçããŸãã OOBããŒã¿ã¯ãéåžžã®ããŒã¿ãããéèŠãšããŠããŒã¯ãããããŒã¿ã§ãã OOBããŒã¿ã®èª¬æã¯ããã®æ¬ã®ç¯å²å€ã§ããip::socket_type::socket::message_do_not_route
ïŒãã®ãã©ã°ã¯ãã«ãŒãã£ã³ã°ããŒãã«ã䜿çšããã«ã¡ãã»ãŒãžãéä¿¡ããå¿
èŠãããããšã瀺ããŸããip::socket_type::socket::message_end_of_record:
ãã®ãã©ã°ã¯ãããŒã¿ãèšé²ã®çµäºã«é¢ããããŒã«ãŒã§ããŒã¯ãããŠããããšã瀺ããŸãã ããã¯Windowsã§ã¯ãµããŒããããŠããŸããã
次ã®ã³ãŒããäœæããããšãããå Žåã¯ãããããmessage_peek
ã䜿çšããŸããã
char buff[1024]; sock.receive(buffer(buff), ip::tcp::socket::message_peek ); memset(buff,1024, 0);
以äžã¯ãç°ãªãã¿ã€ãã®ãœã±ããã«å¯ŸããŠåæçããã³éåæçã«èªã¿åãåœä»€ãäžããäŸã§ãã
- äŸ1ïŒTCPãœã±ãããžã®åæèªã¿åãããã³æžã蟌ã¿ïŒ
ip::tcp::endpoint ep( ip::address::from_string("127.0.0.1"), 80); ip::tcp::socket sock(service); sock.connect(ep); sock.write_some(buffer("GET /index.html\r\n")); std::cout << "bytes available " << sock.available() << std::endl; char buff[512]; size_t read = sock.read_some(buffer(buff));
- äŸ2ïŒUDPãœã±ãããžã®åæèªã¿åãããã³æžã蟌ã¿ïŒ
ip::udp::socket sock(service); sock.open(ip::udp::v4()); ip::udp::endpoint receiver_ep("87.248.112.181", 80); sock.send_to(buffer("testing\n"), receiver_ep); char buff[512]; ip::udp::endpoint sender_ep; sock.receive_from(buffer(buff), sender_ep);
receive_from
ã䜿çšããŠUDPãœã±ããããèªã¿åãå Žåãåã®äŸã«ç€ºãããã«ããšã³ããã€ã³ãã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ãŒã䜿çšããå¿
èŠãããããšã«æ³šæããŠãã ããã
- äŸ3ïŒUDPãµãŒããŒãœã±ããããã®éåæèªã¿åãïŒ
using namespace boost::asio; io_service service; ip::udp::socket sock(service); boost::asio::ip::udp::endpoint sender_ep; char buff[512]; void on_read(const boost::system::error_code & err, std::size_t read_bytes) { std::cout << "read " << read_bytes << std::endl; sock.async_receive_from(buffer(buff), sender_ep, on_read); } int main(int argc, char* argv[]) { ip::udp::endpoint ep( ip::address::from_string("127.0.0.1"), 8001); sock.open(ep.protocol()); sock.set_option(boost::asio::ip::udp::socket::reuse_ address(true)); sock.bind(ep); sock.async_receive_from(buffer(buff,512), sender_ep, on_read); service.run(); }
ãœã±ãã管ç
ãããã®é¢æ°ã¯ãè¿œå ã®ãœã±ãããã©ã¡ãŒã¿ãŒã§æ©èœããŸãã
get_io_service()
ïŒãã®é¢æ°ã¯ã io_service
ã§åãå
¥ããããio_service
ã€ã³ã¹ã¿ã³ã¹ãè¿ããŸããget_option(option)
ïŒãã®é¢æ°ã¯ãœã±ãããã©ã¡ãŒã¿ãŒãè¿ããŸãset_option(option)
ïŒãã®é¢æ°ã¯ãœã±ãããã©ã¡ãŒã¿ãŒãèšå®ããŸãio_control(cmd)
ïŒãã®é¢æ°ã¯ããœã±ããã§I / Oã³ãã³ããå®è¡ããŸãã
ãœã±ããã«ååŸ/èšå®ã§ãã次ã®ãã©ã¡ãŒã¿ãŒïŒ
å | å®çŸ© | çš®é¡ |
---|
broadcast | true ããããŒããã£ã¹ãã¡ãã»ãŒãžãèš±å¯ããŸã | ããŒã« |
debug | true ããœã±ããã¬ãã«ã®ãããã°ãèš±å¯ããŸã | ããŒã« |
do_not_route | true ãã«ãŒãã£ã³ã°ãé²æ¢ããããŒã«ã«ã€ã³ã¿ãŒãã§ã€ã¹ã®ã¿ã䜿çšããŸã | ããŒã« |
enable_connection_aborted | true å Žåãåæãããæ¥ç¶ãåæ¥ç¶ããŸã | ããŒã« |
keep_alive | true ã keep-alives éä¿¡ãkeep-alives | ããŒã« |
linger | true ãä¿åãããŠããªãå Žåããœã±ããã¯close() ã ãé
延ããŸã ããŒã¿ | ããŒã« |
receive_buffer_size | åä¿¡ãããã¡ãµã€ãº | int |
receive_low_watemark | å
¥åãœã±ãããåŠçãããšãã®æå°ãã€ãæ°ãæäŸããŸã | int |
reuse_address | true å Žåããœã±ããã¯ãã§ã«äœ¿çšãããŠããã¢ãã¬ã¹ã«é¢é£ä»ããããŠããå¯èœæ§ããããŸã | ããŒã« |
send_buffer_size | éä¿¡ãããã¡ãµã€ãº | int |
send_low_watermark | åºåãœã±ããã§éä¿¡ããæå°ãã€ãæ°ãæäŸããŸãã | int |
ip::v6_only | true ã䜿çšã§ããã®ã¯IPv6éä¿¡ã®ã¿ã§ãã | bool |
åååtypedef
ãœã±ãããŸãã¯ã¯ã©ã¹ã®å
éštypedef
è¡šãtypedef
ã 䜿çšæ¹æ³ã¯æ¬¡ã®ãšããã§ãã
ip::tcp::endpoint ep( ip::address::from_string("127.0.0.1"), 80); ip::tcp::socket sock(service); sock.connect(ep);
åã®é¢æ°ãæ©èœããã«ã¯ããœã±ãããéããŠããå¿
èŠããããŸããéããŠããªãå ŽåãäŸå€ãã¹ããŒãããŸãã
TCP vs UDPããã³ICMP
å
ã»ã©èšã£ãããã«ããã¹ãŠã®ãœã±ããã¯ã©ã¹ã§ãã¹ãŠã®ã¡ã³ããŒé¢æ°ã䜿çšã§ããããã§ã¯ãããŸããã ã¡ã³ããŒé¢æ°ãç°ãªããªã¹ããäœæããŸããã ããã«ã¡ã³ããŒé¢æ°ããªãå Žåãããã¯ãã¹ãŠã®ãœã±ããã¯ã©ã¹ã«ååšããããšãæå³ããŸãã
ãåå | TCP | UDP | ICMP |
---|
async_read_some | ã¯ã | - | - |
async_write_some | ã¯ã | - | - |
async_send_to | - | ã¯ã | ã¯ã |
read_some | ã¯ã | - | - |
receive_from | - | ã¯ã | ã¯ã |
write_some | ã¯ã | - | - |
send_to | - | ã¯ã | ã¯ã |
ãã®ä»ã®æ©èœ
æ¥ç¶ãŸãã¯å
¥å/åºåã«é¢é£ããä»ã®æ©èœïŒ
local_endpoint()
ïŒãã®é¢æ°ã¯ããœã±ãããããŒã«ã«ã«æ¥ç¶ãããŠããå Žåã«ã¢ãã¬ã¹ãè¿ããŸããremote_endpoint()
ïŒãã®é¢æ°ã¯ããœã±ãããæ¥ç¶ããããªã¢ãŒãã¢ãã¬ã¹ãè¿ããŸããnative_handle()
ïŒãã®é¢æ°ã¯ã¯ãªãŒã³ãªãœã±ãããè¿ããŸãã Boost.Asioã§ãµããŒããããŠããªãã¯ãªãŒã³ãœã±ãããæäœããããã®é¢æ°ã䜿çšããå Žåã«ã®ã¿äœ¿çšããŠãã ãããnon_blocking()
ïŒãã®é¢æ°ã¯ããœã±ãããéããããã³ã°ã®å Žåã¯true
è¿ããããã§ãªãå Žåã¯false
è¿ãtrue
ãnative_non_blocking()
ïŒãã®é¢æ°ã¯ããœã±ãããéããããã³ã°ã®å Žåã¯true
è¿ããããã§ãªãå Žåã¯false
è¿ãtrue
ã ãã ããèªç¶ãªãœã±ããã®çŽç²ãªAPIãåŒã³åºããŸãã ååãšããŠãããã¯å¿
èŠãããŸããïŒ non_blocking()
åžžã«ãã®çµæããã£ãã·ã¥ããŸãïŒ; native_handle()
ãçŽæ¥æ±ãå Žåã«ã®ã¿äœ¿çšããŠãã ãããat_mark()
ïŒOOBãœã±ããã®ããŒã¿ãèªã¿åãå Žåããã®é¢æ°ã¯true
è¿ããŸãã 圌女ãå¿
èŠã«ãªãããšã¯ãã£ãã«ãããŸããã
ãã®ä»ã®èæ
®äºé
ãããŠæåŸã«ãã³ããŒã³ã³ã¹ãã©ã¯ã¿ãšoperator=
å©çšã§ããªãããããœã±ããã€ã³ã¹ã¿ã³ã¹ãã³ããŒã§ããŸããã
ip::tcp::socket s1(service), s2(service); s1 = s2;
åã€ã³ã¹ã¿ã³ã¹ã¯ãªãœãŒã¹ïŒèªç¶ãœã±ããèªäœïŒãä¿åããã³ç®¡çãããããããã¯éåžžã«çã«ããªã£ãŠããŸãã ã³ããŒã³ã³ã¹ãã©ã¯ã¿ã䜿çšããå Žåãæçµçã«ã¯åããœã±ããã®2ã€ã®ã€ã³ã¹ã¿ã³ã¹ããããŸããã äœããã®æ¹æ³ã§æææš©ã管çããå¿
èŠããããŸãïŒ1ã€ã®ã³ããŒã«æææš©ãããããåç
§ã«ãŠã³ãã䜿çšãããŠãããããŸãã¯ä»ã®æ¹æ³ïŒã Boost.Asioã§ã¯ãã³ããŒãçŠæ¢ããã®ãæ
£ç¿ã§ããïŒã³ããŒãäœæããå Žåã¯ãå
±æïŒ shared
ïŒãã€ã³ã¿ãŒã䜿çšããã ãã§ãïŒã
typedef boost::shared_ptr<ip::tcp::socket> socket_ptr; socket_ptr sock1(new ip::tcp::socket(service)); socket_ptr sock2(sock1);
ãœã±ãããããã¡
ãœã±ããã®èªã¿åããŸãã¯æžã蟌ã¿ãè¡ãå Žåãçä¿¡ããŒã¿ãŸãã¯çºä¿¡ããŒã¿ãå«ããããã¡ãŒãå¿
èŠã§ãã ãããã¡ã¡ã¢ãªã¯I / Oæäœã«èããå¿
èŠããããŸãã I / Oæäœãç¶ç¶ããŠããéããªãªãŒã¹ããããŸã§ã¹ã³ãŒãå€ã«ãªããªãããã«ããå¿
èŠããããŸãã
åææäœã®å Žåã¯éåžžã«ç°¡åã§ãã ãã¡ããã buff
ã¯receive
æäœãšsend
æäœã®äž¡æ¹ã«èããªããã°ãªããŸããã
char buff[512]; ... sock.receive(buffer(buff)); strcpy(buff, "ok\n"); sock.send(buffer(buff));
ãŸãã次ã®ã¹ããããã«ç€ºãããã«ãéåææäœã§ã¯ããã»ã©åçŽã§ã¯ãããŸããã
async_receive()
åŒã³åºããåŸã buff
ã¯ã¹ã³ãŒãããå€ããããããã®ã¡ã¢ãªã¯è§£æŸãããŸãã ãœã±ããã§å®éã«ããŒã¿ãååŸããå Žåã¯ããã®ããŒã¿ãèªåã®ãã®ã§ã¯ãªãã¡ã¢ãªã«ã³ããŒããå¿
èŠããããŸãã ä»ã®ããŒã¿ã®ã³ãŒããä»ããŠè§£æŸãŸãã¯åé
åžã§ããŸããããã¹ãŠã¡ã¢ãªç ŽæãçºçããŸãã
ãã®åé¡ã«ã¯ããã€ãã®è§£æ±ºçããããŸãã
- ã°ããŒãã«ãããã¡ã䜿çš
- ãããã¡ãäœæããæäœãå®äºãããç Žæ£ããŸã
- ãœã±ããããã³ãããã¡ãªã©ã®è¿œå ããŒã¿ããµããŒãããéä¿¡ãªããžã§ã¯ããçšæããŸãã
ã°ããŒãã«å€æ°ãæªãããšã¯èª°ããç¥ã£ãŠãããããæåã®è§£æ±ºçã¯ããŸã䟿å©ã§ã¯ãããŸããã ãŸãã2ã€ã®ãã³ãã©ãŒãåããããã¡ãŒã䜿çšãããšã©ããªããŸããïŒ
2çªç®ã®ãœãªã¥ãŒã·ã§ã³ãå®è£
ããæ¹æ³ã¯æ¬¡ã®ãšããã§ãã
void on_read(char * ptr, const boost::system::error_code & err, std::size_t read_bytes) { delete[] ptr; } .... char * buff = new char[512]; sock.async_receive(buffer(buff, 512), boost::bind(on_ read,buff,_1,_2));
æäœã®å®äºæã«ãããã¡ãèªåçã«ã¹ã³ãŒãå€ã«ãããå Žåã¯ã shared pointer
䜿çšshared pointer
ïŒ
struct shared_buffer { boost::shared_array<char> buff; int size; shared_buffer(size_t size) : buff(new char[size]), size(size) {} mutable_buffers_1 asio_buff() const { return buffer(buff.get(), size); } };
shared_buffer
ã¯ã©ã¹ã«ã¯ã shared_array <>
ã€ã³ã¹ã¿ã³ã¹ã®ã³ããŒã§ããshared_array <>
ãå«ãŸããŠããããã shared_array <>
ã¯åç¶ããŸãã åŸè
ãç¯å²å€ã«ãªããšã shared_array <>
ã¯èªåçã«æããããŸããŸãã
Boost.Asioã¯ãæäœã®å®äºæã«åŒã³åºãããçµäºãã³ãã©ãŒã®ã³ããŒãä¿æãããããããã¯æåŸ
ã©ããã«æ©èœããŸãã ãã®ã³ããŒã¯ã boost::bind
ãã¡ã³ã¯ã¿ã§ããã shared_buffer
ã€ã³ã¹ã¿ã³ã¹ã®ã³ããŒãå
éšçã«ä¿åããŸãã ããã¯éåžžã«ãããã§ãïŒ
3çªç®ã®ãªãã·ã§ã³ã¯ããœã±ããããµããŒããããããã¡ãŒãªã©ã®è¿œå ããŒã¿ãå«ãéä¿¡ãªããžã§ã¯ãã䜿çšããããšã§ããããã¯éåžžæ£ãããœãªã¥ãŒã·ã§ã³ã§ãããããªãè€éã§ãã ããã«ã€ããŠã¯ããã®ç« ã®æåŸã§èª¬æããŸãã
ãããã¡ãŒé¢æ°ã©ãããŒ
åã«èŠãã³ãŒãã§ã¯ãèªã¿åã/æžã蟌ã¿æäœçšã®ãããã¡ãŒãåžžã«å¿
èŠã§ãããã³ãŒãã¯å®éã®ãããã¡ãŒã®ãªããžã§ã¯ãã«ãªãã buffer()
ãåŒã³åºããŠé¢æ°ã«æž¡ããŸãã
char buff[512]; sock.async_receive(buffer(buff), on_read
åºæ¬çã«ãã¯ã©ã¹ã«ãããããã¡ã¯ãã¹ãŠã©ãããããBoost.Asioã®é¢æ°ããããã¡ãå埩åŠçã§ããããã«ãªããŸãã 次ã®ã³ãŒãã䜿çšããŠãããšããŸãïŒ
sock.async_receive(some_buffer, on_read);
some_buffer
ã®ã€ã³ã¹ã¿ã³ã¹ã¯ã ConstBufferSequence
ãŸãã¯MutableBufferSequence
ãšããããã€ãã®èŠä»¶ãæºãããŠããå¿
èŠããããŸãïŒãããã«ã€ããŠã¯ãBoost.Asioã®ããã¥ã¡ã³ãã§ç¢ºèªã§ããŸãïŒã ãããã®èŠä»¶ãæºããããã«ç¬èªã®ã¯ã©ã¹ãäœæãã詳现ã¯éåžžã«è€éã§ãããBoost.Asioã«ã¯ãããã®èŠä»¶ãã¢ãã«åããã¯ã©ã¹ãæ¢ã«å«ãŸããŠããŸãã çŽæ¥ã¢ã¯ã»ã¹ããã®ã§ã¯ãªãã buffer()
é¢æ°ã䜿çšããŸãã
buffer()
é¢æ°ã§æ¬¡ãã©ããã§ãããšèšãã°ååã§ãã
- æåã®å®æ°é
å
void*
ããã³æåãµã€ãº- æåå
std::string
- å®æ°é
åPOD []ïŒPODã¯å€ãããŒã¿ã«é©ããŠããŸããã€ãŸããã³ã³ã¹ãã©ã¯ã¿ãŒãšãã¹ãã©ã¯ã¿ãŒã¯äœãããŸããïŒ
- é
å
std::vector
ä»»æã®PODããã®std::vector
boost::array
PODããã®boost::array
- é
å
std::array
ä»»æã®PODããã®std::array
次ã®ã³ãŒããæ©èœããŠããŸãïŒ
struct pod_sample { int i; long l; char c; }; ... char b1[512]; void * b2 = new char[512]; std::string b3; b3.resize(128); pod_sample b4[16]; std::vector<pod_sample> b5; b5.resize(16); boost::array<pod_sample,16> b6; std::array<pod_sample,16> b7; sock.async_send(buffer(b1), on_read); sock.async_send(buffer(b2,512), on_read); sock.async_send(buffer(b3), on_read); sock.async_send(buffer(b4), on_read); sock.async_send(buffer(b5), on_read); sock.async_send(buffer(b6), on_read); sock.async_send(buffer(b7), on_read);
äžè¬ã«ã ConstBufferSequence
ãŸãã¯MutableBufferSequence
èŠä»¶ãæºããããã«ç¬èªã®ã¯ã©ã¹ãäœæãã代ããã«ãå¿
èŠã«ConstBufferSequence
ãŠãããã¡ãŒãå«ãã¯ã©ã¹ãäœæãã mutable_ buffers_1
ã€ã³ã¹ã¿ã³ã¹ãè¿ãããšãã§ããŸããããã¯ãã¯ã©ã¹ã§è¡ã£ãããšãšåãã§ã以åã¯shared_buffer
ã
ç¬ç«ããèªã¿åã/æžã蟌ã¿/æ¥ç¶æ©èœ
Boost.Asioã¯ç¬ç«ããI / Oæ©èœãæäŸããŸãã ç§ã¯ãããã4ã€ã®ã°ã«ãŒãã«åããŸããã
æ¥ç¶æ©èœ
ãããã®é¢æ°ã¯ããœã±ãããŸãã¯çµäºã¢ãã¬ã¹ãæ¥ç¶ããŸãã
connect(socket, begin [, end] [, condition])
: , begin
end
. begin
socket_type::resolver::query
( , « » ). , . condition
, . Iterator connect_condition(const boost::system::error_code & err, Iterator next);
ã , , .async_connect(socket, begin [, end] [, condition], handler):
. void handler(const boost::system::error_code & err, Iterator iterator);
ã , ( end ).
:
using namespace boost::asio::ip; tcp::resolver resolver(service); tcp::resolver::iterator iter = resolver.resolve(tcp::resolver::query("www.yahoo.com","80")); tcp::socket sock(service); connect(sock, iter);
, connect
async_connect
, ; .
/
( , ):
async_read(stream, buffer [, completion] ,handler)
: . . void handler(const boost::system::error_code & err, size_t bytes);
ã completion . Completion
read
, Boost.Asio async_read
( , ). size_t completion (const boost::system::error_code& err, size_t bytes_transfered)
. 0, , ; , , async_read_some
. .async_write(stream, buffer [, completion], handler)
: . async_read
.read(stream, buffer [, completion])
: . async_read
write(stream, buffer [, completion])
: . async_read
.async_read(stream, stream_buffer [, completion], handler)
async_write(strean, stream_buffer [, completion], handler)
write(stream, stream_buffer [, completion])
read(stream, stream_buffer [, completion])
- , . , . , Windows.
:
- ( ) ( ).
Completion
0 ( ).- .
, '\n':
io_service service; ip::tcp::socket sock(service); char buff[512]; int offset = 0; size_t up_to_enter(const boost::system::error_code &, size_t bytes) { for ( size_t i = 0; i < bytes; ++i) if ( buff[i + offset] == '\n') return 0; return 1; } void on_read(const boost::system::error_code &, size_t) {} ... async_read(sock, buffer(buff), up_to_enter, on_read);
, Boost.Asio completion
:
- transfer_at_least(n)
- transfer_exactly(n)
- transfer_all()
:
char buff[512]; void on_read(const boost::system::error_code &, size_t) {}
stream_buffer
Boost.Asio, std::streambuf
. STL , :
io_service service; void on_read(streambuf& buf, const boost::system::error_code &, size_t) { std::istream in(&buf); std::string line; std::getline(in, line); std::cout << "first line: " << line << std::endl; } int main(int argc, char* argv[]) { HANDLE file = ::CreateFile("readme.txt", GENERIC_READ, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,0); windows::stream_handle h(service, file); streambuf buf; async_read(h, buf, transfer_exactly(256), boost::bind(on_read,boost::ref(buf),_1,_2)); service.run(); }
, async_read
( - ) Windows. 256 . , on_read
, std::istream
, ( std::getline
) .
read_until/async_read_until
:
async_read_until(stream, stream_buffer, delim, handler)
: . ( delim
). , std::string
boost::regex
. void handler(const boost::system::error_code & err, size_t bytes);
ãasync_read_until(stream, stream_buffer, completion, handler)
: , . pair<iterator,bool> completion(iterator begin, iterator end);
, buffers_iterator<streambuf::const_buffers_type>
. , . ( begin, end
) . ; ; true
, , , false
.read_until(stream, stream_buffer, delim)
: . async_read_until
.
:
typedef buffers_iterator<streambuf::const_buffers_type> iterator; std::pair<iterator, bool> match_punct(iterator begin, iterator end) { while ( begin != end) if ( std::ispunct(*begin)) return std::make_pair(begin,true); return std::make_pair(end,false); } void on_read(const boost::system::error_code &, size_t) {} ... streambuf buf; async_read_until(sock, buf, match_punct, on_read);
, :
async_read_until(sock, buff, ' ', on_read);
*_at
/ . , / ( ):
async_read_at(stream, offset, buffer [, completion], handler)
: , offset
. handler (const boost::system::error_code& err, size_t bytes);
ã buffer()
streambuf
. , Boost.Asio async_read_at operation
( , ). size_t completion(const boost::system::error_code& err, size_t bytes);
ã 0, , , , , async_read_some_at
.async_write_at(stream, offset, buffer [, completion], handler)
: . async_read_at
.read_at(stream, offset, buffer [, completion])
: . async_read_at
.read_at(stream, offset, buffer [, completion])
: . async_read_at
.
. ; , , . ( forward-only
).
128 , 256:
io_service service; int main(int argc, char* argv[]) { HANDLE file = ::CreateFile("readme.txt", GENERIC_READ, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,0); windows::random_access_handle h(service, file); streambuf buf; read_at(h, 256, buf, transfer_exactly(128)); std::istream in(&buf); std::string line; std::getline(in, line); std::cout << "first line: " << line << std::endl; }
, . . .
çããã«å¹žéãïŒ