basic_stream_socket.hpp 39 KB

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