basic_stream_socket.hpp 44 KB

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