basic_stream_socket.hpp 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165
  1. //
  2. // basic_stream_socket.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2024 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef BOOST_ASIO_BASIC_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. constraint_t<
  105. is_convertible<ExecutionContext&, execution_context&>::value
  106. > = 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. constraint_t<
  142. is_convertible<ExecutionContext&, execution_context&>::value,
  143. defaulted_constraint
  144. > = 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. constraint_t<
  186. is_convertible<ExecutionContext&, execution_context&>::value
  187. > = 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. constraint_t<
  229. is_convertible<ExecutionContext&, execution_context&>::value
  230. > = 0)
  231. : basic_socket<Protocol, Executor>(context, protocol, native_socket)
  232. {
  233. }
  234. /// Move-construct a basic_stream_socket from another.
  235. /**
  236. * This constructor moves a stream socket from one object to another.
  237. *
  238. * @param other The other basic_stream_socket object from which the move
  239. * will occur.
  240. *
  241. * @note Following the move, the moved-from object is in the same state as if
  242. * constructed using the @c basic_stream_socket(const executor_type&)
  243. * constructor.
  244. */
  245. basic_stream_socket(basic_stream_socket&& other) noexcept
  246. : basic_socket<Protocol, Executor>(std::move(other))
  247. {
  248. }
  249. /// Move-assign a basic_stream_socket from another.
  250. /**
  251. * This assignment operator moves a stream socket from one object to another.
  252. *
  253. * @param other The other basic_stream_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_stream_socket(const executor_type&)
  258. * constructor.
  259. */
  260. basic_stream_socket& operator=(basic_stream_socket&& other)
  261. {
  262. basic_socket<Protocol, Executor>::operator=(std::move(other));
  263. return *this;
  264. }
  265. /// Move-construct a basic_stream_socket from a socket of another protocol
  266. /// type.
  267. /**
  268. * This constructor moves a stream socket from one object to another.
  269. *
  270. * @param other The other basic_stream_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_stream_socket(const executor_type&)
  275. * constructor.
  276. */
  277. template <typename Protocol1, typename Executor1>
  278. basic_stream_socket(basic_stream_socket<Protocol1, Executor1>&& other,
  279. constraint_t<
  280. is_convertible<Protocol1, Protocol>::value
  281. && is_convertible<Executor1, Executor>::value
  282. > = 0)
  283. : basic_socket<Protocol, Executor>(std::move(other))
  284. {
  285. }
  286. /// Move-assign a basic_stream_socket from a socket of another protocol type.
  287. /**
  288. * This assignment operator moves a stream socket from one object to another.
  289. *
  290. * @param other The other basic_stream_socket object from which the move
  291. * will occur.
  292. *
  293. * @note Following the move, the moved-from object is in the same state as if
  294. * constructed using the @c basic_stream_socket(const executor_type&)
  295. * constructor.
  296. */
  297. template <typename Protocol1, typename Executor1>
  298. constraint_t<
  299. is_convertible<Protocol1, Protocol>::value
  300. && is_convertible<Executor1, Executor>::value,
  301. basic_stream_socket&
  302. > operator=(basic_stream_socket<Protocol1, Executor1>&& other)
  303. {
  304. basic_socket<Protocol, Executor>::operator=(std::move(other));
  305. return *this;
  306. }
  307. /// Destroys the socket.
  308. /**
  309. * This function destroys the socket, cancelling any outstanding asynchronous
  310. * operations associated with the socket as if by calling @c cancel.
  311. */
  312. ~basic_stream_socket()
  313. {
  314. }
  315. /// Send some data on the socket.
  316. /**
  317. * This function is used to send data on the stream socket. The function
  318. * call will block until one or more bytes of the data has been sent
  319. * successfully, or an until error occurs.
  320. *
  321. * @param buffers One or more data buffers to be sent on the socket.
  322. *
  323. * @returns The number of bytes sent.
  324. *
  325. * @throws boost::system::system_error Thrown on failure.
  326. *
  327. * @note The send operation may not transmit all of the data to the peer.
  328. * Consider using the @ref write function if you need to ensure that all data
  329. * is written before the blocking operation completes.
  330. *
  331. * @par Example
  332. * To send a single data buffer use the @ref buffer function as follows:
  333. * @code
  334. * socket.send(boost::asio::buffer(data, size));
  335. * @endcode
  336. * See the @ref buffer documentation for information on sending multiple
  337. * buffers in one go, and how to use it with arrays, boost::array or
  338. * std::vector.
  339. */
  340. template <typename ConstBufferSequence>
  341. std::size_t send(const ConstBufferSequence& buffers)
  342. {
  343. boost::system::error_code ec;
  344. std::size_t s = this->impl_.get_service().send(
  345. this->impl_.get_implementation(), buffers, 0, ec);
  346. boost::asio::detail::throw_error(ec, "send");
  347. return s;
  348. }
  349. /// Send some data on the socket.
  350. /**
  351. * This function is used to send data on the stream socket. The function
  352. * call will block until one or more bytes of the data has been sent
  353. * successfully, or an until error occurs.
  354. *
  355. * @param buffers One or more data buffers to be sent on the socket.
  356. *
  357. * @param flags Flags specifying how the send call is to be made.
  358. *
  359. * @returns The number of bytes sent.
  360. *
  361. * @throws boost::system::system_error Thrown on failure.
  362. *
  363. * @note The send operation may not transmit all of the data to the peer.
  364. * Consider using the @ref write function if you need to ensure that all data
  365. * is written before the blocking operation completes.
  366. *
  367. * @par Example
  368. * To send a single data buffer use the @ref buffer function as follows:
  369. * @code
  370. * socket.send(boost::asio::buffer(data, size), 0);
  371. * @endcode
  372. * See the @ref buffer documentation for information on sending multiple
  373. * buffers in one go, and how to use it with arrays, boost::array or
  374. * std::vector.
  375. */
  376. template <typename ConstBufferSequence>
  377. std::size_t send(const ConstBufferSequence& buffers,
  378. socket_base::message_flags flags)
  379. {
  380. boost::system::error_code ec;
  381. std::size_t s = this->impl_.get_service().send(
  382. this->impl_.get_implementation(), buffers, flags, ec);
  383. boost::asio::detail::throw_error(ec, "send");
  384. return s;
  385. }
  386. /// Send some data on the socket.
  387. /**
  388. * This function is used to send data on the stream socket. The function
  389. * call will block until one or more bytes of the data has been sent
  390. * successfully, or an until error occurs.
  391. *
  392. * @param buffers One or more data buffers to be sent on the socket.
  393. *
  394. * @param flags Flags specifying how the send call is to be made.
  395. *
  396. * @param ec Set to indicate what error occurred, if any.
  397. *
  398. * @returns The number of bytes sent. Returns 0 if an error occurred.
  399. *
  400. * @note The send operation may not transmit all of the data to the peer.
  401. * Consider using the @ref write function if you need to ensure that all data
  402. * is written before the blocking operation completes.
  403. */
  404. template <typename ConstBufferSequence>
  405. std::size_t send(const ConstBufferSequence& buffers,
  406. socket_base::message_flags flags, boost::system::error_code& ec)
  407. {
  408. return this->impl_.get_service().send(
  409. this->impl_.get_implementation(), buffers, flags, ec);
  410. }
  411. /// Start an asynchronous send.
  412. /**
  413. * This function is used to asynchronously send data on the stream socket.
  414. * It is an initiating function for an @ref asynchronous_operation, and always
  415. * returns immediately.
  416. *
  417. * @param buffers One or more data buffers to be sent on the socket. Although
  418. * the buffers object may be copied as necessary, ownership of the underlying
  419. * memory blocks is retained by the caller, which must guarantee that they
  420. * remain valid until the completion handler is called.
  421. *
  422. * @param token The @ref completion_token that will be used to produce a
  423. * completion handler, which will be called when the send completes.
  424. * Potential completion tokens include @ref use_future, @ref use_awaitable,
  425. * @ref yield_context, or a function object with the correct completion
  426. * signature. The function signature of the completion handler must be:
  427. * @code void handler(
  428. * const boost::system::error_code& error, // Result of operation.
  429. * std::size_t bytes_transferred // Number of bytes sent.
  430. * ); @endcode
  431. * Regardless of whether the asynchronous operation completes immediately or
  432. * not, the completion handler will not be invoked from within this function.
  433. * On immediate completion, invocation of the handler will be performed in a
  434. * manner equivalent to using boost::asio::async_immediate().
  435. *
  436. * @par Completion Signature
  437. * @code void(boost::system::error_code, std::size_t) @endcode
  438. *
  439. * @note The send operation may not transmit all of the data to the peer.
  440. * Consider using the @ref async_write function if you need to ensure that all
  441. * data is written before the asynchronous operation completes.
  442. *
  443. * @par Example
  444. * To send a single data buffer use the @ref buffer function as follows:
  445. * @code
  446. * socket.async_send(boost::asio::buffer(data, size), handler);
  447. * @endcode
  448. * See the @ref buffer documentation for information on sending multiple
  449. * buffers in one go, and how to use it with arrays, boost::array or
  450. * std::vector.
  451. *
  452. * @par Per-Operation Cancellation
  453. * On POSIX or Windows operating systems, this asynchronous operation supports
  454. * cancellation for the following boost::asio::cancellation_type values:
  455. *
  456. * @li @c cancellation_type::terminal
  457. *
  458. * @li @c cancellation_type::partial
  459. *
  460. * @li @c cancellation_type::total
  461. */
  462. template <typename ConstBufferSequence,
  463. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  464. std::size_t)) WriteToken = default_completion_token_t<executor_type>>
  465. auto async_send(const ConstBufferSequence& buffers,
  466. WriteToken&& token = default_completion_token_t<executor_type>())
  467. -> decltype(
  468. async_initiate<WriteToken,
  469. void (boost::system::error_code, std::size_t)>(
  470. declval<initiate_async_send>(), token,
  471. buffers, socket_base::message_flags(0)))
  472. {
  473. return async_initiate<WriteToken,
  474. void (boost::system::error_code, std::size_t)>(
  475. initiate_async_send(this), token,
  476. buffers, socket_base::message_flags(0));
  477. }
  478. /// Start an asynchronous send.
  479. /**
  480. * This function is used to asynchronously send data on the stream socket.
  481. * It is an initiating function for an @ref asynchronous_operation, and always
  482. * returns immediately.
  483. *
  484. * @param buffers One or more data buffers to be sent on the socket. Although
  485. * the buffers object may be copied as necessary, ownership of the underlying
  486. * memory blocks is retained by the caller, which must guarantee that they
  487. * remain valid until the completion handler is called.
  488. *
  489. * @param flags Flags specifying how the send call is to be made.
  490. *
  491. * @param token The @ref completion_token that will be used to produce a
  492. * completion handler, which will be called when the send completes.
  493. * Potential completion tokens include @ref use_future, @ref use_awaitable,
  494. * @ref yield_context, or a function object with the correct completion
  495. * signature. The function signature of the completion handler must be:
  496. * @code void handler(
  497. * const boost::system::error_code& error, // Result of operation.
  498. * std::size_t bytes_transferred // Number of bytes sent.
  499. * ); @endcode
  500. * Regardless of whether the asynchronous operation completes immediately or
  501. * not, the completion handler will not be invoked from within this function.
  502. * On immediate completion, invocation of the handler will be performed in a
  503. * manner equivalent to using boost::asio::async_immediate().
  504. *
  505. * @par Completion Signature
  506. * @code void(boost::system::error_code, std::size_t) @endcode
  507. *
  508. * @note The send operation may not transmit all of the data to the peer.
  509. * Consider using the @ref async_write function if you need to ensure that all
  510. * data is written before the asynchronous operation completes.
  511. *
  512. * @par Example
  513. * To send a single data buffer use the @ref buffer function as follows:
  514. * @code
  515. * socket.async_send(boost::asio::buffer(data, size), 0, handler);
  516. * @endcode
  517. * See the @ref buffer documentation for information on sending multiple
  518. * buffers in one go, and how to use it with arrays, boost::array or
  519. * std::vector.
  520. *
  521. * @par Per-Operation Cancellation
  522. * On POSIX or Windows operating systems, this asynchronous operation supports
  523. * cancellation for the following boost::asio::cancellation_type values:
  524. *
  525. * @li @c cancellation_type::terminal
  526. *
  527. * @li @c cancellation_type::partial
  528. *
  529. * @li @c cancellation_type::total
  530. */
  531. template <typename ConstBufferSequence,
  532. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  533. std::size_t)) WriteToken = default_completion_token_t<executor_type>>
  534. auto async_send(const ConstBufferSequence& buffers,
  535. socket_base::message_flags flags,
  536. WriteToken&& token = default_completion_token_t<executor_type>())
  537. -> decltype(
  538. async_initiate<WriteToken,
  539. void (boost::system::error_code, std::size_t)>(
  540. declval<initiate_async_send>(), token, buffers, flags))
  541. {
  542. return async_initiate<WriteToken,
  543. void (boost::system::error_code, std::size_t)>(
  544. initiate_async_send(this), token, buffers, flags);
  545. }
  546. /// Receive some data on the socket.
  547. /**
  548. * This function is used to receive data on the stream socket. The function
  549. * call will block until one or more bytes of data has been received
  550. * successfully, or until an error occurs.
  551. *
  552. * @param buffers One or more buffers into which the data will be received.
  553. *
  554. * @returns The number of bytes received.
  555. *
  556. * @throws boost::system::system_error Thrown on failure. An error code of
  557. * boost::asio::error::eof indicates that the connection was closed by the
  558. * peer.
  559. *
  560. * @note The receive operation may not receive all of the requested number of
  561. * bytes. Consider using the @ref read function if you need to ensure that the
  562. * requested amount of data is read before the blocking operation completes.
  563. *
  564. * @par Example
  565. * To receive into a single data buffer use the @ref buffer function as
  566. * follows:
  567. * @code
  568. * socket.receive(boost::asio::buffer(data, size));
  569. * @endcode
  570. * See the @ref buffer documentation for information on receiving into
  571. * multiple buffers in one go, and how to use it with arrays, boost::array or
  572. * std::vector.
  573. */
  574. template <typename MutableBufferSequence>
  575. std::size_t receive(const MutableBufferSequence& buffers)
  576. {
  577. boost::system::error_code ec;
  578. std::size_t s = this->impl_.get_service().receive(
  579. this->impl_.get_implementation(), buffers, 0, ec);
  580. boost::asio::detail::throw_error(ec, "receive");
  581. return s;
  582. }
  583. /// Receive some data on the socket.
  584. /**
  585. * This function is used to receive data on the stream socket. The function
  586. * call will block until one or more bytes of data has been received
  587. * successfully, or until an error occurs.
  588. *
  589. * @param buffers One or more buffers into which the data will be received.
  590. *
  591. * @param flags Flags specifying how the receive call is to be made.
  592. *
  593. * @returns The number of bytes received.
  594. *
  595. * @throws boost::system::system_error Thrown on failure. An error code of
  596. * boost::asio::error::eof indicates that the connection was closed by the
  597. * peer.
  598. *
  599. * @note The receive operation may not receive all of the requested number of
  600. * bytes. Consider using the @ref read function if you need to ensure that the
  601. * requested amount of data is read before the blocking operation completes.
  602. *
  603. * @par Example
  604. * To receive into a single data buffer use the @ref buffer function as
  605. * follows:
  606. * @code
  607. * socket.receive(boost::asio::buffer(data, size), 0);
  608. * @endcode
  609. * See the @ref buffer documentation for information on receiving into
  610. * multiple buffers in one go, and how to use it with arrays, boost::array or
  611. * std::vector.
  612. */
  613. template <typename MutableBufferSequence>
  614. std::size_t receive(const MutableBufferSequence& buffers,
  615. socket_base::message_flags flags)
  616. {
  617. boost::system::error_code ec;
  618. std::size_t s = this->impl_.get_service().receive(
  619. this->impl_.get_implementation(), buffers, flags, ec);
  620. boost::asio::detail::throw_error(ec, "receive");
  621. return s;
  622. }
  623. /// Receive some data on a connected socket.
  624. /**
  625. * This function is used to receive data on the stream socket. The function
  626. * call will block until one or more bytes of data has been received
  627. * successfully, or until an error occurs.
  628. *
  629. * @param buffers One or more buffers into which the data will be received.
  630. *
  631. * @param flags Flags specifying how the receive call is to be made.
  632. *
  633. * @param ec Set to indicate what error occurred, if any.
  634. *
  635. * @returns The number of bytes received. Returns 0 if an error occurred.
  636. *
  637. * @note The receive operation may not receive all of the requested number of
  638. * bytes. Consider using the @ref read function if you need to ensure that the
  639. * requested amount of data is read before the blocking operation completes.
  640. */
  641. template <typename MutableBufferSequence>
  642. std::size_t receive(const MutableBufferSequence& buffers,
  643. socket_base::message_flags flags, boost::system::error_code& ec)
  644. {
  645. return this->impl_.get_service().receive(
  646. this->impl_.get_implementation(), buffers, flags, ec);
  647. }
  648. /// Start an asynchronous receive.
  649. /**
  650. * This function is used to asynchronously receive data from the stream
  651. * socket. It is an initiating function for an @ref asynchronous_operation,
  652. * and always returns immediately.
  653. *
  654. * @param buffers One or more buffers into which the data will be received.
  655. * Although the buffers object may be copied as necessary, ownership of the
  656. * underlying memory blocks is retained by the caller, which must guarantee
  657. * that they remain valid until the completion handler is called.
  658. *
  659. * @param token The @ref completion_token that will be used to produce a
  660. * completion handler, which will be called when the receive completes.
  661. * Potential completion tokens include @ref use_future, @ref use_awaitable,
  662. * @ref yield_context, or a function object with the correct completion
  663. * signature. The function signature of the completion handler must be:
  664. * @code void handler(
  665. * const boost::system::error_code& error, // Result of operation.
  666. * std::size_t bytes_transferred // Number of bytes received.
  667. * ); @endcode
  668. * Regardless of whether the asynchronous operation completes immediately or
  669. * not, the completion handler will not be invoked from within this function.
  670. * On immediate completion, invocation of the handler will be performed in a
  671. * manner equivalent to using boost::asio::async_immediate().
  672. *
  673. * @par Completion Signature
  674. * @code void(boost::system::error_code, std::size_t) @endcode
  675. *
  676. * @note The receive operation may not receive all of the requested number of
  677. * bytes. Consider using the @ref async_read function if you need to ensure
  678. * that the requested amount of data is received before the asynchronous
  679. * operation completes.
  680. *
  681. * @par Example
  682. * To receive into a single data buffer use the @ref buffer function as
  683. * follows:
  684. * @code
  685. * socket.async_receive(boost::asio::buffer(data, size), handler);
  686. * @endcode
  687. * See the @ref buffer documentation for information on receiving into
  688. * multiple buffers in one go, and how to use it with arrays, boost::array or
  689. * std::vector.
  690. *
  691. * @par Per-Operation Cancellation
  692. * On POSIX or Windows operating systems, this asynchronous operation supports
  693. * cancellation for the following boost::asio::cancellation_type values:
  694. *
  695. * @li @c cancellation_type::terminal
  696. *
  697. * @li @c cancellation_type::partial
  698. *
  699. * @li @c cancellation_type::total
  700. */
  701. template <typename MutableBufferSequence,
  702. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  703. std::size_t)) ReadToken = default_completion_token_t<executor_type>>
  704. auto async_receive(const MutableBufferSequence& buffers,
  705. ReadToken&& token = default_completion_token_t<executor_type>())
  706. -> decltype(
  707. async_initiate<ReadToken,
  708. void (boost::system::error_code, std::size_t)>(
  709. declval<initiate_async_receive>(), token,
  710. buffers, socket_base::message_flags(0)))
  711. {
  712. return async_initiate<ReadToken,
  713. void (boost::system::error_code, std::size_t)>(
  714. initiate_async_receive(this), token,
  715. buffers, socket_base::message_flags(0));
  716. }
  717. /// Start an asynchronous receive.
  718. /**
  719. * This function is used to asynchronously receive data from the stream
  720. * socket. It is an initiating function for an @ref asynchronous_operation,
  721. * and always returns immediately.
  722. *
  723. * @param buffers One or more buffers into which the data will be received.
  724. * Although the buffers object may be copied as necessary, ownership of the
  725. * underlying memory blocks is retained by the caller, which must guarantee
  726. * that they remain valid until the completion handler is called.
  727. *
  728. * @param flags Flags specifying how the receive call is to be made.
  729. *
  730. * @param token The @ref completion_token that will be used to produce a
  731. * completion handler, which will be called when the receive completes.
  732. * Potential completion tokens include @ref use_future, @ref use_awaitable,
  733. * @ref yield_context, or a function object with the correct completion
  734. * signature. The function signature of the completion handler must be:
  735. * @code void handler(
  736. * const boost::system::error_code& error, // Result of operation.
  737. * std::size_t bytes_transferred // Number of bytes received.
  738. * ); @endcode
  739. * Regardless of whether the asynchronous operation completes immediately or
  740. * not, the completion handler will not be invoked from within this function.
  741. * On immediate completion, invocation of the handler will be performed in a
  742. * manner equivalent to using boost::asio::async_immediate().
  743. *
  744. * @par Completion Signature
  745. * @code void(boost::system::error_code, std::size_t) @endcode
  746. *
  747. * @note The receive operation may not receive all of the requested number of
  748. * bytes. Consider using the @ref async_read function if you need to ensure
  749. * that the requested amount of data is received before the asynchronous
  750. * operation completes.
  751. *
  752. * @par Example
  753. * To receive into a single data buffer use the @ref buffer function as
  754. * follows:
  755. * @code
  756. * socket.async_receive(boost::asio::buffer(data, size), 0, handler);
  757. * @endcode
  758. * See the @ref buffer documentation for information on receiving into
  759. * multiple buffers in one go, and how to use it with arrays, boost::array or
  760. * std::vector.
  761. *
  762. * @par Per-Operation Cancellation
  763. * On POSIX or Windows operating systems, this asynchronous operation supports
  764. * cancellation for the following boost::asio::cancellation_type values:
  765. *
  766. * @li @c cancellation_type::terminal
  767. *
  768. * @li @c cancellation_type::partial
  769. *
  770. * @li @c cancellation_type::total
  771. */
  772. template <typename MutableBufferSequence,
  773. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  774. std::size_t)) ReadToken = default_completion_token_t<executor_type>>
  775. auto async_receive(const MutableBufferSequence& buffers,
  776. socket_base::message_flags flags,
  777. ReadToken&& token = default_completion_token_t<executor_type>())
  778. -> decltype(
  779. async_initiate<ReadToken,
  780. void (boost::system::error_code, std::size_t)>(
  781. declval<initiate_async_receive>(), token, buffers, flags))
  782. {
  783. return async_initiate<ReadToken,
  784. void (boost::system::error_code, std::size_t)>(
  785. initiate_async_receive(this), token, buffers, flags);
  786. }
  787. /// Write some data to the socket.
  788. /**
  789. * This function is used to write data to the stream socket. The function call
  790. * will block until one or more bytes of the data has been written
  791. * successfully, or until an error occurs.
  792. *
  793. * @param buffers One or more data buffers to be written to the socket.
  794. *
  795. * @returns The number of bytes written.
  796. *
  797. * @throws boost::system::system_error Thrown on failure. An error code of
  798. * boost::asio::error::eof indicates that the connection was closed by the
  799. * peer.
  800. *
  801. * @note The write_some operation may not transmit all of the data to the
  802. * peer. Consider using the @ref write function if you need to ensure that
  803. * all data is written before the blocking operation completes.
  804. *
  805. * @par Example
  806. * To write a single data buffer use the @ref buffer function as follows:
  807. * @code
  808. * socket.write_some(boost::asio::buffer(data, size));
  809. * @endcode
  810. * See the @ref buffer documentation for information on writing multiple
  811. * buffers in one go, and how to use it with arrays, boost::array or
  812. * std::vector.
  813. */
  814. template <typename ConstBufferSequence>
  815. std::size_t write_some(const ConstBufferSequence& buffers)
  816. {
  817. boost::system::error_code ec;
  818. std::size_t s = this->impl_.get_service().send(
  819. this->impl_.get_implementation(), buffers, 0, ec);
  820. boost::asio::detail::throw_error(ec, "write_some");
  821. return s;
  822. }
  823. /// Write some data to the socket.
  824. /**
  825. * This function is used to write data to the stream socket. The function call
  826. * will block until one or more bytes of the data has been written
  827. * successfully, or until an error occurs.
  828. *
  829. * @param buffers One or more data buffers to be written to the socket.
  830. *
  831. * @param ec Set to indicate what error occurred, if any.
  832. *
  833. * @returns The number of bytes written. Returns 0 if an error occurred.
  834. *
  835. * @note The write_some operation may not transmit all of the data to the
  836. * peer. Consider using the @ref write function if you need to ensure that
  837. * all data is written before the blocking operation completes.
  838. */
  839. template <typename ConstBufferSequence>
  840. std::size_t write_some(const ConstBufferSequence& buffers,
  841. boost::system::error_code& ec)
  842. {
  843. return this->impl_.get_service().send(
  844. this->impl_.get_implementation(), buffers, 0, ec);
  845. }
  846. /// Start an asynchronous write.
  847. /**
  848. * This function is used to asynchronously write data to the stream socket.
  849. * It is an initiating function for an @ref asynchronous_operation, and always
  850. * returns immediately.
  851. *
  852. * @param buffers One or more data buffers to be written to the socket.
  853. * Although the buffers object may be copied as necessary, ownership of the
  854. * underlying memory blocks is retained by the caller, which must guarantee
  855. * that they remain valid until the completion handler is called.
  856. *
  857. * @param token The @ref completion_token that will be used to produce a
  858. * completion handler, which will be called when the write completes.
  859. * Potential completion tokens include @ref use_future, @ref use_awaitable,
  860. * @ref yield_context, or a function object with the correct completion
  861. * signature. The function signature of the completion handler must be:
  862. * @code void handler(
  863. * const boost::system::error_code& error, // Result of operation.
  864. * std::size_t bytes_transferred // Number of bytes written.
  865. * ); @endcode
  866. * Regardless of whether the asynchronous operation completes immediately or
  867. * not, the completion handler will not be invoked from within this function.
  868. * On immediate completion, invocation of the handler will be performed in a
  869. * manner equivalent to using boost::asio::async_immediate().
  870. *
  871. * @par Completion Signature
  872. * @code void(boost::system::error_code, std::size_t) @endcode
  873. *
  874. * @note The write operation may not transmit all of the data to the peer.
  875. * Consider using the @ref async_write function if you need to ensure that all
  876. * data is written before the asynchronous operation completes.
  877. *
  878. * @par Example
  879. * To write a single data buffer use the @ref buffer function as follows:
  880. * @code
  881. * socket.async_write_some(boost::asio::buffer(data, size), handler);
  882. * @endcode
  883. * See the @ref buffer documentation for information on writing multiple
  884. * buffers in one go, and how to use it with arrays, boost::array or
  885. * std::vector.
  886. *
  887. * @par Per-Operation Cancellation
  888. * On POSIX or Windows operating systems, this asynchronous operation supports
  889. * cancellation for the following boost::asio::cancellation_type values:
  890. *
  891. * @li @c cancellation_type::terminal
  892. *
  893. * @li @c cancellation_type::partial
  894. *
  895. * @li @c cancellation_type::total
  896. */
  897. template <typename ConstBufferSequence,
  898. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  899. std::size_t)) WriteToken = default_completion_token_t<executor_type>>
  900. auto async_write_some(const ConstBufferSequence& buffers,
  901. WriteToken&& token = default_completion_token_t<executor_type>())
  902. -> decltype(
  903. async_initiate<WriteToken,
  904. void (boost::system::error_code, std::size_t)>(
  905. declval<initiate_async_send>(), token,
  906. buffers, socket_base::message_flags(0)))
  907. {
  908. return async_initiate<WriteToken,
  909. void (boost::system::error_code, std::size_t)>(
  910. initiate_async_send(this), token,
  911. buffers, socket_base::message_flags(0));
  912. }
  913. /// Read some data from the socket.
  914. /**
  915. * This function is used to read data from the stream socket. The function
  916. * call will block until one or more bytes of data has been read successfully,
  917. * or until an error occurs.
  918. *
  919. * @param buffers One or more buffers into which the data will be read.
  920. *
  921. * @returns The number of bytes read.
  922. *
  923. * @throws boost::system::system_error Thrown on failure. An error code of
  924. * boost::asio::error::eof indicates that the connection was closed by the
  925. * peer.
  926. *
  927. * @note The read_some operation may not read all of the requested number of
  928. * bytes. Consider using the @ref read function if you need to ensure that
  929. * the requested amount of data is read before the blocking operation
  930. * completes.
  931. *
  932. * @par Example
  933. * To read into a single data buffer use the @ref buffer function as follows:
  934. * @code
  935. * socket.read_some(boost::asio::buffer(data, size));
  936. * @endcode
  937. * See the @ref buffer documentation for information on reading into multiple
  938. * buffers in one go, and how to use it with arrays, boost::array or
  939. * std::vector.
  940. */
  941. template <typename MutableBufferSequence>
  942. std::size_t read_some(const MutableBufferSequence& buffers)
  943. {
  944. boost::system::error_code ec;
  945. std::size_t s = this->impl_.get_service().receive(
  946. this->impl_.get_implementation(), buffers, 0, ec);
  947. boost::asio::detail::throw_error(ec, "read_some");
  948. return s;
  949. }
  950. /// Read some data from the socket.
  951. /**
  952. * This function is used to read data from the stream socket. The function
  953. * call will block until one or more bytes of data has been read successfully,
  954. * or until an error occurs.
  955. *
  956. * @param buffers One or more buffers into which the data will be read.
  957. *
  958. * @param ec Set to indicate what error occurred, if any.
  959. *
  960. * @returns The number of bytes read. Returns 0 if an error occurred.
  961. *
  962. * @note The read_some operation may not read all of the requested number of
  963. * bytes. Consider using the @ref read function if you need to ensure that
  964. * the requested amount of data is read before the blocking operation
  965. * completes.
  966. */
  967. template <typename MutableBufferSequence>
  968. std::size_t read_some(const MutableBufferSequence& buffers,
  969. boost::system::error_code& ec)
  970. {
  971. return this->impl_.get_service().receive(
  972. this->impl_.get_implementation(), buffers, 0, ec);
  973. }
  974. /// Start an asynchronous read.
  975. /**
  976. * This function is used to asynchronously read data from the stream socket.
  977. * socket. It is an initiating function for an @ref asynchronous_operation,
  978. * and always returns immediately.
  979. *
  980. * @param buffers One or more buffers into which the data will be read.
  981. * Although the buffers object may be copied as necessary, ownership of the
  982. * underlying memory blocks is retained by the caller, which must guarantee
  983. * that they remain valid until the completion handler is called.
  984. *
  985. * @param token The @ref completion_token that will be used to produce a
  986. * completion handler, which will be called when the read completes.
  987. * Potential completion tokens include @ref use_future, @ref use_awaitable,
  988. * @ref yield_context, or a function object with the correct completion
  989. * signature. The function signature of the completion handler must be:
  990. * @code void handler(
  991. * const boost::system::error_code& error, // Result of operation.
  992. * std::size_t bytes_transferred // Number of bytes read.
  993. * ); @endcode
  994. * Regardless of whether the asynchronous operation completes immediately or
  995. * not, the completion handler will not be invoked from within this function.
  996. * On immediate completion, invocation of the handler will be performed in a
  997. * manner equivalent to using boost::asio::async_immediate().
  998. *
  999. * @par Completion Signature
  1000. * @code void(boost::system::error_code, std::size_t) @endcode
  1001. *
  1002. * @note The read operation may not read all of the requested number of bytes.
  1003. * Consider using the @ref async_read function if you need to ensure that the
  1004. * requested amount of data is read before the asynchronous operation
  1005. * completes.
  1006. *
  1007. * @par Example
  1008. * To read into a single data buffer use the @ref buffer function as follows:
  1009. * @code
  1010. * socket.async_read_some(boost::asio::buffer(data, size), handler);
  1011. * @endcode
  1012. * See the @ref buffer documentation for information on reading into multiple
  1013. * buffers in one go, and how to use it with arrays, boost::array or
  1014. * std::vector.
  1015. *
  1016. * @par Per-Operation Cancellation
  1017. * On POSIX or Windows operating systems, this asynchronous operation supports
  1018. * cancellation for the following boost::asio::cancellation_type values:
  1019. *
  1020. * @li @c cancellation_type::terminal
  1021. *
  1022. * @li @c cancellation_type::partial
  1023. *
  1024. * @li @c cancellation_type::total
  1025. */
  1026. template <typename MutableBufferSequence,
  1027. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  1028. std::size_t)) ReadToken = default_completion_token_t<executor_type>>
  1029. auto async_read_some(const MutableBufferSequence& buffers,
  1030. ReadToken&& token = default_completion_token_t<executor_type>())
  1031. -> decltype(
  1032. async_initiate<ReadToken,
  1033. void (boost::system::error_code, std::size_t)>(
  1034. declval<initiate_async_receive>(), token,
  1035. buffers, socket_base::message_flags(0)))
  1036. {
  1037. return async_initiate<ReadToken,
  1038. void (boost::system::error_code, std::size_t)>(
  1039. initiate_async_receive(this), token,
  1040. buffers, socket_base::message_flags(0));
  1041. }
  1042. private:
  1043. // Disallow copying and assignment.
  1044. basic_stream_socket(const basic_stream_socket&) = delete;
  1045. basic_stream_socket& operator=(const basic_stream_socket&) = delete;
  1046. class initiate_async_send
  1047. {
  1048. public:
  1049. typedef Executor executor_type;
  1050. explicit initiate_async_send(basic_stream_socket* self)
  1051. : self_(self)
  1052. {
  1053. }
  1054. const executor_type& get_executor() const noexcept
  1055. {
  1056. return self_->get_executor();
  1057. }
  1058. template <typename WriteHandler, typename ConstBufferSequence>
  1059. void operator()(WriteHandler&& handler,
  1060. const ConstBufferSequence& buffers,
  1061. socket_base::message_flags flags) const
  1062. {
  1063. // If you get an error on the following line it means that your handler
  1064. // does not meet the documented type requirements for a WriteHandler.
  1065. BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
  1066. detail::non_const_lvalue<WriteHandler> handler2(handler);
  1067. self_->impl_.get_service().async_send(
  1068. self_->impl_.get_implementation(), buffers, flags,
  1069. handler2.value, self_->impl_.get_executor());
  1070. }
  1071. private:
  1072. basic_stream_socket* self_;
  1073. };
  1074. class initiate_async_receive
  1075. {
  1076. public:
  1077. typedef Executor executor_type;
  1078. explicit initiate_async_receive(basic_stream_socket* self)
  1079. : self_(self)
  1080. {
  1081. }
  1082. const executor_type& get_executor() const noexcept
  1083. {
  1084. return self_->get_executor();
  1085. }
  1086. template <typename ReadHandler, typename MutableBufferSequence>
  1087. void operator()(ReadHandler&& handler,
  1088. const MutableBufferSequence& buffers,
  1089. socket_base::message_flags flags) const
  1090. {
  1091. // If you get an error on the following line it means that your handler
  1092. // does not meet the documented type requirements for a ReadHandler.
  1093. BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
  1094. detail::non_const_lvalue<ReadHandler> handler2(handler);
  1095. self_->impl_.get_service().async_receive(
  1096. self_->impl_.get_implementation(), buffers, flags,
  1097. handler2.value, self_->impl_.get_executor());
  1098. }
  1099. private:
  1100. basic_stream_socket* self_;
  1101. };
  1102. };
  1103. } // namespace asio
  1104. } // namespace boost
  1105. #include <boost/asio/detail/pop_options.hpp>
  1106. #endif // BOOST_ASIO_BASIC_STREAM_SOCKET_HPP