basic_seq_packet_socket.hpp 24 KB

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