basic_seq_packet_socket.hpp 30 KB

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