basic_stream_socket.hpp 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191
  1. //
  2. // basic_stream_socket.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef BOOST_ASIO_BASIC_STREAM_SOCKET_HPP
  11. #define BOOST_ASIO_BASIC_STREAM_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/async_result.hpp>
  18. #include <boost/asio/basic_socket.hpp>
  19. #include <boost/asio/detail/handler_type_requirements.hpp>
  20. #include <boost/asio/detail/non_const_lvalue.hpp>
  21. #include <boost/asio/detail/throw_error.hpp>
  22. #include <boost/asio/error.hpp>
  23. #include <boost/asio/detail/push_options.hpp>
  24. namespace boost {
  25. namespace asio {
  26. #if !defined(BOOST_ASIO_BASIC_STREAM_SOCKET_FWD_DECL)
  27. #define BOOST_ASIO_BASIC_STREAM_SOCKET_FWD_DECL
  28. // Forward declaration with defaulted arguments.
  29. template <typename Protocol, typename Executor = any_io_executor>
  30. class basic_stream_socket;
  31. #endif // !defined(BOOST_ASIO_BASIC_STREAM_SOCKET_FWD_DECL)
  32. /// Provides stream-oriented socket functionality.
  33. /**
  34. * The basic_stream_socket class template provides asynchronous and blocking
  35. * stream-oriented socket functionality.
  36. *
  37. * @par Thread Safety
  38. * @e Distinct @e objects: Safe.@n
  39. * @e Shared @e objects: Unsafe.
  40. *
  41. * Synchronous @c send, @c receive, @c connect, and @c shutdown operations are
  42. * thread safe with respect to each other, if the underlying operating system
  43. * calls are also thread safe. This means that it is permitted to perform
  44. * concurrent calls to these synchronous operations on a single socket object.
  45. * Other synchronous operations, such as @c open or @c close, are not thread
  46. * safe.
  47. *
  48. * @par Concepts:
  49. * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
  50. */
  51. template <typename Protocol, typename Executor>
  52. class basic_stream_socket
  53. : public basic_socket<Protocol, Executor>
  54. {
  55. private:
  56. class initiate_async_send;
  57. class initiate_async_receive;
  58. public:
  59. /// The type of the executor associated with the object.
  60. typedef Executor executor_type;
  61. /// Rebinds the socket type to another executor.
  62. template <typename Executor1>
  63. struct rebind_executor
  64. {
  65. /// The socket type when rebound to the specified executor.
  66. typedef basic_stream_socket<Protocol, Executor1> other;
  67. };
  68. /// The native representation of a socket.
  69. #if defined(GENERATING_DOCUMENTATION)
  70. typedef implementation_defined native_handle_type;
  71. #else
  72. typedef typename basic_socket<Protocol,
  73. Executor>::native_handle_type native_handle_type;
  74. #endif
  75. /// The protocol type.
  76. typedef Protocol protocol_type;
  77. /// The endpoint type.
  78. typedef typename Protocol::endpoint endpoint_type;
  79. /// Construct a basic_stream_socket without opening it.
  80. /**
  81. * This constructor creates a stream socket without opening it. The socket
  82. * needs to be opened and then connected or accepted before data can be sent
  83. * or received on it.
  84. *
  85. * @param ex The I/O executor that the socket will use, by default, to
  86. * dispatch handlers for any asynchronous operations performed on the socket.
  87. */
  88. explicit basic_stream_socket(const executor_type& ex)
  89. : basic_socket<Protocol, Executor>(ex)
  90. {
  91. }
  92. /// Construct a basic_stream_socket without opening it.
  93. /**
  94. * This constructor creates a stream socket without opening it. The socket
  95. * needs to be opened and then connected or accepted before data can be sent
  96. * or received on it.
  97. *
  98. * @param context An execution context which provides the I/O executor that
  99. * the socket will use, by default, to dispatch handlers for any asynchronous
  100. * operations performed on the socket.
  101. */
  102. template <typename ExecutionContext>
  103. explicit basic_stream_socket(ExecutionContext& context,
  104. typename constraint<
  105. is_convertible<ExecutionContext&, execution_context&>::value
  106. >::type = 0)
  107. : basic_socket<Protocol, Executor>(context)
  108. {
  109. }
  110. /// Construct and open a basic_stream_socket.
  111. /**
  112. * This constructor creates and opens a stream socket. The socket needs to be
  113. * connected or accepted before data can be sent or received on it.
  114. *
  115. * @param ex The I/O executor that the socket will use, by default, to
  116. * dispatch handlers for any asynchronous operations performed on the socket.
  117. *
  118. * @param protocol An object specifying protocol parameters to be used.
  119. *
  120. * @throws boost::system::system_error Thrown on failure.
  121. */
  122. basic_stream_socket(const executor_type& ex, const protocol_type& protocol)
  123. : basic_socket<Protocol, Executor>(ex, protocol)
  124. {
  125. }
  126. /// Construct and open a basic_stream_socket.
  127. /**
  128. * This constructor creates and opens a stream socket. The socket needs to be
  129. * connected or accepted before data can be sent or received on it.
  130. *
  131. * @param context An execution context which provides the I/O executor that
  132. * the socket will use, by default, to dispatch handlers for any asynchronous
  133. * operations performed on the socket.
  134. *
  135. * @param protocol An object specifying protocol parameters to be used.
  136. *
  137. * @throws boost::system::system_error Thrown on failure.
  138. */
  139. template <typename ExecutionContext>
  140. basic_stream_socket(ExecutionContext& context, const protocol_type& protocol,
  141. typename constraint<
  142. is_convertible<ExecutionContext&, execution_context&>::value,
  143. defaulted_constraint
  144. >::type = defaulted_constraint())
  145. : basic_socket<Protocol, Executor>(context, protocol)
  146. {
  147. }
  148. /// Construct a basic_stream_socket, opening it and binding it to the given
  149. /// local endpoint.
  150. /**
  151. * This constructor creates a stream socket and automatically opens it bound
  152. * to the specified endpoint on the local machine. The protocol used is the
  153. * protocol associated with the given endpoint.
  154. *
  155. * @param ex The I/O executor that the socket will use, by default, to
  156. * dispatch handlers for any asynchronous operations performed on the socket.
  157. *
  158. * @param endpoint An endpoint on the local machine to which the stream
  159. * socket will be bound.
  160. *
  161. * @throws boost::system::system_error Thrown on failure.
  162. */
  163. basic_stream_socket(const executor_type& ex, const endpoint_type& endpoint)
  164. : basic_socket<Protocol, Executor>(ex, endpoint)
  165. {
  166. }
  167. /// Construct a basic_stream_socket, opening it and binding it to the given
  168. /// local endpoint.
  169. /**
  170. * This constructor creates a stream socket and automatically opens it bound
  171. * to the specified endpoint on the local machine. The protocol used is the
  172. * 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 stream
  179. * socket will be bound.
  180. *
  181. * @throws boost::system::system_error Thrown on failure.
  182. */
  183. template <typename ExecutionContext>
  184. basic_stream_socket(ExecutionContext& context, const endpoint_type& endpoint,
  185. typename constraint<
  186. is_convertible<ExecutionContext&, execution_context&>::value
  187. >::type = 0)
  188. : basic_socket<Protocol, Executor>(context, endpoint)
  189. {
  190. }
  191. /// Construct a basic_stream_socket on an existing native socket.
  192. /**
  193. * This constructor creates a stream socket object to hold an existing native
  194. * socket.
  195. *
  196. * @param ex The I/O executor that the socket will use, by default, to
  197. * dispatch handlers for any asynchronous operations performed on the socket.
  198. *
  199. * @param protocol An object specifying protocol parameters to be used.
  200. *
  201. * @param native_socket The new underlying socket implementation.
  202. *
  203. * @throws boost::system::system_error Thrown on failure.
  204. */
  205. basic_stream_socket(const executor_type& ex,
  206. const protocol_type& protocol, const native_handle_type& native_socket)
  207. : basic_socket<Protocol, Executor>(ex, protocol, native_socket)
  208. {
  209. }
  210. /// Construct a basic_stream_socket on an existing native socket.
  211. /**
  212. * This constructor creates a stream socket object to hold an existing native
  213. * socket.
  214. *
  215. * @param context An execution context which provides the I/O executor that
  216. * the socket will use, by default, to dispatch handlers for any asynchronous
  217. * operations performed on the socket.
  218. *
  219. * @param protocol An object specifying protocol parameters to be used.
  220. *
  221. * @param native_socket The new underlying socket implementation.
  222. *
  223. * @throws boost::system::system_error Thrown on failure.
  224. */
  225. template <typename ExecutionContext>
  226. basic_stream_socket(ExecutionContext& context,
  227. const protocol_type& protocol, const native_handle_type& native_socket,
  228. typename constraint<
  229. is_convertible<ExecutionContext&, execution_context&>::value
  230. >::type = 0)
  231. : basic_socket<Protocol, Executor>(context, protocol, native_socket)
  232. {
  233. }
  234. #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  235. /// Move-construct a basic_stream_socket from another.
  236. /**
  237. * This constructor moves a stream socket from one object to another.
  238. *
  239. * @param other The other basic_stream_socket object from which the move
  240. * will occur.
  241. *
  242. * @note Following the move, the moved-from object is in the same state as if
  243. * constructed using the @c basic_stream_socket(const executor_type&)
  244. * constructor.
  245. */
  246. basic_stream_socket(basic_stream_socket&& other) BOOST_ASIO_NOEXCEPT
  247. : basic_socket<Protocol, Executor>(std::move(other))
  248. {
  249. }
  250. /// Move-assign a basic_stream_socket from another.
  251. /**
  252. * This assignment operator moves a stream socket from one object to another.
  253. *
  254. * @param other The other basic_stream_socket object from which the move
  255. * will occur.
  256. *
  257. * @note Following the move, the moved-from object is in the same state as if
  258. * constructed using the @c basic_stream_socket(const executor_type&)
  259. * constructor.
  260. */
  261. basic_stream_socket& operator=(basic_stream_socket&& other)
  262. {
  263. basic_socket<Protocol, Executor>::operator=(std::move(other));
  264. return *this;
  265. }
  266. /// Move-construct a basic_stream_socket from a socket of another protocol
  267. /// type.
  268. /**
  269. * This constructor moves a stream socket from one object to another.
  270. *
  271. * @param other The other basic_stream_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_stream_socket(const executor_type&)
  276. * constructor.
  277. */
  278. template <typename Protocol1, typename Executor1>
  279. basic_stream_socket(basic_stream_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_stream_socket from a socket of another protocol type.
  288. /**
  289. * This assignment operator moves a stream socket from one object to another.
  290. *
  291. * @param other The other basic_stream_socket object from which the move
  292. * will occur.
  293. *
  294. * @note Following the move, the moved-from object is in the same state as if
  295. * constructed using the @c basic_stream_socket(const executor_type&)
  296. * constructor.
  297. */
  298. template <typename Protocol1, typename Executor1>
  299. typename constraint<
  300. is_convertible<Protocol1, Protocol>::value
  301. && is_convertible<Executor1, Executor>::value,
  302. basic_stream_socket&
  303. >::type operator=(basic_stream_socket<Protocol1, Executor1>&& other)
  304. {
  305. basic_socket<Protocol, Executor>::operator=(std::move(other));
  306. return *this;
  307. }
  308. #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  309. /// Destroys the socket.
  310. /**
  311. * This function destroys the socket, cancelling any outstanding asynchronous
  312. * operations associated with the socket as if by calling @c cancel.
  313. */
  314. ~basic_stream_socket()
  315. {
  316. }
  317. /// Send some data on the socket.
  318. /**
  319. * This function is used to send data on the stream socket. The function
  320. * call will block until one or more bytes of the data has been sent
  321. * successfully, or an until error occurs.
  322. *
  323. * @param buffers One or more data buffers to be sent on the socket.
  324. *
  325. * @returns The number of bytes sent.
  326. *
  327. * @throws boost::system::system_error Thrown on failure.
  328. *
  329. * @note The send operation may not transmit all of the data to the peer.
  330. * Consider using the @ref write function if you need to ensure that all data
  331. * is written before the blocking operation completes.
  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));
  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. {
  345. boost::system::error_code ec;
  346. std::size_t s = this->impl_.get_service().send(
  347. this->impl_.get_implementation(), buffers, 0, ec);
  348. boost::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 stream socket. The function
  354. * call will block until one or more bytes of the data has been sent
  355. * successfully, or an until 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. * @returns The number of bytes sent.
  362. *
  363. * @throws boost::system::system_error Thrown on failure.
  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. * @par Example
  370. * To send a single data buffer use the @ref buffer function as follows:
  371. * @code
  372. * socket.send(boost::asio::buffer(data, size), 0);
  373. * @endcode
  374. * See the @ref buffer documentation for information on sending multiple
  375. * buffers in one go, and how to use it with arrays, boost::array or
  376. * std::vector.
  377. */
  378. template <typename ConstBufferSequence>
  379. std::size_t send(const ConstBufferSequence& buffers,
  380. socket_base::message_flags flags)
  381. {
  382. boost::system::error_code ec;
  383. std::size_t s = this->impl_.get_service().send(
  384. this->impl_.get_implementation(), buffers, flags, ec);
  385. boost::asio::detail::throw_error(ec, "send");
  386. return s;
  387. }
  388. /// Send some data on the socket.
  389. /**
  390. * This function is used to send data on the stream socket. The function
  391. * call will block until one or more bytes of the data has been sent
  392. * successfully, or an until error occurs.
  393. *
  394. * @param buffers One or more data buffers to be sent on the socket.
  395. *
  396. * @param flags Flags specifying how the send call is to be made.
  397. *
  398. * @param ec Set to indicate what error occurred, if any.
  399. *
  400. * @returns The number of bytes sent. Returns 0 if an error occurred.
  401. *
  402. * @note The send operation may not transmit all of the data to the peer.
  403. * Consider using the @ref write function if you need to ensure that all data
  404. * is written before the blocking operation completes.
  405. */
  406. template <typename ConstBufferSequence>
  407. std::size_t send(const ConstBufferSequence& buffers,
  408. socket_base::message_flags flags, boost::system::error_code& ec)
  409. {
  410. return this->impl_.get_service().send(
  411. this->impl_.get_implementation(), buffers, flags, ec);
  412. }
  413. /// Start an asynchronous send.
  414. /**
  415. * This function is used to asynchronously send data on the stream socket.
  416. * It is an initiating function for an @ref asynchronous_operation, and always
  417. * returns immediately.
  418. *
  419. * @param buffers One or more data buffers to be sent on the socket. Although
  420. * the buffers object may be copied as necessary, ownership of the underlying
  421. * memory blocks is retained by the caller, which must guarantee that they
  422. * remain valid until the completion handler is called.
  423. *
  424. * @param token The @ref completion_token that will be used to produce a
  425. * completion handler, which will be called when the send completes.
  426. * Potential completion tokens include @ref use_future, @ref use_awaitable,
  427. * @ref yield_context, or a function object with the correct completion
  428. * signature. The function signature of the completion handler must be:
  429. * @code void handler(
  430. * const boost::system::error_code& error, // Result of operation.
  431. * std::size_t bytes_transferred // Number of bytes sent.
  432. * ); @endcode
  433. * Regardless of whether the asynchronous operation completes immediately or
  434. * not, the completion handler will not be invoked from within this function.
  435. * On immediate completion, invocation of the handler will be performed in a
  436. * manner equivalent to using boost::asio::post().
  437. *
  438. * @par Completion Signature
  439. * @code void(boost::system::error_code, std::size_t) @endcode
  440. *
  441. * @note The send operation may not transmit all of the data to the peer.
  442. * Consider using the @ref async_write function if you need to ensure that all
  443. * data is written before the asynchronous operation completes.
  444. *
  445. * @par Example
  446. * To send a single data buffer use the @ref buffer function as follows:
  447. * @code
  448. * socket.async_send(boost::asio::buffer(data, size), handler);
  449. * @endcode
  450. * See the @ref buffer documentation for information on sending multiple
  451. * buffers in one go, and how to use it with arrays, boost::array or
  452. * std::vector.
  453. *
  454. * @par Per-Operation Cancellation
  455. * On POSIX or Windows operating systems, this asynchronous operation supports
  456. * cancellation for the following boost::asio::cancellation_type values:
  457. *
  458. * @li @c cancellation_type::terminal
  459. *
  460. * @li @c cancellation_type::partial
  461. *
  462. * @li @c cancellation_type::total
  463. */
  464. template <typename ConstBufferSequence,
  465. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  466. std::size_t)) WriteToken
  467. BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
  468. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,
  469. void (boost::system::error_code, std::size_t))
  470. async_send(const ConstBufferSequence& buffers,
  471. BOOST_ASIO_MOVE_ARG(WriteToken) token
  472. BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
  473. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
  474. async_initiate<WriteToken,
  475. void (boost::system::error_code, std::size_t)>(
  476. declval<initiate_async_send>(), token,
  477. buffers, socket_base::message_flags(0))))
  478. {
  479. return async_initiate<WriteToken,
  480. void (boost::system::error_code, std::size_t)>(
  481. initiate_async_send(this), token,
  482. buffers, socket_base::message_flags(0));
  483. }
  484. /// Start an asynchronous send.
  485. /**
  486. * This function is used to asynchronously send data on the stream socket.
  487. * It is an initiating function for an @ref asynchronous_operation, and always
  488. * returns immediately.
  489. *
  490. * @param buffers One or more data buffers to be sent on the socket. Although
  491. * the buffers object may be copied as necessary, ownership of the underlying
  492. * memory blocks is retained by the caller, which must guarantee that they
  493. * remain valid until the completion handler is called.
  494. *
  495. * @param flags Flags specifying how the send call is to be made.
  496. *
  497. * @param token The @ref completion_token that will be used to produce a
  498. * completion handler, which will be called when the send completes.
  499. * Potential completion tokens include @ref use_future, @ref use_awaitable,
  500. * @ref yield_context, or a function object with the correct completion
  501. * signature. The function signature of the completion handler must be:
  502. * @code void handler(
  503. * const boost::system::error_code& error, // Result of operation.
  504. * std::size_t bytes_transferred // Number of bytes sent.
  505. * ); @endcode
  506. * Regardless of whether the asynchronous operation completes immediately or
  507. * not, the completion handler will not be invoked from within this function.
  508. * On immediate completion, invocation of the handler will be performed in a
  509. * manner equivalent to using boost::asio::post().
  510. *
  511. * @par Completion Signature
  512. * @code void(boost::system::error_code, std::size_t) @endcode
  513. *
  514. * @note The send operation may not transmit all of the data to the peer.
  515. * Consider using the @ref async_write function if you need to ensure that all
  516. * data is written before the asynchronous operation completes.
  517. *
  518. * @par Example
  519. * To send a single data buffer use the @ref buffer function as follows:
  520. * @code
  521. * socket.async_send(boost::asio::buffer(data, size), 0, handler);
  522. * @endcode
  523. * See the @ref buffer documentation for information on sending multiple
  524. * buffers in one go, and how to use it with arrays, boost::array or
  525. * std::vector.
  526. *
  527. * @par Per-Operation Cancellation
  528. * On POSIX or Windows operating systems, this asynchronous operation supports
  529. * cancellation for the following boost::asio::cancellation_type values:
  530. *
  531. * @li @c cancellation_type::terminal
  532. *
  533. * @li @c cancellation_type::partial
  534. *
  535. * @li @c cancellation_type::total
  536. */
  537. template <typename ConstBufferSequence,
  538. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  539. std::size_t)) WriteToken
  540. BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
  541. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,
  542. void (boost::system::error_code, std::size_t))
  543. async_send(const ConstBufferSequence& buffers,
  544. socket_base::message_flags flags,
  545. BOOST_ASIO_MOVE_ARG(WriteToken) token
  546. BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
  547. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
  548. async_initiate<WriteToken,
  549. void (boost::system::error_code, std::size_t)>(
  550. declval<initiate_async_send>(), token, buffers, flags)))
  551. {
  552. return async_initiate<WriteToken,
  553. void (boost::system::error_code, std::size_t)>(
  554. initiate_async_send(this), token, buffers, flags);
  555. }
  556. /// Receive some data on the socket.
  557. /**
  558. * This function is used to receive data on the stream socket. The function
  559. * call will block until one or more bytes of data has been received
  560. * successfully, or until an error occurs.
  561. *
  562. * @param buffers One or more buffers into which the data will be received.
  563. *
  564. * @returns The number of bytes received.
  565. *
  566. * @throws boost::system::system_error Thrown on failure. An error code of
  567. * boost::asio::error::eof indicates that the connection was closed by the
  568. * peer.
  569. *
  570. * @note The receive operation may not receive all of the requested number of
  571. * bytes. Consider using the @ref read function if you need to ensure that the
  572. * requested amount of data is read before the blocking operation completes.
  573. *
  574. * @par Example
  575. * To receive into a single data buffer use the @ref buffer function as
  576. * follows:
  577. * @code
  578. * socket.receive(boost::asio::buffer(data, size));
  579. * @endcode
  580. * See the @ref buffer documentation for information on receiving into
  581. * multiple buffers in one go, and how to use it with arrays, boost::array or
  582. * std::vector.
  583. */
  584. template <typename MutableBufferSequence>
  585. std::size_t receive(const MutableBufferSequence& buffers)
  586. {
  587. boost::system::error_code ec;
  588. std::size_t s = this->impl_.get_service().receive(
  589. this->impl_.get_implementation(), buffers, 0, ec);
  590. boost::asio::detail::throw_error(ec, "receive");
  591. return s;
  592. }
  593. /// Receive some data on the socket.
  594. /**
  595. * This function is used to receive data on the stream socket. The function
  596. * call will block until one or more bytes of data has been received
  597. * successfully, or until an error occurs.
  598. *
  599. * @param buffers One or more buffers into which the data will be received.
  600. *
  601. * @param flags Flags specifying how the receive call is to be made.
  602. *
  603. * @returns The number of bytes received.
  604. *
  605. * @throws boost::system::system_error Thrown on failure. An error code of
  606. * boost::asio::error::eof indicates that the connection was closed by the
  607. * peer.
  608. *
  609. * @note The receive operation may not receive all of the requested number of
  610. * bytes. Consider using the @ref read function if you need to ensure that the
  611. * requested amount of data is read before the blocking operation completes.
  612. *
  613. * @par Example
  614. * To receive into a single data buffer use the @ref buffer function as
  615. * follows:
  616. * @code
  617. * socket.receive(boost::asio::buffer(data, size), 0);
  618. * @endcode
  619. * See the @ref buffer documentation for information on receiving into
  620. * multiple buffers in one go, and how to use it with arrays, boost::array or
  621. * std::vector.
  622. */
  623. template <typename MutableBufferSequence>
  624. std::size_t receive(const MutableBufferSequence& buffers,
  625. socket_base::message_flags flags)
  626. {
  627. boost::system::error_code ec;
  628. std::size_t s = this->impl_.get_service().receive(
  629. this->impl_.get_implementation(), buffers, flags, ec);
  630. boost::asio::detail::throw_error(ec, "receive");
  631. return s;
  632. }
  633. /// Receive some data on a connected socket.
  634. /**
  635. * This function is used to receive data on the stream socket. The function
  636. * call will block until one or more bytes of data has been received
  637. * successfully, or until an error occurs.
  638. *
  639. * @param buffers One or more buffers into which the data will be received.
  640. *
  641. * @param flags Flags specifying how the receive call is to be made.
  642. *
  643. * @param ec Set to indicate what error occurred, if any.
  644. *
  645. * @returns The number of bytes received. Returns 0 if an error occurred.
  646. *
  647. * @note The receive operation may not receive all of the requested number of
  648. * bytes. Consider using the @ref read function if you need to ensure that the
  649. * requested amount of data is read before the blocking operation completes.
  650. */
  651. template <typename MutableBufferSequence>
  652. std::size_t receive(const MutableBufferSequence& buffers,
  653. socket_base::message_flags flags, boost::system::error_code& ec)
  654. {
  655. return this->impl_.get_service().receive(
  656. this->impl_.get_implementation(), buffers, flags, ec);
  657. }
  658. /// Start an asynchronous receive.
  659. /**
  660. * This function is used to asynchronously receive data from the stream
  661. * socket. It is an initiating function for an @ref asynchronous_operation,
  662. * and always returns immediately.
  663. *
  664. * @param buffers One or more buffers into which the data will be received.
  665. * Although the buffers object may be copied as necessary, ownership of the
  666. * underlying memory blocks is retained by the caller, which must guarantee
  667. * that they remain valid until the completion handler is called.
  668. *
  669. * @param token The @ref completion_token that will be used to produce a
  670. * completion handler, which will be called when the receive completes.
  671. * Potential completion tokens include @ref use_future, @ref use_awaitable,
  672. * @ref yield_context, or a function object with the correct completion
  673. * signature. The function signature of the completion handler must be:
  674. * @code void handler(
  675. * const boost::system::error_code& error, // Result of operation.
  676. * std::size_t bytes_transferred // Number of bytes received.
  677. * ); @endcode
  678. * Regardless of whether the asynchronous operation completes immediately or
  679. * not, the completion handler will not be invoked from within this function.
  680. * On immediate completion, invocation of the handler will be performed in a
  681. * manner equivalent to using boost::asio::post().
  682. *
  683. * @par Completion Signature
  684. * @code void(boost::system::error_code, std::size_t) @endcode
  685. *
  686. * @note The receive operation may not receive all of the requested number of
  687. * bytes. Consider using the @ref async_read function if you need to ensure
  688. * that the requested amount of data is received before the asynchronous
  689. * operation completes.
  690. *
  691. * @par Example
  692. * To receive into a single data buffer use the @ref buffer function as
  693. * follows:
  694. * @code
  695. * socket.async_receive(boost::asio::buffer(data, size), handler);
  696. * @endcode
  697. * See the @ref buffer documentation for information on receiving into
  698. * multiple buffers in one go, and how to use it with arrays, boost::array or
  699. * std::vector.
  700. *
  701. * @par Per-Operation Cancellation
  702. * On POSIX or Windows operating systems, this asynchronous operation supports
  703. * cancellation for the following boost::asio::cancellation_type values:
  704. *
  705. * @li @c cancellation_type::terminal
  706. *
  707. * @li @c cancellation_type::partial
  708. *
  709. * @li @c cancellation_type::total
  710. */
  711. template <typename MutableBufferSequence,
  712. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  713. std::size_t)) ReadToken
  714. BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
  715. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,
  716. void (boost::system::error_code, std::size_t))
  717. async_receive(const MutableBufferSequence& buffers,
  718. BOOST_ASIO_MOVE_ARG(ReadToken) token
  719. BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
  720. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
  721. async_initiate<ReadToken,
  722. void (boost::system::error_code, std::size_t)>(
  723. declval<initiate_async_receive>(), token,
  724. buffers, socket_base::message_flags(0))))
  725. {
  726. return async_initiate<ReadToken,
  727. void (boost::system::error_code, std::size_t)>(
  728. initiate_async_receive(this), token,
  729. buffers, socket_base::message_flags(0));
  730. }
  731. /// Start an asynchronous receive.
  732. /**
  733. * This function is used to asynchronously receive data from the stream
  734. * socket. It is an initiating function for an @ref asynchronous_operation,
  735. * and always returns immediately.
  736. *
  737. * @param buffers One or more buffers into which the data will be received.
  738. * Although the buffers object may be copied as necessary, ownership of the
  739. * underlying memory blocks is retained by the caller, which must guarantee
  740. * that they remain valid until the completion handler is called.
  741. *
  742. * @param flags Flags specifying how the receive call is to be made.
  743. *
  744. * @param token The @ref completion_token that will be used to produce a
  745. * completion handler, which will be called when the receive completes.
  746. * Potential completion tokens include @ref use_future, @ref use_awaitable,
  747. * @ref yield_context, or a function object with the correct completion
  748. * signature. The function signature of the completion handler must be:
  749. * @code void handler(
  750. * const boost::system::error_code& error, // Result of operation.
  751. * std::size_t bytes_transferred // Number of bytes received.
  752. * ); @endcode
  753. * Regardless of whether the asynchronous operation completes immediately or
  754. * not, the completion handler will not be invoked from within this function.
  755. * On immediate completion, invocation of the handler will be performed in a
  756. * manner equivalent to using boost::asio::post().
  757. *
  758. * @par Completion Signature
  759. * @code void(boost::system::error_code, std::size_t) @endcode
  760. *
  761. * @note The receive operation may not receive all of the requested number of
  762. * bytes. Consider using the @ref async_read function if you need to ensure
  763. * that the requested amount of data is received before the asynchronous
  764. * operation completes.
  765. *
  766. * @par Example
  767. * To receive into a single data buffer use the @ref buffer function as
  768. * follows:
  769. * @code
  770. * socket.async_receive(boost::asio::buffer(data, size), 0, handler);
  771. * @endcode
  772. * See the @ref buffer documentation for information on receiving into
  773. * multiple buffers in one go, and how to use it with arrays, boost::array or
  774. * std::vector.
  775. *
  776. * @par Per-Operation Cancellation
  777. * On POSIX or Windows operating systems, this asynchronous operation supports
  778. * cancellation for the following boost::asio::cancellation_type values:
  779. *
  780. * @li @c cancellation_type::terminal
  781. *
  782. * @li @c cancellation_type::partial
  783. *
  784. * @li @c cancellation_type::total
  785. */
  786. template <typename MutableBufferSequence,
  787. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  788. std::size_t)) ReadToken
  789. BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
  790. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,
  791. void (boost::system::error_code, std::size_t))
  792. async_receive(const MutableBufferSequence& buffers,
  793. socket_base::message_flags flags,
  794. BOOST_ASIO_MOVE_ARG(ReadToken) token
  795. BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
  796. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
  797. async_initiate<ReadToken,
  798. void (boost::system::error_code, std::size_t)>(
  799. declval<initiate_async_receive>(), token, buffers, flags)))
  800. {
  801. return async_initiate<ReadToken,
  802. void (boost::system::error_code, std::size_t)>(
  803. initiate_async_receive(this), token, buffers, flags);
  804. }
  805. /// Write some data to the socket.
  806. /**
  807. * This function is used to write data to the stream socket. The function call
  808. * will block until one or more bytes of the data has been written
  809. * successfully, or until an error occurs.
  810. *
  811. * @param buffers One or more data buffers to be written to the socket.
  812. *
  813. * @returns The number of bytes written.
  814. *
  815. * @throws boost::system::system_error Thrown on failure. An error code of
  816. * boost::asio::error::eof indicates that the connection was closed by the
  817. * peer.
  818. *
  819. * @note The write_some operation may not transmit all of the data to the
  820. * peer. Consider using the @ref write function if you need to ensure that
  821. * all data is written before the blocking operation completes.
  822. *
  823. * @par Example
  824. * To write a single data buffer use the @ref buffer function as follows:
  825. * @code
  826. * socket.write_some(boost::asio::buffer(data, size));
  827. * @endcode
  828. * See the @ref buffer documentation for information on writing multiple
  829. * buffers in one go, and how to use it with arrays, boost::array or
  830. * std::vector.
  831. */
  832. template <typename ConstBufferSequence>
  833. std::size_t write_some(const ConstBufferSequence& buffers)
  834. {
  835. boost::system::error_code ec;
  836. std::size_t s = this->impl_.get_service().send(
  837. this->impl_.get_implementation(), buffers, 0, ec);
  838. boost::asio::detail::throw_error(ec, "write_some");
  839. return s;
  840. }
  841. /// Write some data to the socket.
  842. /**
  843. * This function is used to write data to the stream socket. The function call
  844. * will block until one or more bytes of the data has been written
  845. * successfully, or until an error occurs.
  846. *
  847. * @param buffers One or more data buffers to be written to the socket.
  848. *
  849. * @param ec Set to indicate what error occurred, if any.
  850. *
  851. * @returns The number of bytes written. Returns 0 if an error occurred.
  852. *
  853. * @note The write_some operation may not transmit all of the data to the
  854. * peer. Consider using the @ref write function if you need to ensure that
  855. * all data is written before the blocking operation completes.
  856. */
  857. template <typename ConstBufferSequence>
  858. std::size_t write_some(const ConstBufferSequence& buffers,
  859. boost::system::error_code& ec)
  860. {
  861. return this->impl_.get_service().send(
  862. this->impl_.get_implementation(), buffers, 0, ec);
  863. }
  864. /// Start an asynchronous write.
  865. /**
  866. * This function is used to asynchronously write data to the stream socket.
  867. * It is an initiating function for an @ref asynchronous_operation, and always
  868. * returns immediately.
  869. *
  870. * @param buffers One or more data buffers to be written to the socket.
  871. * Although the buffers object may be copied as necessary, ownership of the
  872. * underlying memory blocks is retained by the caller, which must guarantee
  873. * that they remain valid until the completion handler is called.
  874. *
  875. * @param token The @ref completion_token that will be used to produce a
  876. * completion handler, which will be called when the write completes.
  877. * Potential completion tokens include @ref use_future, @ref use_awaitable,
  878. * @ref yield_context, or a function object with the correct completion
  879. * signature. The function signature of the completion handler must be:
  880. * @code void handler(
  881. * const boost::system::error_code& error, // Result of operation.
  882. * std::size_t bytes_transferred // Number of bytes written.
  883. * ); @endcode
  884. * Regardless of whether the asynchronous operation completes immediately or
  885. * not, the completion handler will not be invoked from within this function.
  886. * On immediate completion, invocation of the handler will be performed in a
  887. * manner equivalent to using boost::asio::post().
  888. *
  889. * @par Completion Signature
  890. * @code void(boost::system::error_code, std::size_t) @endcode
  891. *
  892. * @note The write operation may not transmit all of the data to the peer.
  893. * Consider using the @ref async_write function if you need to ensure that all
  894. * data is written before the asynchronous operation completes.
  895. *
  896. * @par Example
  897. * To write a single data buffer use the @ref buffer function as follows:
  898. * @code
  899. * socket.async_write_some(boost::asio::buffer(data, size), handler);
  900. * @endcode
  901. * See the @ref buffer documentation for information on writing multiple
  902. * buffers in one go, and how to use it with arrays, boost::array or
  903. * std::vector.
  904. *
  905. * @par Per-Operation Cancellation
  906. * On POSIX or Windows operating systems, this asynchronous operation supports
  907. * cancellation for the following boost::asio::cancellation_type values:
  908. *
  909. * @li @c cancellation_type::terminal
  910. *
  911. * @li @c cancellation_type::partial
  912. *
  913. * @li @c cancellation_type::total
  914. */
  915. template <typename ConstBufferSequence,
  916. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  917. std::size_t)) WriteToken
  918. BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
  919. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,
  920. void (boost::system::error_code, std::size_t))
  921. async_write_some(const ConstBufferSequence& buffers,
  922. BOOST_ASIO_MOVE_ARG(WriteToken) token
  923. BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
  924. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
  925. async_initiate<WriteToken,
  926. void (boost::system::error_code, std::size_t)>(
  927. declval<initiate_async_send>(), token,
  928. buffers, socket_base::message_flags(0))))
  929. {
  930. return async_initiate<WriteToken,
  931. void (boost::system::error_code, std::size_t)>(
  932. initiate_async_send(this), token,
  933. buffers, socket_base::message_flags(0));
  934. }
  935. /// Read some data from the socket.
  936. /**
  937. * This function is used to read data from the stream socket. The function
  938. * call will block until one or more bytes of data has been read successfully,
  939. * or until an error occurs.
  940. *
  941. * @param buffers One or more buffers into which the data will be read.
  942. *
  943. * @returns The number of bytes read.
  944. *
  945. * @throws boost::system::system_error Thrown on failure. An error code of
  946. * boost::asio::error::eof indicates that the connection was closed by the
  947. * peer.
  948. *
  949. * @note The read_some operation may not read all of the requested number of
  950. * bytes. Consider using the @ref read function if you need to ensure that
  951. * the requested amount of data is read before the blocking operation
  952. * completes.
  953. *
  954. * @par Example
  955. * To read into a single data buffer use the @ref buffer function as follows:
  956. * @code
  957. * socket.read_some(boost::asio::buffer(data, size));
  958. * @endcode
  959. * See the @ref buffer documentation for information on reading into multiple
  960. * buffers in one go, and how to use it with arrays, boost::array or
  961. * std::vector.
  962. */
  963. template <typename MutableBufferSequence>
  964. std::size_t read_some(const MutableBufferSequence& buffers)
  965. {
  966. boost::system::error_code ec;
  967. std::size_t s = this->impl_.get_service().receive(
  968. this->impl_.get_implementation(), buffers, 0, ec);
  969. boost::asio::detail::throw_error(ec, "read_some");
  970. return s;
  971. }
  972. /// Read some data from the socket.
  973. /**
  974. * This function is used to read data from the stream socket. The function
  975. * call will block until one or more bytes of data has been read successfully,
  976. * or until an error occurs.
  977. *
  978. * @param buffers One or more buffers into which the data will be read.
  979. *
  980. * @param ec Set to indicate what error occurred, if any.
  981. *
  982. * @returns The number of bytes read. Returns 0 if an error occurred.
  983. *
  984. * @note The read_some operation may not read all of the requested number of
  985. * bytes. Consider using the @ref read function if you need to ensure that
  986. * the requested amount of data is read before the blocking operation
  987. * completes.
  988. */
  989. template <typename MutableBufferSequence>
  990. std::size_t read_some(const MutableBufferSequence& buffers,
  991. boost::system::error_code& ec)
  992. {
  993. return this->impl_.get_service().receive(
  994. this->impl_.get_implementation(), buffers, 0, ec);
  995. }
  996. /// Start an asynchronous read.
  997. /**
  998. * This function is used to asynchronously read data from the stream socket.
  999. * socket. It is an initiating function for an @ref asynchronous_operation,
  1000. * and always returns immediately.
  1001. *
  1002. * @param buffers One or more buffers into which the data will be read.
  1003. * Although the buffers object may be copied as necessary, ownership of the
  1004. * underlying memory blocks is retained by the caller, which must guarantee
  1005. * that they remain valid until the completion handler is called.
  1006. *
  1007. * @param token The @ref completion_token that will be used to produce a
  1008. * completion handler, which will be called when the read completes.
  1009. * Potential completion tokens include @ref use_future, @ref use_awaitable,
  1010. * @ref yield_context, or a function object with the correct completion
  1011. * signature. The function signature of the completion handler must be:
  1012. * @code void handler(
  1013. * const boost::system::error_code& error, // Result of operation.
  1014. * std::size_t bytes_transferred // Number of bytes read.
  1015. * ); @endcode
  1016. * Regardless of whether the asynchronous operation completes immediately or
  1017. * not, the completion handler will not be invoked from within this function.
  1018. * On immediate completion, invocation of the handler will be performed in a
  1019. * manner equivalent to using boost::asio::post().
  1020. *
  1021. * @par Completion Signature
  1022. * @code void(boost::system::error_code, std::size_t) @endcode
  1023. *
  1024. * @note The read operation may not read all of the requested number of bytes.
  1025. * Consider using the @ref async_read function if you need to ensure that the
  1026. * requested amount of data is read before the asynchronous operation
  1027. * completes.
  1028. *
  1029. * @par Example
  1030. * To read into a single data buffer use the @ref buffer function as follows:
  1031. * @code
  1032. * socket.async_read_some(boost::asio::buffer(data, size), handler);
  1033. * @endcode
  1034. * See the @ref buffer documentation for information on reading into multiple
  1035. * buffers in one go, and how to use it with arrays, boost::array or
  1036. * std::vector.
  1037. *
  1038. * @par Per-Operation Cancellation
  1039. * On POSIX or Windows operating systems, this asynchronous operation supports
  1040. * cancellation for the following boost::asio::cancellation_type values:
  1041. *
  1042. * @li @c cancellation_type::terminal
  1043. *
  1044. * @li @c cancellation_type::partial
  1045. *
  1046. * @li @c cancellation_type::total
  1047. */
  1048. template <typename MutableBufferSequence,
  1049. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  1050. std::size_t)) ReadToken
  1051. BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
  1052. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,
  1053. void (boost::system::error_code, std::size_t))
  1054. async_read_some(const MutableBufferSequence& buffers,
  1055. BOOST_ASIO_MOVE_ARG(ReadToken) token
  1056. BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
  1057. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
  1058. async_initiate<ReadToken,
  1059. void (boost::system::error_code, std::size_t)>(
  1060. declval<initiate_async_receive>(), token,
  1061. buffers, socket_base::message_flags(0))))
  1062. {
  1063. return async_initiate<ReadToken,
  1064. void (boost::system::error_code, std::size_t)>(
  1065. initiate_async_receive(this), token,
  1066. buffers, socket_base::message_flags(0));
  1067. }
  1068. private:
  1069. // Disallow copying and assignment.
  1070. basic_stream_socket(const basic_stream_socket&) BOOST_ASIO_DELETED;
  1071. basic_stream_socket& operator=(const basic_stream_socket&) BOOST_ASIO_DELETED;
  1072. class initiate_async_send
  1073. {
  1074. public:
  1075. typedef Executor executor_type;
  1076. explicit initiate_async_send(basic_stream_socket* self)
  1077. : self_(self)
  1078. {
  1079. }
  1080. const executor_type& get_executor() const BOOST_ASIO_NOEXCEPT
  1081. {
  1082. return self_->get_executor();
  1083. }
  1084. template <typename WriteHandler, typename ConstBufferSequence>
  1085. void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
  1086. const ConstBufferSequence& buffers,
  1087. socket_base::message_flags flags) const
  1088. {
  1089. // If you get an error on the following line it means that your handler
  1090. // does not meet the documented type requirements for a WriteHandler.
  1091. BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
  1092. detail::non_const_lvalue<WriteHandler> handler2(handler);
  1093. self_->impl_.get_service().async_send(
  1094. self_->impl_.get_implementation(), buffers, flags,
  1095. handler2.value, self_->impl_.get_executor());
  1096. }
  1097. private:
  1098. basic_stream_socket* self_;
  1099. };
  1100. class initiate_async_receive
  1101. {
  1102. public:
  1103. typedef Executor executor_type;
  1104. explicit initiate_async_receive(basic_stream_socket* self)
  1105. : self_(self)
  1106. {
  1107. }
  1108. const executor_type& get_executor() const BOOST_ASIO_NOEXCEPT
  1109. {
  1110. return self_->get_executor();
  1111. }
  1112. template <typename ReadHandler, typename MutableBufferSequence>
  1113. void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
  1114. const MutableBufferSequence& buffers,
  1115. socket_base::message_flags flags) const
  1116. {
  1117. // If you get an error on the following line it means that your handler
  1118. // does not meet the documented type requirements for a ReadHandler.
  1119. BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
  1120. detail::non_const_lvalue<ReadHandler> handler2(handler);
  1121. self_->impl_.get_service().async_receive(
  1122. self_->impl_.get_implementation(), buffers, flags,
  1123. handler2.value, self_->impl_.get_executor());
  1124. }
  1125. private:
  1126. basic_stream_socket* self_;
  1127. };
  1128. };
  1129. } // namespace asio
  1130. } // namespace boost
  1131. #include <boost/asio/detail/pop_options.hpp>
  1132. #endif // BOOST_ASIO_BASIC_STREAM_SOCKET_HPP