Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

713 lines
27KB

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