basic_seq_packet_socket.hpp 29 KB

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