basic_seq_packet_socket.hpp 30 KB

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