basic_stream_socket.hpp 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923
  1. //
  2. // basic_stream_socket.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2018 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/throw_error.hpp>
  21. #include <boost/asio/error.hpp>
  22. #if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
  23. # include <boost/asio/stream_socket_service.hpp>
  24. #endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
  25. #include <boost/asio/detail/push_options.hpp>
  26. namespace boost {
  27. namespace asio {
  28. /// Provides stream-oriented socket functionality.
  29. /**
  30. * The basic_stream_socket class template provides asynchronous and blocking
  31. * stream-oriented socket functionality.
  32. *
  33. * @par Thread Safety
  34. * @e Distinct @e objects: Safe.@n
  35. * @e Shared @e objects: Unsafe.
  36. *
  37. * @par Concepts:
  38. * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
  39. */
  40. template <typename Protocol
  41. BOOST_ASIO_SVC_TPARAM_DEF1(= stream_socket_service<Protocol>)>
  42. class basic_stream_socket
  43. : public basic_socket<Protocol BOOST_ASIO_SVC_TARG>
  44. {
  45. public:
  46. /// The native representation of a socket.
  47. #if defined(GENERATING_DOCUMENTATION)
  48. typedef implementation_defined native_handle_type;
  49. #else
  50. typedef typename basic_socket<
  51. Protocol BOOST_ASIO_SVC_TARG>::native_handle_type native_handle_type;
  52. #endif
  53. /// The protocol type.
  54. typedef Protocol protocol_type;
  55. /// The endpoint type.
  56. typedef typename Protocol::endpoint endpoint_type;
  57. /// Construct a basic_stream_socket without opening it.
  58. /**
  59. * This constructor creates a stream socket without opening it. The socket
  60. * needs to be opened and then connected or accepted before data can be sent
  61. * or received on it.
  62. *
  63. * @param io_context The io_context object that the stream socket will use to
  64. * dispatch handlers for any asynchronous operations performed on the socket.
  65. */
  66. explicit basic_stream_socket(boost::asio::io_context& io_context)
  67. : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context)
  68. {
  69. }
  70. /// Construct and open a basic_stream_socket.
  71. /**
  72. * This constructor creates and opens a stream socket. The socket needs to be
  73. * connected or accepted before data can be sent or received on it.
  74. *
  75. * @param io_context The io_context object that the stream socket will use to
  76. * dispatch handlers for any asynchronous operations performed on the socket.
  77. *
  78. * @param protocol An object specifying protocol parameters to be used.
  79. *
  80. * @throws boost::system::system_error Thrown on failure.
  81. */
  82. basic_stream_socket(boost::asio::io_context& io_context,
  83. const protocol_type& protocol)
  84. : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, protocol)
  85. {
  86. }
  87. /// Construct a basic_stream_socket, opening it and binding it to the given
  88. /// local endpoint.
  89. /**
  90. * This constructor creates a stream socket and automatically opens it bound
  91. * to the specified endpoint on the local machine. The protocol used is the
  92. * protocol associated with the given endpoint.
  93. *
  94. * @param io_context The io_context object that the stream socket will use to
  95. * dispatch handlers for any asynchronous operations performed on the socket.
  96. *
  97. * @param endpoint An endpoint on the local machine to which the stream
  98. * socket will be bound.
  99. *
  100. * @throws boost::system::system_error Thrown on failure.
  101. */
  102. basic_stream_socket(boost::asio::io_context& io_context,
  103. const endpoint_type& endpoint)
  104. : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, endpoint)
  105. {
  106. }
  107. /// Construct a basic_stream_socket on an existing native socket.
  108. /**
  109. * This constructor creates a stream socket object to hold an existing native
  110. * socket.
  111. *
  112. * @param io_context The io_context object that the stream socket will use to
  113. * dispatch handlers for any asynchronous operations performed on the socket.
  114. *
  115. * @param protocol An object specifying protocol parameters to be used.
  116. *
  117. * @param native_socket The new underlying socket implementation.
  118. *
  119. * @throws boost::system::system_error Thrown on failure.
  120. */
  121. basic_stream_socket(boost::asio::io_context& io_context,
  122. const protocol_type& protocol, const native_handle_type& native_socket)
  123. : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(
  124. io_context, protocol, native_socket)
  125. {
  126. }
  127. #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  128. /// Move-construct a basic_stream_socket from another.
  129. /**
  130. * This constructor moves a stream socket from one object to another.
  131. *
  132. * @param other The other basic_stream_socket object from which the move
  133. * will occur.
  134. *
  135. * @note Following the move, the moved-from object is in the same state as if
  136. * constructed using the @c basic_stream_socket(io_context&) constructor.
  137. */
  138. basic_stream_socket(basic_stream_socket&& other)
  139. : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
  140. {
  141. }
  142. /// Move-assign a basic_stream_socket from another.
  143. /**
  144. * This assignment operator moves a stream socket from one object to another.
  145. *
  146. * @param other The other basic_stream_socket object from which the move
  147. * will occur.
  148. *
  149. * @note Following the move, the moved-from object is in the same state as if
  150. * constructed using the @c basic_stream_socket(io_context&) constructor.
  151. */
  152. basic_stream_socket& operator=(basic_stream_socket&& other)
  153. {
  154. basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other));
  155. return *this;
  156. }
  157. /// Move-construct a basic_stream_socket from a socket of another protocol
  158. /// type.
  159. /**
  160. * This constructor moves a stream socket from one object to another.
  161. *
  162. * @param other The other basic_stream_socket object from which the move
  163. * will occur.
  164. *
  165. * @note Following the move, the moved-from object is in the same state as if
  166. * constructed using the @c basic_stream_socket(io_context&) constructor.
  167. */
  168. template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
  169. basic_stream_socket(
  170. basic_stream_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
  171. typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
  172. : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
  173. {
  174. }
  175. /// Move-assign a basic_stream_socket from a socket of another protocol type.
  176. /**
  177. * This assignment operator moves a stream socket from one object to another.
  178. *
  179. * @param other The other basic_stream_socket object from which the move
  180. * will occur.
  181. *
  182. * @note Following the move, the moved-from object is in the same state as if
  183. * constructed using the @c basic_stream_socket(io_context&) constructor.
  184. */
  185. template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
  186. typename enable_if<is_convertible<Protocol1, Protocol>::value,
  187. basic_stream_socket>::type& operator=(
  188. basic_stream_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
  189. {
  190. basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other));
  191. return *this;
  192. }
  193. #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  194. /// Destroys the socket.
  195. /**
  196. * This function destroys the socket, cancelling any outstanding asynchronous
  197. * operations associated with the socket as if by calling @c cancel.
  198. */
  199. ~basic_stream_socket()
  200. {
  201. }
  202. /// Send some data on the socket.
  203. /**
  204. * This function is used to send data on the stream socket. The function
  205. * call will block until one or more bytes of the data has been sent
  206. * successfully, or an until error occurs.
  207. *
  208. * @param buffers One or more data buffers to be sent on the socket.
  209. *
  210. * @returns The number of bytes sent.
  211. *
  212. * @throws boost::system::system_error Thrown on failure.
  213. *
  214. * @note The send operation may not transmit all of the data to the peer.
  215. * Consider using the @ref write function if you need to ensure that all data
  216. * is written before the blocking operation completes.
  217. *
  218. * @par Example
  219. * To send a single data buffer use the @ref buffer function as follows:
  220. * @code
  221. * socket.send(boost::asio::buffer(data, size));
  222. * @endcode
  223. * See the @ref buffer documentation for information on sending multiple
  224. * buffers in one go, and how to use it with arrays, boost::array or
  225. * std::vector.
  226. */
  227. template <typename ConstBufferSequence>
  228. std::size_t send(const ConstBufferSequence& buffers)
  229. {
  230. boost::system::error_code ec;
  231. std::size_t s = this->get_service().send(
  232. this->get_implementation(), buffers, 0, ec);
  233. boost::asio::detail::throw_error(ec, "send");
  234. return s;
  235. }
  236. /// Send some data on the socket.
  237. /**
  238. * This function is used to send data on the stream socket. The function
  239. * call will block until one or more bytes of the data has been sent
  240. * successfully, or an until error occurs.
  241. *
  242. * @param buffers One or more data buffers to be sent on the socket.
  243. *
  244. * @param flags Flags specifying how the send call is to be made.
  245. *
  246. * @returns The number of bytes sent.
  247. *
  248. * @throws boost::system::system_error Thrown on failure.
  249. *
  250. * @note The send operation may not transmit all of the data to the peer.
  251. * Consider using the @ref write function if you need to ensure that all data
  252. * is written before the blocking operation completes.
  253. *
  254. * @par Example
  255. * To send a single data buffer use the @ref buffer function as follows:
  256. * @code
  257. * socket.send(boost::asio::buffer(data, size), 0);
  258. * @endcode
  259. * See the @ref buffer documentation for information on sending multiple
  260. * buffers in one go, and how to use it with arrays, boost::array or
  261. * std::vector.
  262. */
  263. template <typename ConstBufferSequence>
  264. std::size_t send(const ConstBufferSequence& buffers,
  265. socket_base::message_flags flags)
  266. {
  267. boost::system::error_code ec;
  268. std::size_t s = this->get_service().send(
  269. this->get_implementation(), buffers, flags, ec);
  270. boost::asio::detail::throw_error(ec, "send");
  271. return s;
  272. }
  273. /// Send some data on the socket.
  274. /**
  275. * This function is used to send data on the stream socket. The function
  276. * call will block until one or more bytes of the data has been sent
  277. * successfully, or an until error occurs.
  278. *
  279. * @param buffers One or more data buffers to be sent on the socket.
  280. *
  281. * @param flags Flags specifying how the send call is to be made.
  282. *
  283. * @param ec Set to indicate what error occurred, if any.
  284. *
  285. * @returns The number of bytes sent. Returns 0 if an error occurred.
  286. *
  287. * @note The send operation may not transmit all of the data to the peer.
  288. * Consider using the @ref write function if you need to ensure that all data
  289. * is written before the blocking operation completes.
  290. */
  291. template <typename ConstBufferSequence>
  292. std::size_t send(const ConstBufferSequence& buffers,
  293. socket_base::message_flags flags, boost::system::error_code& ec)
  294. {
  295. return this->get_service().send(
  296. this->get_implementation(), buffers, flags, ec);
  297. }
  298. /// Start an asynchronous send.
  299. /**
  300. * This function is used to asynchronously send data on the stream socket.
  301. * The function call always returns immediately.
  302. *
  303. * @param buffers One or more data buffers to be sent on the socket. Although
  304. * the buffers object may be copied as necessary, ownership of the underlying
  305. * memory blocks is retained by the caller, which must guarantee that they
  306. * remain valid until the handler is called.
  307. *
  308. * @param handler The handler to be called when the send operation completes.
  309. * Copies will be made of the handler as required. The function signature of
  310. * the handler must be:
  311. * @code void handler(
  312. * const boost::system::error_code& error, // Result of operation.
  313. * std::size_t bytes_transferred // Number of bytes sent.
  314. * ); @endcode
  315. * Regardless of whether the asynchronous operation completes immediately or
  316. * not, the handler will not be invoked from within this function. Invocation
  317. * of the handler will be performed in a manner equivalent to using
  318. * boost::asio::io_context::post().
  319. *
  320. * @note The send operation may not transmit all of the data to the peer.
  321. * Consider using the @ref async_write function if you need to ensure that all
  322. * data is written before the asynchronous operation completes.
  323. *
  324. * @par Example
  325. * To send a single data buffer use the @ref buffer function as follows:
  326. * @code
  327. * socket.async_send(boost::asio::buffer(data, size), handler);
  328. * @endcode
  329. * See the @ref buffer documentation for information on sending multiple
  330. * buffers in one go, and how to use it with arrays, boost::array or
  331. * std::vector.
  332. */
  333. template <typename ConstBufferSequence, typename WriteHandler>
  334. BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
  335. void (boost::system::error_code, std::size_t))
  336. async_send(const ConstBufferSequence& buffers,
  337. BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
  338. {
  339. // If you get an error on the following line it means that your handler does
  340. // not meet the documented type requirements for a WriteHandler.
  341. BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
  342. #if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
  343. return this->get_service().async_send(
  344. this->get_implementation(), buffers, 0,
  345. BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
  346. #else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
  347. async_completion<WriteHandler,
  348. void (boost::system::error_code, std::size_t)> init(handler);
  349. this->get_service().async_send(
  350. this->get_implementation(), buffers, 0,
  351. init.completion_handler);
  352. return init.result.get();
  353. #endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
  354. }
  355. /// Start an asynchronous send.
  356. /**
  357. * This function is used to asynchronously send data on the stream socket.
  358. * The function call always returns immediately.
  359. *
  360. * @param buffers One or more data buffers to be sent on the socket. Although
  361. * the buffers object may be copied as necessary, ownership of the underlying
  362. * memory blocks is retained by the caller, which must guarantee that they
  363. * remain valid until the handler is called.
  364. *
  365. * @param flags Flags specifying how the send call is to be made.
  366. *
  367. * @param handler The handler to be called when the send operation completes.
  368. * Copies will be made of the handler as required. The function signature of
  369. * the handler must be:
  370. * @code void handler(
  371. * const boost::system::error_code& error, // Result of operation.
  372. * std::size_t bytes_transferred // Number of bytes sent.
  373. * ); @endcode
  374. * Regardless of whether the asynchronous operation completes immediately or
  375. * not, the handler will not be invoked from within this function. Invocation
  376. * of the handler will be performed in a manner equivalent to using
  377. * boost::asio::io_context::post().
  378. *
  379. * @note The send operation may not transmit all of the data to the peer.
  380. * Consider using the @ref async_write function if you need to ensure that all
  381. * data is written before the asynchronous operation completes.
  382. *
  383. * @par Example
  384. * To send a single data buffer use the @ref buffer function as follows:
  385. * @code
  386. * socket.async_send(boost::asio::buffer(data, size), 0, handler);
  387. * @endcode
  388. * See the @ref buffer documentation for information on sending multiple
  389. * buffers in one go, and how to use it with arrays, boost::array or
  390. * std::vector.
  391. */
  392. template <typename ConstBufferSequence, typename WriteHandler>
  393. BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
  394. void (boost::system::error_code, std::size_t))
  395. async_send(const ConstBufferSequence& buffers,
  396. socket_base::message_flags flags,
  397. BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
  398. {
  399. // If you get an error on the following line it means that your handler does
  400. // not meet the documented type requirements for a WriteHandler.
  401. BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
  402. #if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
  403. return this->get_service().async_send(
  404. this->get_implementation(), buffers, flags,
  405. BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
  406. #else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
  407. async_completion<WriteHandler,
  408. void (boost::system::error_code, std::size_t)> init(handler);
  409. this->get_service().async_send(
  410. this->get_implementation(), buffers, flags,
  411. init.completion_handler);
  412. return init.result.get();
  413. #endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
  414. }
  415. /// Receive some data on the socket.
  416. /**
  417. * This function is used to receive data on the stream socket. The function
  418. * call will block until one or more bytes of data has been received
  419. * successfully, or until an error occurs.
  420. *
  421. * @param buffers One or more buffers into which the data will be received.
  422. *
  423. * @returns The number of bytes received.
  424. *
  425. * @throws boost::system::system_error Thrown on failure. An error code of
  426. * boost::asio::error::eof indicates that the connection was closed by the
  427. * peer.
  428. *
  429. * @note The receive operation may not receive all of the requested number of
  430. * bytes. Consider using the @ref read function if you need to ensure that the
  431. * requested amount of data is read before the blocking operation completes.
  432. *
  433. * @par Example
  434. * To receive into a single data buffer use the @ref buffer function as
  435. * follows:
  436. * @code
  437. * socket.receive(boost::asio::buffer(data, size));
  438. * @endcode
  439. * See the @ref buffer documentation for information on receiving into
  440. * multiple buffers in one go, and how to use it with arrays, boost::array or
  441. * std::vector.
  442. */
  443. template <typename MutableBufferSequence>
  444. std::size_t receive(const MutableBufferSequence& buffers)
  445. {
  446. boost::system::error_code ec;
  447. std::size_t s = this->get_service().receive(
  448. this->get_implementation(), buffers, 0, ec);
  449. boost::asio::detail::throw_error(ec, "receive");
  450. return s;
  451. }
  452. /// Receive some data on the socket.
  453. /**
  454. * This function is used to receive data on the stream socket. The function
  455. * call will block until one or more bytes of data has been received
  456. * successfully, or until an error occurs.
  457. *
  458. * @param buffers One or more buffers into which the data will be received.
  459. *
  460. * @param flags Flags specifying how the receive call is to be made.
  461. *
  462. * @returns The number of bytes received.
  463. *
  464. * @throws boost::system::system_error Thrown on failure. An error code of
  465. * boost::asio::error::eof indicates that the connection was closed by the
  466. * peer.
  467. *
  468. * @note The receive operation may not receive all of the requested number of
  469. * bytes. Consider using the @ref read function if you need to ensure that the
  470. * requested amount of data is read before the blocking operation completes.
  471. *
  472. * @par Example
  473. * To receive into a single data buffer use the @ref buffer function as
  474. * follows:
  475. * @code
  476. * socket.receive(boost::asio::buffer(data, size), 0);
  477. * @endcode
  478. * See the @ref buffer documentation for information on receiving into
  479. * multiple buffers in one go, and how to use it with arrays, boost::array or
  480. * std::vector.
  481. */
  482. template <typename MutableBufferSequence>
  483. std::size_t receive(const MutableBufferSequence& buffers,
  484. socket_base::message_flags flags)
  485. {
  486. boost::system::error_code ec;
  487. std::size_t s = this->get_service().receive(
  488. this->get_implementation(), buffers, flags, ec);
  489. boost::asio::detail::throw_error(ec, "receive");
  490. return s;
  491. }
  492. /// Receive some data on a connected socket.
  493. /**
  494. * This function is used to receive data on the stream socket. The function
  495. * call will block until one or more bytes of data has been received
  496. * successfully, or until an error occurs.
  497. *
  498. * @param buffers One or more buffers into which the data will be received.
  499. *
  500. * @param flags Flags specifying how the receive call is to be made.
  501. *
  502. * @param ec Set to indicate what error occurred, if any.
  503. *
  504. * @returns The number of bytes received. Returns 0 if an error occurred.
  505. *
  506. * @note The receive operation may not receive all of the requested number of
  507. * bytes. Consider using the @ref read function if you need to ensure that the
  508. * requested amount of data is read before the blocking operation completes.
  509. */
  510. template <typename MutableBufferSequence>
  511. std::size_t receive(const MutableBufferSequence& buffers,
  512. socket_base::message_flags flags, boost::system::error_code& ec)
  513. {
  514. return this->get_service().receive(
  515. this->get_implementation(), buffers, flags, ec);
  516. }
  517. /// Start an asynchronous receive.
  518. /**
  519. * This function is used to asynchronously receive data from the stream
  520. * socket. The function call always returns immediately.
  521. *
  522. * @param buffers One or more buffers into which the data will be received.
  523. * Although the buffers object may be copied as necessary, ownership of the
  524. * underlying memory blocks is retained by the caller, which must guarantee
  525. * that they remain valid until the handler is called.
  526. *
  527. * @param handler The handler to be called when the receive operation
  528. * completes. Copies will be made of the handler as required. The function
  529. * signature of the handler must be:
  530. * @code void handler(
  531. * const boost::system::error_code& error, // Result of operation.
  532. * std::size_t bytes_transferred // Number of bytes received.
  533. * ); @endcode
  534. * Regardless of whether the asynchronous operation completes immediately or
  535. * not, the handler will not be invoked from within this function. Invocation
  536. * of the handler will be performed in a manner equivalent to using
  537. * boost::asio::io_context::post().
  538. *
  539. * @note The receive operation may not receive all of the requested number of
  540. * bytes. Consider using the @ref async_read function if you need to ensure
  541. * that the requested amount of data is received before the asynchronous
  542. * operation completes.
  543. *
  544. * @par Example
  545. * To receive into a single data buffer use the @ref buffer function as
  546. * follows:
  547. * @code
  548. * socket.async_receive(boost::asio::buffer(data, size), handler);
  549. * @endcode
  550. * See the @ref buffer documentation for information on receiving into
  551. * multiple buffers in one go, and how to use it with arrays, boost::array or
  552. * std::vector.
  553. */
  554. template <typename MutableBufferSequence, typename ReadHandler>
  555. BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
  556. void (boost::system::error_code, std::size_t))
  557. async_receive(const MutableBufferSequence& buffers,
  558. BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
  559. {
  560. // If you get an error on the following line it means that your handler does
  561. // not meet the documented type requirements for a ReadHandler.
  562. BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
  563. #if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
  564. return this->get_service().async_receive(this->get_implementation(),
  565. buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
  566. #else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
  567. async_completion<ReadHandler,
  568. void (boost::system::error_code, std::size_t)> init(handler);
  569. this->get_service().async_receive(this->get_implementation(),
  570. buffers, 0, init.completion_handler);
  571. return init.result.get();
  572. #endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
  573. }
  574. /// Start an asynchronous receive.
  575. /**
  576. * This function is used to asynchronously receive data from the stream
  577. * socket. The function call always returns immediately.
  578. *
  579. * @param buffers One or more buffers into which the data will be received.
  580. * Although the buffers object may be copied as necessary, ownership of the
  581. * underlying memory blocks is retained by the caller, which must guarantee
  582. * that they remain valid until the handler is called.
  583. *
  584. * @param flags Flags specifying how the receive call is to be made.
  585. *
  586. * @param handler The handler to be called when the receive operation
  587. * completes. Copies will be made of the handler as required. The function
  588. * signature of the handler must be:
  589. * @code void handler(
  590. * const boost::system::error_code& error, // Result of operation.
  591. * std::size_t bytes_transferred // Number of bytes received.
  592. * ); @endcode
  593. * Regardless of whether the asynchronous operation completes immediately or
  594. * not, the handler will not be invoked from within this function. Invocation
  595. * of the handler will be performed in a manner equivalent to using
  596. * boost::asio::io_context::post().
  597. *
  598. * @note The receive operation may not receive all of the requested number of
  599. * bytes. Consider using the @ref async_read function if you need to ensure
  600. * that the requested amount of data is received before the asynchronous
  601. * 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.async_receive(boost::asio::buffer(data, size), 0, handler);
  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, typename ReadHandler>
  614. BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
  615. void (boost::system::error_code, std::size_t))
  616. async_receive(const MutableBufferSequence& buffers,
  617. socket_base::message_flags flags,
  618. BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
  619. {
  620. // If you get an error on the following line it means that your handler does
  621. // not meet the documented type requirements for a ReadHandler.
  622. BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
  623. #if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
  624. return this->get_service().async_receive(this->get_implementation(),
  625. buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
  626. #else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
  627. async_completion<ReadHandler,
  628. void (boost::system::error_code, std::size_t)> init(handler);
  629. this->get_service().async_receive(this->get_implementation(),
  630. buffers, flags, init.completion_handler);
  631. return init.result.get();
  632. #endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
  633. }
  634. /// Write some data to the socket.
  635. /**
  636. * This function is used to write data to the stream socket. The function call
  637. * will block until one or more bytes of the data has been written
  638. * successfully, or until an error occurs.
  639. *
  640. * @param buffers One or more data buffers to be written to the socket.
  641. *
  642. * @returns The number of bytes written.
  643. *
  644. * @throws boost::system::system_error Thrown on failure. An error code of
  645. * boost::asio::error::eof indicates that the connection was closed by the
  646. * peer.
  647. *
  648. * @note The write_some operation may not transmit all of the data to the
  649. * peer. Consider using the @ref write function if you need to ensure that
  650. * all data is written before the blocking operation completes.
  651. *
  652. * @par Example
  653. * To write a single data buffer use the @ref buffer function as follows:
  654. * @code
  655. * socket.write_some(boost::asio::buffer(data, size));
  656. * @endcode
  657. * See the @ref buffer documentation for information on writing multiple
  658. * buffers in one go, and how to use it with arrays, boost::array or
  659. * std::vector.
  660. */
  661. template <typename ConstBufferSequence>
  662. std::size_t write_some(const ConstBufferSequence& buffers)
  663. {
  664. boost::system::error_code ec;
  665. std::size_t s = this->get_service().send(
  666. this->get_implementation(), buffers, 0, ec);
  667. boost::asio::detail::throw_error(ec, "write_some");
  668. return s;
  669. }
  670. /// Write some data to the socket.
  671. /**
  672. * This function is used to write data to the stream socket. The function call
  673. * will block until one or more bytes of the data has been written
  674. * successfully, or until an error occurs.
  675. *
  676. * @param buffers One or more data buffers to be written to the socket.
  677. *
  678. * @param ec Set to indicate what error occurred, if any.
  679. *
  680. * @returns The number of bytes written. Returns 0 if an error occurred.
  681. *
  682. * @note The write_some operation may not transmit all of the data to the
  683. * peer. Consider using the @ref write function if you need to ensure that
  684. * all data is written before the blocking operation completes.
  685. */
  686. template <typename ConstBufferSequence>
  687. std::size_t write_some(const ConstBufferSequence& buffers,
  688. boost::system::error_code& ec)
  689. {
  690. return this->get_service().send(this->get_implementation(), buffers, 0, ec);
  691. }
  692. /// Start an asynchronous write.
  693. /**
  694. * This function is used to asynchronously write data to the stream socket.
  695. * The function call always returns immediately.
  696. *
  697. * @param buffers One or more data buffers to be written to the socket.
  698. * Although the buffers object may be copied as necessary, ownership of the
  699. * underlying memory blocks is retained by the caller, which must guarantee
  700. * that they remain valid until the handler is called.
  701. *
  702. * @param handler The handler to be called when the write operation completes.
  703. * Copies will be made of the handler as required. The function signature of
  704. * the handler must be:
  705. * @code void handler(
  706. * const boost::system::error_code& error, // Result of operation.
  707. * std::size_t bytes_transferred // Number of bytes written.
  708. * ); @endcode
  709. * Regardless of whether the asynchronous operation completes immediately or
  710. * not, the handler will not be invoked from within this function. Invocation
  711. * of the handler will be performed in a manner equivalent to using
  712. * boost::asio::io_context::post().
  713. *
  714. * @note The write operation may not transmit all of the data to the peer.
  715. * Consider using the @ref async_write function if you need to ensure that all
  716. * data is written before the asynchronous operation completes.
  717. *
  718. * @par Example
  719. * To write a single data buffer use the @ref buffer function as follows:
  720. * @code
  721. * socket.async_write_some(boost::asio::buffer(data, size), handler);
  722. * @endcode
  723. * See the @ref buffer documentation for information on writing multiple
  724. * buffers in one go, and how to use it with arrays, boost::array or
  725. * std::vector.
  726. */
  727. template <typename ConstBufferSequence, typename WriteHandler>
  728. BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
  729. void (boost::system::error_code, std::size_t))
  730. async_write_some(const ConstBufferSequence& buffers,
  731. BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
  732. {
  733. // If you get an error on the following line it means that your handler does
  734. // not meet the documented type requirements for a WriteHandler.
  735. BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
  736. #if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
  737. return this->get_service().async_send(this->get_implementation(),
  738. buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
  739. #else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
  740. async_completion<WriteHandler,
  741. void (boost::system::error_code, std::size_t)> init(handler);
  742. this->get_service().async_send(this->get_implementation(),
  743. buffers, 0, init.completion_handler);
  744. return init.result.get();
  745. #endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
  746. }
  747. /// Read some data from the socket.
  748. /**
  749. * This function is used to read data from the stream socket. The function
  750. * call will block until one or more bytes of data has been read successfully,
  751. * or until an error occurs.
  752. *
  753. * @param buffers One or more buffers into which the data will be read.
  754. *
  755. * @returns The number of bytes read.
  756. *
  757. * @throws boost::system::system_error Thrown on failure. An error code of
  758. * boost::asio::error::eof indicates that the connection was closed by the
  759. * peer.
  760. *
  761. * @note The read_some operation may not read all of the requested number of
  762. * bytes. Consider using the @ref read function if you need to ensure that
  763. * the requested amount of data is read before the blocking operation
  764. * completes.
  765. *
  766. * @par Example
  767. * To read into a single data buffer use the @ref buffer function as follows:
  768. * @code
  769. * socket.read_some(boost::asio::buffer(data, size));
  770. * @endcode
  771. * See the @ref buffer documentation for information on reading into multiple
  772. * buffers in one go, and how to use it with arrays, boost::array or
  773. * std::vector.
  774. */
  775. template <typename MutableBufferSequence>
  776. std::size_t read_some(const MutableBufferSequence& buffers)
  777. {
  778. boost::system::error_code ec;
  779. std::size_t s = this->get_service().receive(
  780. this->get_implementation(), buffers, 0, ec);
  781. boost::asio::detail::throw_error(ec, "read_some");
  782. return s;
  783. }
  784. /// Read some data from the socket.
  785. /**
  786. * This function is used to read data from the stream socket. The function
  787. * call will block until one or more bytes of data has been read successfully,
  788. * or until an error occurs.
  789. *
  790. * @param buffers One or more buffers into which the data will be read.
  791. *
  792. * @param ec Set to indicate what error occurred, if any.
  793. *
  794. * @returns The number of bytes read. Returns 0 if an error occurred.
  795. *
  796. * @note The read_some operation may not read all of the requested number of
  797. * bytes. Consider using the @ref read function if you need to ensure that
  798. * the requested amount of data is read before the blocking operation
  799. * completes.
  800. */
  801. template <typename MutableBufferSequence>
  802. std::size_t read_some(const MutableBufferSequence& buffers,
  803. boost::system::error_code& ec)
  804. {
  805. return this->get_service().receive(
  806. this->get_implementation(), buffers, 0, ec);
  807. }
  808. /// Start an asynchronous read.
  809. /**
  810. * This function is used to asynchronously read data from the stream socket.
  811. * The function call always returns immediately.
  812. *
  813. * @param buffers One or more buffers into which the data will be read.
  814. * Although the buffers object may be copied as necessary, ownership of the
  815. * underlying memory blocks is retained by the caller, which must guarantee
  816. * that they remain valid until the handler is called.
  817. *
  818. * @param handler The handler to be called when the read operation completes.
  819. * Copies will be made of the handler as required. The function signature of
  820. * the handler must be:
  821. * @code void handler(
  822. * const boost::system::error_code& error, // Result of operation.
  823. * std::size_t bytes_transferred // Number of bytes read.
  824. * ); @endcode
  825. * Regardless of whether the asynchronous operation completes immediately or
  826. * not, the handler will not be invoked from within this function. Invocation
  827. * of the handler will be performed in a manner equivalent to using
  828. * boost::asio::io_context::post().
  829. *
  830. * @note The read operation may not read all of the requested number of bytes.
  831. * Consider using the @ref async_read function if you need to ensure that the
  832. * requested amount of data is read before the asynchronous operation
  833. * completes.
  834. *
  835. * @par Example
  836. * To read into a single data buffer use the @ref buffer function as follows:
  837. * @code
  838. * socket.async_read_some(boost::asio::buffer(data, size), handler);
  839. * @endcode
  840. * See the @ref buffer documentation for information on reading into multiple
  841. * buffers in one go, and how to use it with arrays, boost::array or
  842. * std::vector.
  843. */
  844. template <typename MutableBufferSequence, typename ReadHandler>
  845. BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
  846. void (boost::system::error_code, std::size_t))
  847. async_read_some(const MutableBufferSequence& buffers,
  848. BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
  849. {
  850. // If you get an error on the following line it means that your handler does
  851. // not meet the documented type requirements for a ReadHandler.
  852. BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
  853. #if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
  854. return this->get_service().async_receive(this->get_implementation(),
  855. buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
  856. #else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
  857. async_completion<ReadHandler,
  858. void (boost::system::error_code, std::size_t)> init(handler);
  859. this->get_service().async_receive(this->get_implementation(),
  860. buffers, 0, init.completion_handler);
  861. return init.result.get();
  862. #endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
  863. }
  864. };
  865. } // namespace asio
  866. } // namespace boost
  867. #include <boost/asio/detail/pop_options.hpp>
  868. #endif // BOOST_ASIO_BASIC_STREAM_SOCKET_HPP