basic_stream_socket.hpp 41 KB

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