basic_seq_packet_socket.hpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  1. //
  2. // basic_seq_packet_socket.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef ASIO_BASIC_SEQ_PACKET_SOCKET_HPP
  11. #define ASIO_BASIC_SEQ_PACKET_SOCKET_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include "asio/detail/config.hpp"
  16. #include <cstddef>
  17. #include "asio/basic_socket.hpp"
  18. #include "asio/detail/handler_type_requirements.hpp"
  19. #include "asio/detail/throw_error.hpp"
  20. #include "asio/error.hpp"
  21. #if defined(ASIO_ENABLE_OLD_SERVICES)
  22. # include "asio/seq_packet_socket_service.hpp"
  23. #endif // defined(ASIO_ENABLE_OLD_SERVICES)
  24. #include "asio/detail/push_options.hpp"
  25. namespace asio {
  26. /// Provides sequenced packet socket functionality.
  27. /**
  28. * The basic_seq_packet_socket class template provides asynchronous and blocking
  29. * sequenced packet socket functionality.
  30. *
  31. * @par Thread Safety
  32. * @e Distinct @e objects: Safe.@n
  33. * @e Shared @e objects: Unsafe.
  34. */
  35. template <typename Protocol
  36. ASIO_SVC_TPARAM_DEF1(= seq_packet_socket_service<Protocol>)>
  37. class basic_seq_packet_socket
  38. : public basic_socket<Protocol ASIO_SVC_TARG>
  39. {
  40. public:
  41. /// The native representation of a socket.
  42. #if defined(GENERATING_DOCUMENTATION)
  43. typedef implementation_defined native_handle_type;
  44. #else
  45. typedef typename basic_socket<
  46. Protocol ASIO_SVC_TARG>::native_handle_type native_handle_type;
  47. #endif
  48. /// The protocol type.
  49. typedef Protocol protocol_type;
  50. /// The endpoint type.
  51. typedef typename Protocol::endpoint endpoint_type;
  52. /// Construct a basic_seq_packet_socket without opening it.
  53. /**
  54. * This constructor creates a sequenced packet socket without opening it. The
  55. * socket needs to be opened and then connected or accepted before data can
  56. * be sent or received on it.
  57. *
  58. * @param io_context The io_context object that the sequenced packet socket
  59. * will use to dispatch handlers for any asynchronous operations performed on
  60. * the socket.
  61. */
  62. explicit basic_seq_packet_socket(asio::io_context& io_context)
  63. : basic_socket<Protocol ASIO_SVC_TARG>(io_context)
  64. {
  65. }
  66. /// Construct and open a basic_seq_packet_socket.
  67. /**
  68. * This constructor creates and opens a sequenced_packet socket. The socket
  69. * needs to be connected or accepted before data can be sent or received on
  70. * it.
  71. *
  72. * @param io_context The io_context object that the sequenced packet socket
  73. * will use to dispatch handlers for any asynchronous operations performed on
  74. * the socket.
  75. *
  76. * @param protocol An object specifying protocol parameters to be used.
  77. *
  78. * @throws asio::system_error Thrown on failure.
  79. */
  80. basic_seq_packet_socket(asio::io_context& io_context,
  81. const protocol_type& protocol)
  82. : basic_socket<Protocol ASIO_SVC_TARG>(io_context, protocol)
  83. {
  84. }
  85. /// Construct a basic_seq_packet_socket, opening it and binding it to the
  86. /// given local endpoint.
  87. /**
  88. * This constructor creates a sequenced packet socket and automatically opens
  89. * it bound to the specified endpoint on the local machine. The protocol used
  90. * is the protocol associated with the given endpoint.
  91. *
  92. * @param io_context The io_context object that the sequenced packet socket
  93. * will use to dispatch handlers for any asynchronous operations performed on
  94. * the socket.
  95. *
  96. * @param endpoint An endpoint on the local machine to which the sequenced
  97. * packet socket will be bound.
  98. *
  99. * @throws asio::system_error Thrown on failure.
  100. */
  101. basic_seq_packet_socket(asio::io_context& io_context,
  102. const endpoint_type& endpoint)
  103. : basic_socket<Protocol ASIO_SVC_TARG>(io_context, endpoint)
  104. {
  105. }
  106. /// Construct a basic_seq_packet_socket on an existing native socket.
  107. /**
  108. * This constructor creates a sequenced packet socket object to hold an
  109. * existing native socket.
  110. *
  111. * @param io_context The io_context object that the sequenced packet socket
  112. * will use to dispatch handlers for any asynchronous operations performed on
  113. * the socket.
  114. *
  115. * @param protocol An object specifying protocol parameters to be used.
  116. *
  117. * @param native_socket The new underlying socket implementation.
  118. *
  119. * @throws asio::system_error Thrown on failure.
  120. */
  121. basic_seq_packet_socket(asio::io_context& io_context,
  122. const protocol_type& protocol, const native_handle_type& native_socket)
  123. : basic_socket<Protocol ASIO_SVC_TARG>(
  124. io_context, protocol, native_socket)
  125. {
  126. }
  127. #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  128. /// Move-construct a basic_seq_packet_socket from another.
  129. /**
  130. * This constructor moves a sequenced packet socket from one object to
  131. * another.
  132. *
  133. * @param other The other basic_seq_packet_socket object from which the move
  134. * will occur.
  135. *
  136. * @note Following the move, the moved-from object is in the same state as if
  137. * constructed using the @c basic_seq_packet_socket(io_context&) constructor.
  138. */
  139. basic_seq_packet_socket(basic_seq_packet_socket&& other)
  140. : basic_socket<Protocol ASIO_SVC_TARG>(std::move(other))
  141. {
  142. }
  143. /// Move-assign a basic_seq_packet_socket from another.
  144. /**
  145. * This assignment operator moves a sequenced packet socket from one object to
  146. * another.
  147. *
  148. * @param other The other basic_seq_packet_socket object from which the move
  149. * will occur.
  150. *
  151. * @note Following the move, the moved-from object is in the same state as if
  152. * constructed using the @c basic_seq_packet_socket(io_context&) constructor.
  153. */
  154. basic_seq_packet_socket& operator=(basic_seq_packet_socket&& other)
  155. {
  156. basic_socket<Protocol ASIO_SVC_TARG>::operator=(std::move(other));
  157. return *this;
  158. }
  159. /// Move-construct a basic_seq_packet_socket from a socket of another protocol
  160. /// type.
  161. /**
  162. * This constructor moves a sequenced packet socket from one object to
  163. * another.
  164. *
  165. * @param other The other basic_seq_packet_socket object from which the move
  166. * will occur.
  167. *
  168. * @note Following the move, the moved-from object is in the same state as if
  169. * constructed using the @c basic_seq_packet_socket(io_context&) constructor.
  170. */
  171. template <typename Protocol1 ASIO_SVC_TPARAM1>
  172. basic_seq_packet_socket(
  173. basic_seq_packet_socket<Protocol1 ASIO_SVC_TARG1>&& other,
  174. typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
  175. : basic_socket<Protocol ASIO_SVC_TARG>(std::move(other))
  176. {
  177. }
  178. /// Move-assign a basic_seq_packet_socket from a socket of another protocol
  179. /// type.
  180. /**
  181. * This assignment operator moves a sequenced packet socket from one object to
  182. * another.
  183. *
  184. * @param other The other basic_seq_packet_socket object from which the move
  185. * will occur.
  186. *
  187. * @note Following the move, the moved-from object is in the same state as if
  188. * constructed using the @c basic_seq_packet_socket(io_context&) constructor.
  189. */
  190. template <typename Protocol1 ASIO_SVC_TPARAM1>
  191. typename enable_if<is_convertible<Protocol1, Protocol>::value,
  192. basic_seq_packet_socket>::type& operator=(
  193. basic_seq_packet_socket<Protocol1 ASIO_SVC_TARG1>&& other)
  194. {
  195. basic_socket<Protocol ASIO_SVC_TARG>::operator=(std::move(other));
  196. return *this;
  197. }
  198. #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  199. /// Destroys the socket.
  200. /**
  201. * This function destroys the socket, cancelling any outstanding asynchronous
  202. * operations associated with the socket as if by calling @c cancel.
  203. */
  204. ~basic_seq_packet_socket()
  205. {
  206. }
  207. /// Send some data on the socket.
  208. /**
  209. * This function is used to send data on the sequenced packet socket. The
  210. * function call will block until the data has been sent successfully, or an
  211. * until error occurs.
  212. *
  213. * @param buffers One or more data buffers to be sent on the socket.
  214. *
  215. * @param flags Flags specifying how the send call is to be made.
  216. *
  217. * @returns The number of bytes sent.
  218. *
  219. * @throws asio::system_error Thrown on failure.
  220. *
  221. * @par Example
  222. * To send a single data buffer use the @ref buffer function as follows:
  223. * @code
  224. * socket.send(asio::buffer(data, size), 0);
  225. * @endcode
  226. * See the @ref buffer documentation for information on sending multiple
  227. * buffers in one go, and how to use it with arrays, boost::array or
  228. * std::vector.
  229. */
  230. template <typename ConstBufferSequence>
  231. std::size_t send(const ConstBufferSequence& buffers,
  232. socket_base::message_flags flags)
  233. {
  234. asio::error_code ec;
  235. std::size_t s = this->get_service().send(
  236. this->get_implementation(), buffers, flags, ec);
  237. asio::detail::throw_error(ec, "send");
  238. return s;
  239. }
  240. /// Send some data on the socket.
  241. /**
  242. * This function is used to send data on the sequenced packet socket. The
  243. * function call will block the data has been sent successfully, or an until
  244. * error occurs.
  245. *
  246. * @param buffers One or more data buffers to be sent on the socket.
  247. *
  248. * @param flags Flags specifying how the send call is to be made.
  249. *
  250. * @param ec Set to indicate what error occurred, if any.
  251. *
  252. * @returns The number of bytes sent. Returns 0 if an error occurred.
  253. *
  254. * @note The send operation may not transmit all of the data to the peer.
  255. * Consider using the @ref write function if you need to ensure that all data
  256. * is written before the blocking operation completes.
  257. */
  258. template <typename ConstBufferSequence>
  259. std::size_t send(const ConstBufferSequence& buffers,
  260. socket_base::message_flags flags, asio::error_code& ec)
  261. {
  262. return this->get_service().send(
  263. this->get_implementation(), buffers, flags, ec);
  264. }
  265. /// Start an asynchronous send.
  266. /**
  267. * This function is used to asynchronously send data on the sequenced packet
  268. * socket. The function call always returns immediately.
  269. *
  270. * @param buffers One or more data buffers to be sent on the socket. Although
  271. * the buffers object may be copied as necessary, ownership of the underlying
  272. * memory blocks is retained by the caller, which must guarantee that they
  273. * remain valid until the handler is called.
  274. *
  275. * @param flags Flags specifying how the send call is to be made.
  276. *
  277. * @param handler The handler to be called when the send operation completes.
  278. * Copies will be made of the handler as required. The function signature of
  279. * the handler must be:
  280. * @code void handler(
  281. * const asio::error_code& error, // Result of operation.
  282. * std::size_t bytes_transferred // Number of bytes sent.
  283. * ); @endcode
  284. * Regardless of whether the asynchronous operation completes immediately or
  285. * not, the handler will not be invoked from within this function. Invocation
  286. * of the handler will be performed in a manner equivalent to using
  287. * asio::io_context::post().
  288. *
  289. * @par Example
  290. * To send a single data buffer use the @ref buffer function as follows:
  291. * @code
  292. * socket.async_send(asio::buffer(data, size), 0, handler);
  293. * @endcode
  294. * See the @ref buffer documentation for information on sending multiple
  295. * buffers in one go, and how to use it with arrays, boost::array or
  296. * std::vector.
  297. */
  298. template <typename ConstBufferSequence, typename WriteHandler>
  299. ASIO_INITFN_RESULT_TYPE(WriteHandler,
  300. void (asio::error_code, std::size_t))
  301. async_send(const ConstBufferSequence& buffers,
  302. socket_base::message_flags flags,
  303. ASIO_MOVE_ARG(WriteHandler) handler)
  304. {
  305. // If you get an error on the following line it means that your handler does
  306. // not meet the documented type requirements for a WriteHandler.
  307. ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
  308. #if defined(ASIO_ENABLE_OLD_SERVICES)
  309. return this->get_service().async_send(this->get_implementation(),
  310. buffers, flags, ASIO_MOVE_CAST(WriteHandler)(handler));
  311. #else // defined(ASIO_ENABLE_OLD_SERVICES)
  312. async_completion<WriteHandler,
  313. void (asio::error_code, std::size_t)> init(handler);
  314. this->get_service().async_send(this->get_implementation(),
  315. buffers, flags, init.completion_handler);
  316. return init.result.get();
  317. #endif // defined(ASIO_ENABLE_OLD_SERVICES)
  318. }
  319. /// Receive some data on the socket.
  320. /**
  321. * This function is used to receive data on the sequenced packet socket. The
  322. * function call will block until data has been received successfully, or
  323. * until an error occurs.
  324. *
  325. * @param buffers One or more buffers into which the data will be received.
  326. *
  327. * @param out_flags After the receive call completes, contains flags
  328. * associated with the received data. For example, if the
  329. * socket_base::message_end_of_record bit is set then the received data marks
  330. * the end of a record.
  331. *
  332. * @returns The number of bytes received.
  333. *
  334. * @throws asio::system_error Thrown on failure. An error code of
  335. * asio::error::eof indicates that the connection was closed by the
  336. * peer.
  337. *
  338. * @par Example
  339. * To receive into a single data buffer use the @ref buffer function as
  340. * follows:
  341. * @code
  342. * socket.receive(asio::buffer(data, size), out_flags);
  343. * @endcode
  344. * See the @ref buffer documentation for information on receiving into
  345. * multiple buffers in one go, and how to use it with arrays, boost::array or
  346. * std::vector.
  347. */
  348. template <typename MutableBufferSequence>
  349. std::size_t receive(const MutableBufferSequence& buffers,
  350. socket_base::message_flags& out_flags)
  351. {
  352. asio::error_code ec;
  353. #if defined(ASIO_ENABLE_OLD_SERVICES)
  354. std::size_t s = this->get_service().receive(
  355. this->get_implementation(), buffers, 0, out_flags, ec);
  356. #else // defined(ASIO_ENABLE_OLD_SERVICES)
  357. std::size_t s = this->get_service().receive_with_flags(
  358. this->get_implementation(), buffers, 0, out_flags, ec);
  359. #endif // defined(ASIO_ENABLE_OLD_SERVICES)
  360. asio::detail::throw_error(ec, "receive");
  361. return s;
  362. }
  363. /// Receive some data on the socket.
  364. /**
  365. * This function is used to receive data on the sequenced packet socket. The
  366. * function call will block until data has been received successfully, or
  367. * until an error occurs.
  368. *
  369. * @param buffers One or more buffers into which the data will be received.
  370. *
  371. * @param in_flags Flags specifying how the receive call is to be made.
  372. *
  373. * @param out_flags After the receive call completes, contains flags
  374. * associated with the received data. For example, if the
  375. * socket_base::message_end_of_record bit is set then the received data marks
  376. * the end of a record.
  377. *
  378. * @returns The number of bytes received.
  379. *
  380. * @throws asio::system_error Thrown on failure. An error code of
  381. * asio::error::eof indicates that the connection was closed by the
  382. * peer.
  383. *
  384. * @note The receive operation may not receive all of the requested number of
  385. * bytes. Consider using the @ref read function if you need to ensure that the
  386. * requested amount of data is read before the blocking operation completes.
  387. *
  388. * @par Example
  389. * To receive into a single data buffer use the @ref buffer function as
  390. * follows:
  391. * @code
  392. * socket.receive(asio::buffer(data, size), 0, out_flags);
  393. * @endcode
  394. * See the @ref buffer documentation for information on receiving into
  395. * multiple buffers in one go, and how to use it with arrays, boost::array or
  396. * std::vector.
  397. */
  398. template <typename MutableBufferSequence>
  399. std::size_t receive(const MutableBufferSequence& buffers,
  400. socket_base::message_flags in_flags,
  401. socket_base::message_flags& out_flags)
  402. {
  403. asio::error_code ec;
  404. #if defined(ASIO_ENABLE_OLD_SERVICES)
  405. std::size_t s = this->get_service().receive(
  406. this->get_implementation(), buffers, in_flags, out_flags, ec);
  407. #else // defined(ASIO_ENABLE_OLD_SERVICES)
  408. std::size_t s = this->get_service().receive_with_flags(
  409. this->get_implementation(), buffers, in_flags, out_flags, ec);
  410. #endif // defined(ASIO_ENABLE_OLD_SERVICES)
  411. asio::detail::throw_error(ec, "receive");
  412. return s;
  413. }
  414. /// Receive some data on a connected socket.
  415. /**
  416. * This function is used to receive data on the sequenced packet socket. The
  417. * function call will block until data has been received successfully, or
  418. * until an error occurs.
  419. *
  420. * @param buffers One or more buffers into which the data will be received.
  421. *
  422. * @param in_flags Flags specifying how the receive call is to be made.
  423. *
  424. * @param out_flags After the receive call completes, contains flags
  425. * associated with the received data. For example, if the
  426. * socket_base::message_end_of_record bit is set then the received data marks
  427. * the end of a record.
  428. *
  429. * @param ec Set to indicate what error occurred, if any.
  430. *
  431. * @returns The number of bytes received. Returns 0 if an error occurred.
  432. *
  433. * @note The receive operation may not receive all of the requested number of
  434. * bytes. Consider using the @ref read function if you need to ensure that the
  435. * requested amount of data is read before the blocking operation completes.
  436. */
  437. template <typename MutableBufferSequence>
  438. std::size_t receive(const MutableBufferSequence& buffers,
  439. socket_base::message_flags in_flags,
  440. socket_base::message_flags& out_flags, asio::error_code& ec)
  441. {
  442. #if defined(ASIO_ENABLE_OLD_SERVICES)
  443. return this->get_service().receive(this->get_implementation(),
  444. buffers, in_flags, out_flags, ec);
  445. #else // defined(ASIO_ENABLE_OLD_SERVICES)
  446. return this->get_service().receive_with_flags(this->get_implementation(),
  447. buffers, in_flags, out_flags, ec);
  448. #endif // defined(ASIO_ENABLE_OLD_SERVICES)
  449. }
  450. /// Start an asynchronous receive.
  451. /**
  452. * This function is used to asynchronously receive data from the sequenced
  453. * packet socket. The function call always returns immediately.
  454. *
  455. * @param buffers One or more buffers into which the data will be received.
  456. * Although the buffers object may be copied as necessary, ownership of the
  457. * underlying memory blocks is retained by the caller, which must guarantee
  458. * that they remain valid until the handler is called.
  459. *
  460. * @param out_flags Once the asynchronous operation completes, contains flags
  461. * associated with the received data. For example, if the
  462. * socket_base::message_end_of_record bit is set then the received data marks
  463. * the end of a record. The caller must guarantee that the referenced
  464. * variable remains valid until the handler is called.
  465. *
  466. * @param handler The handler to be called when the receive operation
  467. * completes. Copies will be made of the handler as required. The function
  468. * signature of the handler must be:
  469. * @code void handler(
  470. * const asio::error_code& error, // Result of operation.
  471. * std::size_t bytes_transferred // Number of bytes received.
  472. * ); @endcode
  473. * Regardless of whether the asynchronous operation completes immediately or
  474. * not, the handler will not be invoked from within this function. Invocation
  475. * of the handler will be performed in a manner equivalent to using
  476. * asio::io_context::post().
  477. *
  478. * @par Example
  479. * To receive into a single data buffer use the @ref buffer function as
  480. * follows:
  481. * @code
  482. * socket.async_receive(asio::buffer(data, size), out_flags, handler);
  483. * @endcode
  484. * See the @ref buffer documentation for information on receiving into
  485. * multiple buffers in one go, and how to use it with arrays, boost::array or
  486. * std::vector.
  487. */
  488. template <typename MutableBufferSequence, typename ReadHandler>
  489. ASIO_INITFN_RESULT_TYPE(ReadHandler,
  490. void (asio::error_code, std::size_t))
  491. async_receive(const MutableBufferSequence& buffers,
  492. socket_base::message_flags& out_flags,
  493. ASIO_MOVE_ARG(ReadHandler) handler)
  494. {
  495. // If you get an error on the following line it means that your handler does
  496. // not meet the documented type requirements for a ReadHandler.
  497. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
  498. #if defined(ASIO_ENABLE_OLD_SERVICES)
  499. return this->get_service().async_receive(
  500. this->get_implementation(), buffers, 0, out_flags,
  501. ASIO_MOVE_CAST(ReadHandler)(handler));
  502. #else // defined(ASIO_ENABLE_OLD_SERVICES)
  503. async_completion<ReadHandler,
  504. void (asio::error_code, std::size_t)> init(handler);
  505. this->get_service().async_receive_with_flags(
  506. this->get_implementation(), buffers, 0, out_flags,
  507. init.completion_handler);
  508. return init.result.get();
  509. #endif // defined(ASIO_ENABLE_OLD_SERVICES)
  510. }
  511. /// Start an asynchronous receive.
  512. /**
  513. * This function is used to asynchronously receive data from the sequenced
  514. * data socket. The function call always returns immediately.
  515. *
  516. * @param buffers One or more buffers into which the data will be received.
  517. * Although the buffers object may be copied as necessary, ownership of the
  518. * underlying memory blocks is retained by the caller, which must guarantee
  519. * that they remain valid until the handler is called.
  520. *
  521. * @param in_flags Flags specifying how the receive call is to be made.
  522. *
  523. * @param out_flags Once the asynchronous operation completes, contains flags
  524. * associated with the received data. For example, if the
  525. * socket_base::message_end_of_record bit is set then the received data marks
  526. * the end of a record. The caller must guarantee that the referenced
  527. * variable remains valid until the handler is called.
  528. *
  529. * @param handler The handler to be called when the receive operation
  530. * completes. Copies will be made of the handler as required. The function
  531. * signature of the handler must be:
  532. * @code void handler(
  533. * const asio::error_code& error, // Result of operation.
  534. * std::size_t bytes_transferred // Number of bytes received.
  535. * ); @endcode
  536. * Regardless of whether the asynchronous operation completes immediately or
  537. * not, the handler will not be invoked from within this function. Invocation
  538. * of the handler will be performed in a manner equivalent to using
  539. * asio::io_context::post().
  540. *
  541. * @par Example
  542. * To receive into a single data buffer use the @ref buffer function as
  543. * follows:
  544. * @code
  545. * socket.async_receive(
  546. * asio::buffer(data, size),
  547. * 0, out_flags, handler);
  548. * @endcode
  549. * See the @ref buffer documentation for information on receiving into
  550. * multiple buffers in one go, and how to use it with arrays, boost::array or
  551. * std::vector.
  552. */
  553. template <typename MutableBufferSequence, typename ReadHandler>
  554. ASIO_INITFN_RESULT_TYPE(ReadHandler,
  555. void (asio::error_code, std::size_t))
  556. async_receive(const MutableBufferSequence& buffers,
  557. socket_base::message_flags in_flags,
  558. socket_base::message_flags& out_flags,
  559. ASIO_MOVE_ARG(ReadHandler) handler)
  560. {
  561. // If you get an error on the following line it means that your handler does
  562. // not meet the documented type requirements for a ReadHandler.
  563. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
  564. #if defined(ASIO_ENABLE_OLD_SERVICES)
  565. return this->get_service().async_receive(
  566. this->get_implementation(), buffers, in_flags, out_flags,
  567. ASIO_MOVE_CAST(ReadHandler)(handler));
  568. #else // defined(ASIO_ENABLE_OLD_SERVICES)
  569. async_completion<ReadHandler,
  570. void (asio::error_code, std::size_t)> init(handler);
  571. this->get_service().async_receive_with_flags(
  572. this->get_implementation(), buffers, in_flags, out_flags,
  573. init.completion_handler);
  574. return init.result.get();
  575. #endif // defined(ASIO_ENABLE_OLD_SERVICES)
  576. }
  577. };
  578. } // namespace asio
  579. #include "asio/detail/pop_options.hpp"
  580. #endif // ASIO_BASIC_SEQ_PACKET_SOCKET_HPP