basic_seq_packet_socket.hpp 31 KB

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