basic_stream_socket.hpp 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051
  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) BOOST_ASIO_NOEXCEPT
  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,
  438. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  439. std::size_t)) WriteHandler
  440. BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
  441. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
  442. void (boost::system::error_code, std::size_t))
  443. async_send(const ConstBufferSequence& buffers,
  444. BOOST_ASIO_MOVE_ARG(WriteHandler) handler
  445. BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
  446. {
  447. return async_initiate<WriteHandler,
  448. void (boost::system::error_code, std::size_t)>(
  449. initiate_async_send(this), handler,
  450. buffers, socket_base::message_flags(0));
  451. }
  452. /// Start an asynchronous send.
  453. /**
  454. * This function is used to asynchronously send data on the stream socket.
  455. * The function call always returns immediately.
  456. *
  457. * @param buffers One or more data buffers to be sent on the socket. Although
  458. * the buffers object may be copied as necessary, ownership of the underlying
  459. * memory blocks is retained by the caller, which must guarantee that they
  460. * remain valid until the handler is called.
  461. *
  462. * @param flags Flags specifying how the send call is to be made.
  463. *
  464. * @param handler The handler to be called when the send operation completes.
  465. * Copies will be made of the handler as required. The function signature of
  466. * the handler must be:
  467. * @code void handler(
  468. * const boost::system::error_code& error, // Result of operation.
  469. * std::size_t bytes_transferred // Number of bytes sent.
  470. * ); @endcode
  471. * Regardless of whether the asynchronous operation completes immediately or
  472. * not, the handler will not be invoked from within this function. On
  473. * immediate completion, invocation of the handler will be performed in a
  474. * manner equivalent to using boost::asio::post().
  475. *
  476. * @note The send operation may not transmit all of the data to the peer.
  477. * Consider using the @ref async_write function if you need to ensure that all
  478. * data is written before the asynchronous operation completes.
  479. *
  480. * @par Example
  481. * To send a single data buffer use the @ref buffer function as follows:
  482. * @code
  483. * socket.async_send(boost::asio::buffer(data, size), 0, handler);
  484. * @endcode
  485. * See the @ref buffer documentation for information on sending multiple
  486. * buffers in one go, and how to use it with arrays, boost::array or
  487. * std::vector.
  488. */
  489. template <typename ConstBufferSequence,
  490. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  491. std::size_t)) WriteHandler
  492. BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
  493. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
  494. void (boost::system::error_code, std::size_t))
  495. async_send(const ConstBufferSequence& buffers,
  496. socket_base::message_flags flags,
  497. BOOST_ASIO_MOVE_ARG(WriteHandler) handler
  498. BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
  499. {
  500. return async_initiate<WriteHandler,
  501. void (boost::system::error_code, std::size_t)>(
  502. initiate_async_send(this), handler, buffers, flags);
  503. }
  504. /// Receive some data on the socket.
  505. /**
  506. * This function is used to receive data on the stream socket. The function
  507. * call will block until one or more bytes of data has been received
  508. * successfully, or until an error occurs.
  509. *
  510. * @param buffers One or more buffers into which the data will be received.
  511. *
  512. * @returns The number of bytes received.
  513. *
  514. * @throws boost::system::system_error Thrown on failure. An error code of
  515. * boost::asio::error::eof indicates that the connection was closed by the
  516. * peer.
  517. *
  518. * @note The receive operation may not receive all of the requested number of
  519. * bytes. Consider using the @ref read function if you need to ensure that the
  520. * requested amount of data is read before the blocking operation completes.
  521. *
  522. * @par Example
  523. * To receive into a single data buffer use the @ref buffer function as
  524. * follows:
  525. * @code
  526. * socket.receive(boost::asio::buffer(data, size));
  527. * @endcode
  528. * See the @ref buffer documentation for information on receiving into
  529. * multiple buffers in one go, and how to use it with arrays, boost::array or
  530. * std::vector.
  531. */
  532. template <typename MutableBufferSequence>
  533. std::size_t receive(const MutableBufferSequence& buffers)
  534. {
  535. boost::system::error_code ec;
  536. std::size_t s = this->impl_.get_service().receive(
  537. this->impl_.get_implementation(), buffers, 0, ec);
  538. boost::asio::detail::throw_error(ec, "receive");
  539. return s;
  540. }
  541. /// Receive some data on the socket.
  542. /**
  543. * This function is used to receive data on the stream socket. The function
  544. * call will block until one or more bytes of data has been received
  545. * successfully, or until an error occurs.
  546. *
  547. * @param buffers One or more buffers into which the data will be received.
  548. *
  549. * @param flags Flags specifying how the receive call is to be made.
  550. *
  551. * @returns The number of bytes received.
  552. *
  553. * @throws boost::system::system_error Thrown on failure. An error code of
  554. * boost::asio::error::eof indicates that the connection was closed by the
  555. * peer.
  556. *
  557. * @note The receive operation may not receive all of the requested number of
  558. * bytes. Consider using the @ref read function if you need to ensure that the
  559. * requested amount of data is read before the blocking operation completes.
  560. *
  561. * @par Example
  562. * To receive into a single data buffer use the @ref buffer function as
  563. * follows:
  564. * @code
  565. * socket.receive(boost::asio::buffer(data, size), 0);
  566. * @endcode
  567. * See the @ref buffer documentation for information on receiving into
  568. * multiple buffers in one go, and how to use it with arrays, boost::array or
  569. * std::vector.
  570. */
  571. template <typename MutableBufferSequence>
  572. std::size_t receive(const MutableBufferSequence& buffers,
  573. socket_base::message_flags flags)
  574. {
  575. boost::system::error_code ec;
  576. std::size_t s = this->impl_.get_service().receive(
  577. this->impl_.get_implementation(), buffers, flags, ec);
  578. boost::asio::detail::throw_error(ec, "receive");
  579. return s;
  580. }
  581. /// Receive some data on a connected socket.
  582. /**
  583. * This function is used to receive data on the stream socket. The function
  584. * call will block until one or more bytes of data has been received
  585. * successfully, or until an error occurs.
  586. *
  587. * @param buffers One or more buffers into which the data will be received.
  588. *
  589. * @param flags Flags specifying how the receive call is to be made.
  590. *
  591. * @param ec Set to indicate what error occurred, if any.
  592. *
  593. * @returns The number of bytes received. Returns 0 if an error occurred.
  594. *
  595. * @note The receive operation may not receive all of the requested number of
  596. * bytes. Consider using the @ref read function if you need to ensure that the
  597. * requested amount of data is read before the blocking operation completes.
  598. */
  599. template <typename MutableBufferSequence>
  600. std::size_t receive(const MutableBufferSequence& buffers,
  601. socket_base::message_flags flags, boost::system::error_code& ec)
  602. {
  603. return this->impl_.get_service().receive(
  604. this->impl_.get_implementation(), buffers, flags, ec);
  605. }
  606. /// Start an asynchronous receive.
  607. /**
  608. * This function is used to asynchronously receive data from the stream
  609. * socket. The function call always returns immediately.
  610. *
  611. * @param buffers One or more buffers into which the data will be received.
  612. * Although the buffers object may be copied as necessary, ownership of the
  613. * underlying memory blocks is retained by the caller, which must guarantee
  614. * that they remain valid until the handler is called.
  615. *
  616. * @param handler The handler to be called when the receive operation
  617. * completes. Copies will be made of the handler as required. The function
  618. * signature of the handler must be:
  619. * @code void handler(
  620. * const boost::system::error_code& error, // Result of operation.
  621. * std::size_t bytes_transferred // Number of bytes received.
  622. * ); @endcode
  623. * Regardless of whether the asynchronous operation completes immediately or
  624. * not, the handler will not be invoked from within this function. On
  625. * immediate completion, invocation of the handler will be performed in a
  626. * manner equivalent to using boost::asio::post().
  627. *
  628. * @note The receive operation may not receive all of the requested number of
  629. * bytes. Consider using the @ref async_read function if you need to ensure
  630. * that the requested amount of data is received before the asynchronous
  631. * operation completes.
  632. *
  633. * @par Example
  634. * To receive into a single data buffer use the @ref buffer function as
  635. * follows:
  636. * @code
  637. * socket.async_receive(boost::asio::buffer(data, size), handler);
  638. * @endcode
  639. * See the @ref buffer documentation for information on receiving into
  640. * multiple buffers in one go, and how to use it with arrays, boost::array or
  641. * std::vector.
  642. */
  643. template <typename MutableBufferSequence,
  644. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  645. std::size_t)) ReadHandler
  646. BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
  647. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
  648. void (boost::system::error_code, std::size_t))
  649. async_receive(const MutableBufferSequence& buffers,
  650. BOOST_ASIO_MOVE_ARG(ReadHandler) handler
  651. BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
  652. {
  653. return async_initiate<ReadHandler,
  654. void (boost::system::error_code, std::size_t)>(
  655. initiate_async_receive(this), handler,
  656. buffers, socket_base::message_flags(0));
  657. }
  658. /// Start an asynchronous receive.
  659. /**
  660. * This function is used to asynchronously receive data from the stream
  661. * socket. The function call always returns immediately.
  662. *
  663. * @param buffers One or more buffers into which the data will be received.
  664. * Although the buffers object may be copied as necessary, ownership of the
  665. * underlying memory blocks is retained by the caller, which must guarantee
  666. * that they remain valid until the handler is called.
  667. *
  668. * @param flags Flags specifying how the receive call is to be made.
  669. *
  670. * @param handler The handler to be called when the receive operation
  671. * completes. Copies will be made of the handler as required. The function
  672. * signature of the handler must be:
  673. * @code void handler(
  674. * const boost::system::error_code& error, // Result of operation.
  675. * std::size_t bytes_transferred // Number of bytes received.
  676. * ); @endcode
  677. * Regardless of whether the asynchronous operation completes immediately or
  678. * not, the handler will not be invoked from within this function. On
  679. * immediate completion, invocation of the handler will be performed in a
  680. * manner equivalent to using boost::asio::post().
  681. *
  682. * @note The receive operation may not receive all of the requested number of
  683. * bytes. Consider using the @ref async_read function if you need to ensure
  684. * that the requested amount of data is received before the asynchronous
  685. * operation completes.
  686. *
  687. * @par Example
  688. * To receive into a single data buffer use the @ref buffer function as
  689. * follows:
  690. * @code
  691. * socket.async_receive(boost::asio::buffer(data, size), 0, handler);
  692. * @endcode
  693. * See the @ref buffer documentation for information on receiving into
  694. * multiple buffers in one go, and how to use it with arrays, boost::array or
  695. * std::vector.
  696. */
  697. template <typename MutableBufferSequence,
  698. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  699. std::size_t)) ReadHandler
  700. BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
  701. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
  702. void (boost::system::error_code, std::size_t))
  703. async_receive(const MutableBufferSequence& buffers,
  704. socket_base::message_flags flags,
  705. BOOST_ASIO_MOVE_ARG(ReadHandler) handler
  706. BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
  707. {
  708. return async_initiate<ReadHandler,
  709. void (boost::system::error_code, std::size_t)>(
  710. initiate_async_receive(this), handler, buffers, flags);
  711. }
  712. /// Write some data to the socket.
  713. /**
  714. * This function is used to write data to the stream socket. The function call
  715. * will block until one or more bytes of the data has been written
  716. * successfully, or until an error occurs.
  717. *
  718. * @param buffers One or more data buffers to be written to the socket.
  719. *
  720. * @returns The number of bytes written.
  721. *
  722. * @throws boost::system::system_error Thrown on failure. An error code of
  723. * boost::asio::error::eof indicates that the connection was closed by the
  724. * peer.
  725. *
  726. * @note The write_some operation may not transmit all of the data to the
  727. * peer. Consider using the @ref write function if you need to ensure that
  728. * all data is written before the blocking operation completes.
  729. *
  730. * @par Example
  731. * To write a single data buffer use the @ref buffer function as follows:
  732. * @code
  733. * socket.write_some(boost::asio::buffer(data, size));
  734. * @endcode
  735. * See the @ref buffer documentation for information on writing multiple
  736. * buffers in one go, and how to use it with arrays, boost::array or
  737. * std::vector.
  738. */
  739. template <typename ConstBufferSequence>
  740. std::size_t write_some(const ConstBufferSequence& buffers)
  741. {
  742. boost::system::error_code ec;
  743. std::size_t s = this->impl_.get_service().send(
  744. this->impl_.get_implementation(), buffers, 0, ec);
  745. boost::asio::detail::throw_error(ec, "write_some");
  746. return s;
  747. }
  748. /// Write some data to the socket.
  749. /**
  750. * This function is used to write data to the stream socket. The function call
  751. * will block until one or more bytes of the data has been written
  752. * successfully, or until an error occurs.
  753. *
  754. * @param buffers One or more data buffers to be written to the socket.
  755. *
  756. * @param ec Set to indicate what error occurred, if any.
  757. *
  758. * @returns The number of bytes written. Returns 0 if an error occurred.
  759. *
  760. * @note The write_some operation may not transmit all of the data to the
  761. * peer. Consider using the @ref write function if you need to ensure that
  762. * all data is written before the blocking operation completes.
  763. */
  764. template <typename ConstBufferSequence>
  765. std::size_t write_some(const ConstBufferSequence& buffers,
  766. boost::system::error_code& ec)
  767. {
  768. return this->impl_.get_service().send(
  769. this->impl_.get_implementation(), buffers, 0, ec);
  770. }
  771. /// Start an asynchronous write.
  772. /**
  773. * This function is used to asynchronously write data to the stream socket.
  774. * The function call always returns immediately.
  775. *
  776. * @param buffers One or more data buffers to be written to the socket.
  777. * Although the buffers object may be copied as necessary, ownership of the
  778. * underlying memory blocks is retained by the caller, which must guarantee
  779. * that they remain valid until the handler is called.
  780. *
  781. * @param handler The handler to be called when the write operation completes.
  782. * Copies will be made of the handler as required. The function signature of
  783. * the handler must be:
  784. * @code void handler(
  785. * const boost::system::error_code& error, // Result of operation.
  786. * std::size_t bytes_transferred // Number of bytes written.
  787. * ); @endcode
  788. * Regardless of whether the asynchronous operation completes immediately or
  789. * not, the handler will not be invoked from within this function. On
  790. * immediate completion, invocation of the handler will be performed in a
  791. * manner equivalent to using boost::asio::post().
  792. *
  793. * @note The write operation may not transmit all of the data to the peer.
  794. * Consider using the @ref async_write function if you need to ensure that all
  795. * data is written before the asynchronous operation completes.
  796. *
  797. * @par Example
  798. * To write a single data buffer use the @ref buffer function as follows:
  799. * @code
  800. * socket.async_write_some(boost::asio::buffer(data, size), handler);
  801. * @endcode
  802. * See the @ref buffer documentation for information on writing multiple
  803. * buffers in one go, and how to use it with arrays, boost::array or
  804. * std::vector.
  805. */
  806. template <typename ConstBufferSequence,
  807. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  808. std::size_t)) WriteHandler
  809. BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
  810. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
  811. void (boost::system::error_code, std::size_t))
  812. async_write_some(const ConstBufferSequence& buffers,
  813. BOOST_ASIO_MOVE_ARG(WriteHandler) handler
  814. BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
  815. {
  816. return async_initiate<WriteHandler,
  817. void (boost::system::error_code, std::size_t)>(
  818. initiate_async_send(this), handler,
  819. buffers, socket_base::message_flags(0));
  820. }
  821. /// Read some data from the socket.
  822. /**
  823. * This function is used to read data from the stream socket. The function
  824. * call will block until one or more bytes of data has been read successfully,
  825. * or until an error occurs.
  826. *
  827. * @param buffers One or more buffers into which the data will be read.
  828. *
  829. * @returns The number of bytes read.
  830. *
  831. * @throws boost::system::system_error Thrown on failure. An error code of
  832. * boost::asio::error::eof indicates that the connection was closed by the
  833. * peer.
  834. *
  835. * @note The read_some operation may not read all of the requested number of
  836. * bytes. Consider using the @ref read function if you need to ensure that
  837. * the requested amount of data is read before the blocking operation
  838. * completes.
  839. *
  840. * @par Example
  841. * To read into a single data buffer use the @ref buffer function as follows:
  842. * @code
  843. * socket.read_some(boost::asio::buffer(data, size));
  844. * @endcode
  845. * See the @ref buffer documentation for information on reading into multiple
  846. * buffers in one go, and how to use it with arrays, boost::array or
  847. * std::vector.
  848. */
  849. template <typename MutableBufferSequence>
  850. std::size_t read_some(const MutableBufferSequence& buffers)
  851. {
  852. boost::system::error_code ec;
  853. std::size_t s = this->impl_.get_service().receive(
  854. this->impl_.get_implementation(), buffers, 0, ec);
  855. boost::asio::detail::throw_error(ec, "read_some");
  856. return s;
  857. }
  858. /// Read some data from the socket.
  859. /**
  860. * This function is used to read data from the stream socket. The function
  861. * call will block until one or more bytes of data has been read successfully,
  862. * or until an error occurs.
  863. *
  864. * @param buffers One or more buffers into which the data will be read.
  865. *
  866. * @param ec Set to indicate what error occurred, if any.
  867. *
  868. * @returns The number of bytes read. Returns 0 if an error occurred.
  869. *
  870. * @note The read_some operation may not read all of the requested number of
  871. * bytes. Consider using the @ref read function if you need to ensure that
  872. * the requested amount of data is read before the blocking operation
  873. * completes.
  874. */
  875. template <typename MutableBufferSequence>
  876. std::size_t read_some(const MutableBufferSequence& buffers,
  877. boost::system::error_code& ec)
  878. {
  879. return this->impl_.get_service().receive(
  880. this->impl_.get_implementation(), buffers, 0, ec);
  881. }
  882. /// Start an asynchronous read.
  883. /**
  884. * This function is used to asynchronously read data from the stream socket.
  885. * The function call always returns immediately.
  886. *
  887. * @param buffers One or more buffers into which the data will be read.
  888. * Although the buffers object may be copied as necessary, ownership of the
  889. * underlying memory blocks is retained by the caller, which must guarantee
  890. * that they remain valid until the handler is called.
  891. *
  892. * @param handler The handler to be called when the read operation completes.
  893. * Copies will be made of the handler as required. The function signature of
  894. * the handler must be:
  895. * @code void handler(
  896. * const boost::system::error_code& error, // Result of operation.
  897. * std::size_t bytes_transferred // Number of bytes read.
  898. * ); @endcode
  899. * Regardless of whether the asynchronous operation completes immediately or
  900. * not, the handler will not be invoked from within this function. On
  901. * immediate completion, invocation of the handler will be performed in a
  902. * manner equivalent to using boost::asio::post().
  903. *
  904. * @note The read operation may not read all of the requested number of bytes.
  905. * Consider using the @ref async_read function if you need to ensure that the
  906. * requested amount of data is read before the asynchronous operation
  907. * completes.
  908. *
  909. * @par Example
  910. * To read into a single data buffer use the @ref buffer function as follows:
  911. * @code
  912. * socket.async_read_some(boost::asio::buffer(data, size), handler);
  913. * @endcode
  914. * See the @ref buffer documentation for information on reading into multiple
  915. * buffers in one go, and how to use it with arrays, boost::array or
  916. * std::vector.
  917. */
  918. template <typename MutableBufferSequence,
  919. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  920. std::size_t)) ReadHandler
  921. BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
  922. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
  923. void (boost::system::error_code, std::size_t))
  924. async_read_some(const MutableBufferSequence& buffers,
  925. BOOST_ASIO_MOVE_ARG(ReadHandler) handler
  926. BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
  927. {
  928. return async_initiate<ReadHandler,
  929. void (boost::system::error_code, std::size_t)>(
  930. initiate_async_receive(this), handler,
  931. buffers, socket_base::message_flags(0));
  932. }
  933. private:
  934. class initiate_async_send
  935. {
  936. public:
  937. typedef Executor executor_type;
  938. explicit initiate_async_send(basic_stream_socket* self)
  939. : self_(self)
  940. {
  941. }
  942. executor_type get_executor() const BOOST_ASIO_NOEXCEPT
  943. {
  944. return self_->get_executor();
  945. }
  946. template <typename WriteHandler, typename ConstBufferSequence>
  947. void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
  948. const ConstBufferSequence& buffers,
  949. socket_base::message_flags flags) const
  950. {
  951. // If you get an error on the following line it means that your handler
  952. // does not meet the documented type requirements for a WriteHandler.
  953. BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
  954. detail::non_const_lvalue<WriteHandler> handler2(handler);
  955. self_->impl_.get_service().async_send(
  956. self_->impl_.get_implementation(), buffers, flags,
  957. handler2.value, self_->impl_.get_implementation_executor());
  958. }
  959. private:
  960. basic_stream_socket* self_;
  961. };
  962. class initiate_async_receive
  963. {
  964. public:
  965. typedef Executor executor_type;
  966. explicit initiate_async_receive(basic_stream_socket* self)
  967. : self_(self)
  968. {
  969. }
  970. executor_type get_executor() const BOOST_ASIO_NOEXCEPT
  971. {
  972. return self_->get_executor();
  973. }
  974. template <typename ReadHandler, typename MutableBufferSequence>
  975. void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
  976. const MutableBufferSequence& buffers,
  977. socket_base::message_flags flags) const
  978. {
  979. // If you get an error on the following line it means that your handler
  980. // does not meet the documented type requirements for a ReadHandler.
  981. BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
  982. detail::non_const_lvalue<ReadHandler> handler2(handler);
  983. self_->impl_.get_service().async_receive(
  984. self_->impl_.get_implementation(), buffers, flags,
  985. handler2.value, self_->impl_.get_implementation_executor());
  986. }
  987. private:
  988. basic_stream_socket* self_;
  989. };
  990. };
  991. } // namespace asio
  992. } // namespace boost
  993. #include <boost/asio/detail/pop_options.hpp>
  994. #endif // BOOST_ASIO_BASIC_STREAM_SOCKET_HPP