basic_socket.hpp 64 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896
  1. //
  2. // basic_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_SOCKET_HPP
  11. #define BOOST_ASIO_BASIC_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 <boost/asio/async_result.hpp>
  17. #include <boost/asio/detail/handler_type_requirements.hpp>
  18. #include <boost/asio/detail/io_object_impl.hpp>
  19. #include <boost/asio/detail/non_const_lvalue.hpp>
  20. #include <boost/asio/detail/throw_error.hpp>
  21. #include <boost/asio/detail/type_traits.hpp>
  22. #include <boost/asio/error.hpp>
  23. #include <boost/asio/execution_context.hpp>
  24. #include <boost/asio/executor.hpp>
  25. #include <boost/asio/post.hpp>
  26. #include <boost/asio/socket_base.hpp>
  27. #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
  28. # include <boost/asio/detail/null_socket_service.hpp>
  29. #elif defined(BOOST_ASIO_HAS_IOCP)
  30. # include <boost/asio/detail/win_iocp_socket_service.hpp>
  31. #else
  32. # include <boost/asio/detail/reactive_socket_service.hpp>
  33. #endif
  34. #if defined(BOOST_ASIO_HAS_MOVE)
  35. # include <utility>
  36. #endif // defined(BOOST_ASIO_HAS_MOVE)
  37. #include <boost/asio/detail/push_options.hpp>
  38. namespace boost {
  39. namespace asio {
  40. #if !defined(BOOST_ASIO_BASIC_SOCKET_FWD_DECL)
  41. #define BOOST_ASIO_BASIC_SOCKET_FWD_DECL
  42. // Forward declaration with defaulted arguments.
  43. template <typename Protocol, typename Executor = executor>
  44. class basic_socket;
  45. #endif // !defined(BOOST_ASIO_BASIC_SOCKET_FWD_DECL)
  46. /// Provides socket functionality.
  47. /**
  48. * The basic_socket class template provides functionality that is common to both
  49. * stream-oriented and datagram-oriented sockets.
  50. *
  51. * @par Thread Safety
  52. * @e Distinct @e objects: Safe.@n
  53. * @e Shared @e objects: Unsafe.
  54. */
  55. template <typename Protocol, typename Executor>
  56. class basic_socket
  57. : public socket_base
  58. {
  59. public:
  60. /// The type of the executor associated with the object.
  61. typedef Executor executor_type;
  62. /// Rebinds the socket type to another executor.
  63. template <typename Executor1>
  64. struct rebind_executor
  65. {
  66. /// The socket type when rebound to the specified executor.
  67. typedef basic_socket<Protocol, Executor1> other;
  68. };
  69. /// The native representation of a socket.
  70. #if defined(GENERATING_DOCUMENTATION)
  71. typedef implementation_defined native_handle_type;
  72. #elif defined(BOOST_ASIO_WINDOWS_RUNTIME)
  73. typedef typename detail::null_socket_service<
  74. Protocol>::native_handle_type native_handle_type;
  75. #elif defined(BOOST_ASIO_HAS_IOCP)
  76. typedef typename detail::win_iocp_socket_service<
  77. Protocol>::native_handle_type native_handle_type;
  78. #else
  79. typedef typename detail::reactive_socket_service<
  80. Protocol>::native_handle_type native_handle_type;
  81. #endif
  82. /// The protocol type.
  83. typedef Protocol protocol_type;
  84. /// The endpoint type.
  85. typedef typename Protocol::endpoint endpoint_type;
  86. #if !defined(BOOST_ASIO_NO_EXTENSIONS)
  87. /// A basic_socket is always the lowest layer.
  88. typedef basic_socket<Protocol, Executor> lowest_layer_type;
  89. #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
  90. /// Construct a basic_socket without opening it.
  91. /**
  92. * This constructor creates a socket without opening it.
  93. *
  94. * @param ex The I/O executor that the socket will use, by default, to
  95. * dispatch handlers for any asynchronous operations performed on the socket.
  96. */
  97. explicit basic_socket(const executor_type& ex)
  98. : impl_(ex)
  99. {
  100. }
  101. /// Construct a basic_socket without opening it.
  102. /**
  103. * This constructor creates a socket without opening it.
  104. *
  105. * @param context An execution context which provides the I/O executor that
  106. * the socket will use, by default, to dispatch handlers for any asynchronous
  107. * operations performed on the socket.
  108. */
  109. template <typename ExecutionContext>
  110. explicit basic_socket(ExecutionContext& context,
  111. typename enable_if<
  112. is_convertible<ExecutionContext&, execution_context&>::value
  113. >::type* = 0)
  114. : impl_(context)
  115. {
  116. }
  117. /// Construct and open a basic_socket.
  118. /**
  119. * This constructor creates and opens a socket.
  120. *
  121. * @param ex The I/O executor that the socket will use, by default, to
  122. * dispatch handlers for any asynchronous operations performed on the socket.
  123. *
  124. * @param protocol An object specifying protocol parameters to be used.
  125. *
  126. * @throws boost::system::system_error Thrown on failure.
  127. */
  128. basic_socket(const executor_type& ex, const protocol_type& protocol)
  129. : impl_(ex)
  130. {
  131. boost::system::error_code ec;
  132. impl_.get_service().open(impl_.get_implementation(), protocol, ec);
  133. boost::asio::detail::throw_error(ec, "open");
  134. }
  135. /// Construct and open a basic_socket.
  136. /**
  137. * This constructor creates and opens a socket.
  138. *
  139. * @param context An execution context which provides the I/O executor that
  140. * the socket will use, by default, to dispatch handlers for any asynchronous
  141. * operations performed on the socket.
  142. *
  143. * @param protocol An object specifying protocol parameters to be used.
  144. *
  145. * @throws boost::system::system_error Thrown on failure.
  146. */
  147. template <typename ExecutionContext>
  148. basic_socket(ExecutionContext& context, const protocol_type& protocol,
  149. typename enable_if<
  150. is_convertible<ExecutionContext&, execution_context&>::value
  151. >::type* = 0)
  152. : impl_(context)
  153. {
  154. boost::system::error_code ec;
  155. impl_.get_service().open(impl_.get_implementation(), protocol, ec);
  156. boost::asio::detail::throw_error(ec, "open");
  157. }
  158. /// Construct a basic_socket, opening it and binding it to the given local
  159. /// endpoint.
  160. /**
  161. * This constructor creates a socket and automatically opens it bound to the
  162. * specified endpoint on the local machine. The protocol used is the protocol
  163. * associated with the given endpoint.
  164. *
  165. * @param ex The I/O executor that the socket will use, by default, to
  166. * dispatch handlers for any asynchronous operations performed on the socket.
  167. *
  168. * @param endpoint An endpoint on the local machine to which the socket will
  169. * be bound.
  170. *
  171. * @throws boost::system::system_error Thrown on failure.
  172. */
  173. basic_socket(const executor_type& ex, const endpoint_type& endpoint)
  174. : impl_(ex)
  175. {
  176. boost::system::error_code ec;
  177. const protocol_type protocol = endpoint.protocol();
  178. impl_.get_service().open(impl_.get_implementation(), protocol, ec);
  179. boost::asio::detail::throw_error(ec, "open");
  180. impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
  181. boost::asio::detail::throw_error(ec, "bind");
  182. }
  183. /// Construct a basic_socket, opening it and binding it to the given local
  184. /// endpoint.
  185. /**
  186. * This constructor creates a socket and automatically opens it bound to the
  187. * specified endpoint on the local machine. The protocol used is the protocol
  188. * associated with the given endpoint.
  189. *
  190. * @param context An execution context which provides the I/O executor that
  191. * the socket will use, by default, to dispatch handlers for any asynchronous
  192. * operations performed on the socket.
  193. *
  194. * @param endpoint An endpoint on the local machine to which the socket will
  195. * be bound.
  196. *
  197. * @throws boost::system::system_error Thrown on failure.
  198. */
  199. template <typename ExecutionContext>
  200. basic_socket(ExecutionContext& context, const endpoint_type& endpoint,
  201. typename enable_if<
  202. is_convertible<ExecutionContext&, execution_context&>::value
  203. >::type* = 0)
  204. : impl_(context)
  205. {
  206. boost::system::error_code ec;
  207. const protocol_type protocol = endpoint.protocol();
  208. impl_.get_service().open(impl_.get_implementation(), protocol, ec);
  209. boost::asio::detail::throw_error(ec, "open");
  210. impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
  211. boost::asio::detail::throw_error(ec, "bind");
  212. }
  213. /// Construct a basic_socket on an existing native socket.
  214. /**
  215. * This constructor creates a socket object to hold an existing native socket.
  216. *
  217. * @param ex The I/O executor that the socket will use, by default, to
  218. * dispatch handlers for any asynchronous operations performed on the socket.
  219. *
  220. * @param protocol An object specifying protocol parameters to be used.
  221. *
  222. * @param native_socket A native socket.
  223. *
  224. * @throws boost::system::system_error Thrown on failure.
  225. */
  226. basic_socket(const executor_type& ex, const protocol_type& protocol,
  227. const native_handle_type& native_socket)
  228. : impl_(ex)
  229. {
  230. boost::system::error_code ec;
  231. impl_.get_service().assign(impl_.get_implementation(),
  232. protocol, native_socket, ec);
  233. boost::asio::detail::throw_error(ec, "assign");
  234. }
  235. /// Construct a basic_socket on an existing native socket.
  236. /**
  237. * This constructor creates a socket object to hold an existing native socket.
  238. *
  239. * @param context An execution context which provides the I/O executor that
  240. * the socket will use, by default, to dispatch handlers for any asynchronous
  241. * operations performed on the socket.
  242. *
  243. * @param protocol An object specifying protocol parameters to be used.
  244. *
  245. * @param native_socket A native socket.
  246. *
  247. * @throws boost::system::system_error Thrown on failure.
  248. */
  249. template <typename ExecutionContext>
  250. basic_socket(ExecutionContext& context, const protocol_type& protocol,
  251. const native_handle_type& native_socket,
  252. typename enable_if<
  253. is_convertible<ExecutionContext&, execution_context&>::value
  254. >::type* = 0)
  255. : impl_(context)
  256. {
  257. boost::system::error_code ec;
  258. impl_.get_service().assign(impl_.get_implementation(),
  259. protocol, native_socket, ec);
  260. boost::asio::detail::throw_error(ec, "assign");
  261. }
  262. #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  263. /// Move-construct a basic_socket from another.
  264. /**
  265. * This constructor moves a socket from one object to another.
  266. *
  267. * @param other The other basic_socket object from which the move will
  268. * occur.
  269. *
  270. * @note Following the move, the moved-from object is in the same state as if
  271. * constructed using the @c basic_socket(const executor_type&) constructor.
  272. */
  273. basic_socket(basic_socket&& other) BOOST_ASIO_NOEXCEPT
  274. : impl_(std::move(other.impl_))
  275. {
  276. }
  277. /// Move-assign a basic_socket from another.
  278. /**
  279. * This assignment operator moves a socket from one object to another.
  280. *
  281. * @param other The other basic_socket object from which the move will
  282. * occur.
  283. *
  284. * @note Following the move, the moved-from object is in the same state as if
  285. * constructed using the @c basic_socket(const executor_type&) constructor.
  286. */
  287. basic_socket& operator=(basic_socket&& other)
  288. {
  289. impl_ = std::move(other.impl_);
  290. return *this;
  291. }
  292. // All sockets have access to each other's implementations.
  293. template <typename Protocol1, typename Executor1>
  294. friend class basic_socket;
  295. /// Move-construct a basic_socket from a socket of another protocol type.
  296. /**
  297. * This constructor moves a socket from one object to another.
  298. *
  299. * @param other The other basic_socket object from which the move will
  300. * occur.
  301. *
  302. * @note Following the move, the moved-from object is in the same state as if
  303. * constructed using the @c basic_socket(const executor_type&) constructor.
  304. */
  305. template <typename Protocol1, typename Executor1>
  306. basic_socket(basic_socket<Protocol1, Executor1>&& other,
  307. typename enable_if<
  308. is_convertible<Protocol1, Protocol>::value
  309. && is_convertible<Executor1, Executor>::value
  310. >::type* = 0)
  311. : impl_(std::move(other.impl_))
  312. {
  313. }
  314. /// Move-assign a basic_socket from a socket of another protocol type.
  315. /**
  316. * This assignment operator moves a socket from one object to another.
  317. *
  318. * @param other The other basic_socket object from which the move will
  319. * occur.
  320. *
  321. * @note Following the move, the moved-from object is in the same state as if
  322. * constructed using the @c basic_socket(const executor_type&) constructor.
  323. */
  324. template <typename Protocol1, typename Executor1>
  325. typename enable_if<
  326. is_convertible<Protocol1, Protocol>::value
  327. && is_convertible<Executor1, Executor>::value,
  328. basic_socket&
  329. >::type operator=(basic_socket<Protocol1, Executor1> && other)
  330. {
  331. basic_socket tmp(std::move(other));
  332. impl_ = std::move(tmp.impl_);
  333. return *this;
  334. }
  335. #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  336. /// Get the executor associated with the object.
  337. executor_type get_executor() BOOST_ASIO_NOEXCEPT
  338. {
  339. return impl_.get_executor();
  340. }
  341. #if !defined(BOOST_ASIO_NO_EXTENSIONS)
  342. /// Get a reference to the lowest layer.
  343. /**
  344. * This function returns a reference to the lowest layer in a stack of
  345. * layers. Since a basic_socket cannot contain any further layers, it simply
  346. * returns a reference to itself.
  347. *
  348. * @return A reference to the lowest layer in the stack of layers. Ownership
  349. * is not transferred to the caller.
  350. */
  351. lowest_layer_type& lowest_layer()
  352. {
  353. return *this;
  354. }
  355. /// Get a const reference to the lowest layer.
  356. /**
  357. * This function returns a const reference to the lowest layer in a stack of
  358. * layers. Since a basic_socket cannot contain any further layers, it simply
  359. * returns a reference to itself.
  360. *
  361. * @return A const reference to the lowest layer in the stack of layers.
  362. * Ownership is not transferred to the caller.
  363. */
  364. const lowest_layer_type& lowest_layer() const
  365. {
  366. return *this;
  367. }
  368. #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
  369. /// Open the socket using the specified protocol.
  370. /**
  371. * This function opens the socket so that it will use the specified protocol.
  372. *
  373. * @param protocol An object specifying protocol parameters to be used.
  374. *
  375. * @throws boost::system::system_error Thrown on failure.
  376. *
  377. * @par Example
  378. * @code
  379. * boost::asio::ip::tcp::socket socket(my_context);
  380. * socket.open(boost::asio::ip::tcp::v4());
  381. * @endcode
  382. */
  383. void open(const protocol_type& protocol = protocol_type())
  384. {
  385. boost::system::error_code ec;
  386. impl_.get_service().open(impl_.get_implementation(), protocol, ec);
  387. boost::asio::detail::throw_error(ec, "open");
  388. }
  389. /// Open the socket using the specified protocol.
  390. /**
  391. * This function opens the socket so that it will use the specified protocol.
  392. *
  393. * @param protocol An object specifying which protocol is to be used.
  394. *
  395. * @param ec Set to indicate what error occurred, if any.
  396. *
  397. * @par Example
  398. * @code
  399. * boost::asio::ip::tcp::socket socket(my_context);
  400. * boost::system::error_code ec;
  401. * socket.open(boost::asio::ip::tcp::v4(), ec);
  402. * if (ec)
  403. * {
  404. * // An error occurred.
  405. * }
  406. * @endcode
  407. */
  408. BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol,
  409. boost::system::error_code& ec)
  410. {
  411. impl_.get_service().open(impl_.get_implementation(), protocol, ec);
  412. BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
  413. }
  414. /// Assign an existing native socket to the socket.
  415. /*
  416. * This function opens the socket to hold an existing native socket.
  417. *
  418. * @param protocol An object specifying which protocol is to be used.
  419. *
  420. * @param native_socket A native socket.
  421. *
  422. * @throws boost::system::system_error Thrown on failure.
  423. */
  424. void assign(const protocol_type& protocol,
  425. const native_handle_type& native_socket)
  426. {
  427. boost::system::error_code ec;
  428. impl_.get_service().assign(impl_.get_implementation(),
  429. protocol, native_socket, ec);
  430. boost::asio::detail::throw_error(ec, "assign");
  431. }
  432. /// Assign an existing native socket to the socket.
  433. /*
  434. * This function opens the socket to hold an existing native socket.
  435. *
  436. * @param protocol An object specifying which protocol is to be used.
  437. *
  438. * @param native_socket A native socket.
  439. *
  440. * @param ec Set to indicate what error occurred, if any.
  441. */
  442. BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol,
  443. const native_handle_type& native_socket, boost::system::error_code& ec)
  444. {
  445. impl_.get_service().assign(impl_.get_implementation(),
  446. protocol, native_socket, ec);
  447. BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
  448. }
  449. /// Determine whether the socket is open.
  450. bool is_open() const
  451. {
  452. return impl_.get_service().is_open(impl_.get_implementation());
  453. }
  454. /// Close the socket.
  455. /**
  456. * This function is used to close the socket. Any asynchronous send, receive
  457. * or connect operations will be cancelled immediately, and will complete
  458. * with the boost::asio::error::operation_aborted error.
  459. *
  460. * @throws boost::system::system_error Thrown on failure. Note that, even if
  461. * the function indicates an error, the underlying descriptor is closed.
  462. *
  463. * @note For portable behaviour with respect to graceful closure of a
  464. * connected socket, call shutdown() before closing the socket.
  465. */
  466. void close()
  467. {
  468. boost::system::error_code ec;
  469. impl_.get_service().close(impl_.get_implementation(), ec);
  470. boost::asio::detail::throw_error(ec, "close");
  471. }
  472. /// Close the socket.
  473. /**
  474. * This function is used to close the socket. Any asynchronous send, receive
  475. * or connect operations will be cancelled immediately, and will complete
  476. * with the boost::asio::error::operation_aborted error.
  477. *
  478. * @param ec Set to indicate what error occurred, if any. Note that, even if
  479. * the function indicates an error, the underlying descriptor is closed.
  480. *
  481. * @par Example
  482. * @code
  483. * boost::asio::ip::tcp::socket socket(my_context);
  484. * ...
  485. * boost::system::error_code ec;
  486. * socket.close(ec);
  487. * if (ec)
  488. * {
  489. * // An error occurred.
  490. * }
  491. * @endcode
  492. *
  493. * @note For portable behaviour with respect to graceful closure of a
  494. * connected socket, call shutdown() before closing the socket.
  495. */
  496. BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
  497. {
  498. impl_.get_service().close(impl_.get_implementation(), ec);
  499. BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
  500. }
  501. /// Release ownership of the underlying native socket.
  502. /**
  503. * This function causes all outstanding asynchronous connect, send and receive
  504. * operations to finish immediately, and the handlers for cancelled operations
  505. * will be passed the boost::asio::error::operation_aborted error. Ownership
  506. * of the native socket is then transferred to the caller.
  507. *
  508. * @throws boost::system::system_error Thrown on failure.
  509. *
  510. * @note This function is unsupported on Windows versions prior to Windows
  511. * 8.1, and will fail with boost::asio::error::operation_not_supported on
  512. * these platforms.
  513. */
  514. #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
  515. && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
  516. __declspec(deprecated("This function always fails with "
  517. "operation_not_supported when used on Windows versions "
  518. "prior to Windows 8.1."))
  519. #endif
  520. native_handle_type release()
  521. {
  522. boost::system::error_code ec;
  523. native_handle_type s = impl_.get_service().release(
  524. impl_.get_implementation(), ec);
  525. boost::asio::detail::throw_error(ec, "release");
  526. return s;
  527. }
  528. /// Release ownership of the underlying native socket.
  529. /**
  530. * This function causes all outstanding asynchronous connect, send and receive
  531. * operations to finish immediately, and the handlers for cancelled operations
  532. * will be passed the boost::asio::error::operation_aborted error. Ownership
  533. * of the native socket is then transferred to the caller.
  534. *
  535. * @param ec Set to indicate what error occurred, if any.
  536. *
  537. * @note This function is unsupported on Windows versions prior to Windows
  538. * 8.1, and will fail with boost::asio::error::operation_not_supported on
  539. * these platforms.
  540. */
  541. #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
  542. && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
  543. __declspec(deprecated("This function always fails with "
  544. "operation_not_supported when used on Windows versions "
  545. "prior to Windows 8.1."))
  546. #endif
  547. native_handle_type release(boost::system::error_code& ec)
  548. {
  549. return impl_.get_service().release(impl_.get_implementation(), ec);
  550. }
  551. /// Get the native socket representation.
  552. /**
  553. * This function may be used to obtain the underlying representation of the
  554. * socket. This is intended to allow access to native socket functionality
  555. * that is not otherwise provided.
  556. */
  557. native_handle_type native_handle()
  558. {
  559. return impl_.get_service().native_handle(impl_.get_implementation());
  560. }
  561. /// Cancel all asynchronous operations associated with the socket.
  562. /**
  563. * This function causes all outstanding asynchronous connect, send and receive
  564. * operations to finish immediately, and the handlers for cancelled operations
  565. * will be passed the boost::asio::error::operation_aborted error.
  566. *
  567. * @throws boost::system::system_error Thrown on failure.
  568. *
  569. * @note Calls to cancel() will always fail with
  570. * boost::asio::error::operation_not_supported when run on Windows XP, Windows
  571. * Server 2003, and earlier versions of Windows, unless
  572. * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has
  573. * two issues that should be considered before enabling its use:
  574. *
  575. * @li It will only cancel asynchronous operations that were initiated in the
  576. * current thread.
  577. *
  578. * @li It can appear to complete without error, but the request to cancel the
  579. * unfinished operations may be silently ignored by the operating system.
  580. * Whether it works or not seems to depend on the drivers that are installed.
  581. *
  582. * For portable cancellation, consider using one of the following
  583. * alternatives:
  584. *
  585. * @li Disable asio's I/O completion port backend by defining
  586. * BOOST_ASIO_DISABLE_IOCP.
  587. *
  588. * @li Use the close() function to simultaneously cancel the outstanding
  589. * operations and close the socket.
  590. *
  591. * When running on Windows Vista, Windows Server 2008, and later, the
  592. * CancelIoEx function is always used. This function does not have the
  593. * problems described above.
  594. */
  595. #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
  596. && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \
  597. && !defined(BOOST_ASIO_ENABLE_CANCELIO)
  598. __declspec(deprecated("By default, this function always fails with "
  599. "operation_not_supported when used on Windows XP, Windows Server 2003, "
  600. "or earlier. Consult documentation for details."))
  601. #endif
  602. void cancel()
  603. {
  604. boost::system::error_code ec;
  605. impl_.get_service().cancel(impl_.get_implementation(), ec);
  606. boost::asio::detail::throw_error(ec, "cancel");
  607. }
  608. /// Cancel all asynchronous operations associated with the socket.
  609. /**
  610. * This function causes all outstanding asynchronous connect, send and receive
  611. * operations to finish immediately, and the handlers for cancelled operations
  612. * will be passed the boost::asio::error::operation_aborted error.
  613. *
  614. * @param ec Set to indicate what error occurred, if any.
  615. *
  616. * @note Calls to cancel() will always fail with
  617. * boost::asio::error::operation_not_supported when run on Windows XP, Windows
  618. * Server 2003, and earlier versions of Windows, unless
  619. * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has
  620. * two issues that should be considered before enabling its use:
  621. *
  622. * @li It will only cancel asynchronous operations that were initiated in the
  623. * current thread.
  624. *
  625. * @li It can appear to complete without error, but the request to cancel the
  626. * unfinished operations may be silently ignored by the operating system.
  627. * Whether it works or not seems to depend on the drivers that are installed.
  628. *
  629. * For portable cancellation, consider using one of the following
  630. * alternatives:
  631. *
  632. * @li Disable asio's I/O completion port backend by defining
  633. * BOOST_ASIO_DISABLE_IOCP.
  634. *
  635. * @li Use the close() function to simultaneously cancel the outstanding
  636. * operations and close the socket.
  637. *
  638. * When running on Windows Vista, Windows Server 2008, and later, the
  639. * CancelIoEx function is always used. This function does not have the
  640. * problems described above.
  641. */
  642. #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
  643. && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \
  644. && !defined(BOOST_ASIO_ENABLE_CANCELIO)
  645. __declspec(deprecated("By default, this function always fails with "
  646. "operation_not_supported when used on Windows XP, Windows Server 2003, "
  647. "or earlier. Consult documentation for details."))
  648. #endif
  649. BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
  650. {
  651. impl_.get_service().cancel(impl_.get_implementation(), ec);
  652. BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
  653. }
  654. /// Determine whether the socket is at the out-of-band data mark.
  655. /**
  656. * This function is used to check whether the socket input is currently
  657. * positioned at the out-of-band data mark.
  658. *
  659. * @return A bool indicating whether the socket is at the out-of-band data
  660. * mark.
  661. *
  662. * @throws boost::system::system_error Thrown on failure.
  663. */
  664. bool at_mark() const
  665. {
  666. boost::system::error_code ec;
  667. bool b = impl_.get_service().at_mark(impl_.get_implementation(), ec);
  668. boost::asio::detail::throw_error(ec, "at_mark");
  669. return b;
  670. }
  671. /// Determine whether the socket is at the out-of-band data mark.
  672. /**
  673. * This function is used to check whether the socket input is currently
  674. * positioned at the out-of-band data mark.
  675. *
  676. * @param ec Set to indicate what error occurred, if any.
  677. *
  678. * @return A bool indicating whether the socket is at the out-of-band data
  679. * mark.
  680. */
  681. bool at_mark(boost::system::error_code& ec) const
  682. {
  683. return impl_.get_service().at_mark(impl_.get_implementation(), ec);
  684. }
  685. /// Determine the number of bytes available for reading.
  686. /**
  687. * This function is used to determine the number of bytes that may be read
  688. * without blocking.
  689. *
  690. * @return The number of bytes that may be read without blocking, or 0 if an
  691. * error occurs.
  692. *
  693. * @throws boost::system::system_error Thrown on failure.
  694. */
  695. std::size_t available() const
  696. {
  697. boost::system::error_code ec;
  698. std::size_t s = impl_.get_service().available(
  699. impl_.get_implementation(), ec);
  700. boost::asio::detail::throw_error(ec, "available");
  701. return s;
  702. }
  703. /// Determine the number of bytes available for reading.
  704. /**
  705. * This function is used to determine the number of bytes that may be read
  706. * without blocking.
  707. *
  708. * @param ec Set to indicate what error occurred, if any.
  709. *
  710. * @return The number of bytes that may be read without blocking, or 0 if an
  711. * error occurs.
  712. */
  713. std::size_t available(boost::system::error_code& ec) const
  714. {
  715. return impl_.get_service().available(impl_.get_implementation(), ec);
  716. }
  717. /// Bind the socket to the given local endpoint.
  718. /**
  719. * This function binds the socket to the specified endpoint on the local
  720. * machine.
  721. *
  722. * @param endpoint An endpoint on the local machine to which the socket will
  723. * be bound.
  724. *
  725. * @throws boost::system::system_error Thrown on failure.
  726. *
  727. * @par Example
  728. * @code
  729. * boost::asio::ip::tcp::socket socket(my_context);
  730. * socket.open(boost::asio::ip::tcp::v4());
  731. * socket.bind(boost::asio::ip::tcp::endpoint(
  732. * boost::asio::ip::tcp::v4(), 12345));
  733. * @endcode
  734. */
  735. void bind(const endpoint_type& endpoint)
  736. {
  737. boost::system::error_code ec;
  738. impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
  739. boost::asio::detail::throw_error(ec, "bind");
  740. }
  741. /// Bind the socket to the given local endpoint.
  742. /**
  743. * This function binds the socket to the specified endpoint on the local
  744. * machine.
  745. *
  746. * @param endpoint An endpoint on the local machine to which the socket will
  747. * be bound.
  748. *
  749. * @param ec Set to indicate what error occurred, if any.
  750. *
  751. * @par Example
  752. * @code
  753. * boost::asio::ip::tcp::socket socket(my_context);
  754. * socket.open(boost::asio::ip::tcp::v4());
  755. * boost::system::error_code ec;
  756. * socket.bind(boost::asio::ip::tcp::endpoint(
  757. * boost::asio::ip::tcp::v4(), 12345), ec);
  758. * if (ec)
  759. * {
  760. * // An error occurred.
  761. * }
  762. * @endcode
  763. */
  764. BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint,
  765. boost::system::error_code& ec)
  766. {
  767. impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
  768. BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
  769. }
  770. /// Connect the socket to the specified endpoint.
  771. /**
  772. * This function is used to connect a socket to the specified remote endpoint.
  773. * The function call will block until the connection is successfully made or
  774. * an error occurs.
  775. *
  776. * The socket is automatically opened if it is not already open. If the
  777. * connect fails, and the socket was automatically opened, the socket is
  778. * not returned to the closed state.
  779. *
  780. * @param peer_endpoint The remote endpoint to which the socket will be
  781. * connected.
  782. *
  783. * @throws boost::system::system_error Thrown on failure.
  784. *
  785. * @par Example
  786. * @code
  787. * boost::asio::ip::tcp::socket socket(my_context);
  788. * boost::asio::ip::tcp::endpoint endpoint(
  789. * boost::asio::ip::address::from_string("1.2.3.4"), 12345);
  790. * socket.connect(endpoint);
  791. * @endcode
  792. */
  793. void connect(const endpoint_type& peer_endpoint)
  794. {
  795. boost::system::error_code ec;
  796. if (!is_open())
  797. {
  798. impl_.get_service().open(impl_.get_implementation(),
  799. peer_endpoint.protocol(), ec);
  800. boost::asio::detail::throw_error(ec, "connect");
  801. }
  802. impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec);
  803. boost::asio::detail::throw_error(ec, "connect");
  804. }
  805. /// Connect the socket to the specified endpoint.
  806. /**
  807. * This function is used to connect a socket to the specified remote endpoint.
  808. * The function call will block until the connection is successfully made or
  809. * an error occurs.
  810. *
  811. * The socket is automatically opened if it is not already open. If the
  812. * connect fails, and the socket was automatically opened, the socket is
  813. * not returned to the closed state.
  814. *
  815. * @param peer_endpoint The remote endpoint to which the socket will be
  816. * connected.
  817. *
  818. * @param ec Set to indicate what error occurred, if any.
  819. *
  820. * @par Example
  821. * @code
  822. * boost::asio::ip::tcp::socket socket(my_context);
  823. * boost::asio::ip::tcp::endpoint endpoint(
  824. * boost::asio::ip::address::from_string("1.2.3.4"), 12345);
  825. * boost::system::error_code ec;
  826. * socket.connect(endpoint, ec);
  827. * if (ec)
  828. * {
  829. * // An error occurred.
  830. * }
  831. * @endcode
  832. */
  833. BOOST_ASIO_SYNC_OP_VOID connect(const endpoint_type& peer_endpoint,
  834. boost::system::error_code& ec)
  835. {
  836. if (!is_open())
  837. {
  838. impl_.get_service().open(impl_.get_implementation(),
  839. peer_endpoint.protocol(), ec);
  840. if (ec)
  841. {
  842. BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
  843. }
  844. }
  845. impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec);
  846. BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
  847. }
  848. /// Start an asynchronous connect.
  849. /**
  850. * This function is used to asynchronously connect a socket to the specified
  851. * remote endpoint. The function call always returns immediately.
  852. *
  853. * The socket is automatically opened if it is not already open. If the
  854. * connect fails, and the socket was automatically opened, the socket is
  855. * not returned to the closed state.
  856. *
  857. * @param peer_endpoint The remote endpoint to which the socket will be
  858. * connected. Copies will be made of the endpoint object as required.
  859. *
  860. * @param handler The handler to be called when the connection operation
  861. * completes. Copies will be made of the handler as required. The function
  862. * signature of the handler must be:
  863. * @code void handler(
  864. * const boost::system::error_code& error // Result of operation
  865. * ); @endcode
  866. * Regardless of whether the asynchronous operation completes immediately or
  867. * not, the handler will not be invoked from within this function. On
  868. * immediate completion, invocation of the handler will be performed in a
  869. * manner equivalent to using boost::asio::post().
  870. *
  871. * @par Example
  872. * @code
  873. * void connect_handler(const boost::system::error_code& error)
  874. * {
  875. * if (!error)
  876. * {
  877. * // Connect succeeded.
  878. * }
  879. * }
  880. *
  881. * ...
  882. *
  883. * boost::asio::ip::tcp::socket socket(my_context);
  884. * boost::asio::ip::tcp::endpoint endpoint(
  885. * boost::asio::ip::address::from_string("1.2.3.4"), 12345);
  886. * socket.async_connect(endpoint, connect_handler);
  887. * @endcode
  888. */
  889. template <
  890. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
  891. ConnectHandler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
  892. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ConnectHandler,
  893. void (boost::system::error_code))
  894. async_connect(const endpoint_type& peer_endpoint,
  895. BOOST_ASIO_MOVE_ARG(ConnectHandler) handler
  896. BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
  897. {
  898. boost::system::error_code open_ec;
  899. if (!is_open())
  900. {
  901. const protocol_type protocol = peer_endpoint.protocol();
  902. impl_.get_service().open(impl_.get_implementation(), protocol, open_ec);
  903. }
  904. return async_initiate<ConnectHandler, void (boost::system::error_code)>(
  905. initiate_async_connect(this), handler, peer_endpoint, open_ec);
  906. }
  907. /// Set an option on the socket.
  908. /**
  909. * This function is used to set an option on the socket.
  910. *
  911. * @param option The new option value to be set on the socket.
  912. *
  913. * @throws boost::system::system_error Thrown on failure.
  914. *
  915. * @sa SettableSocketOption @n
  916. * boost::asio::socket_base::broadcast @n
  917. * boost::asio::socket_base::do_not_route @n
  918. * boost::asio::socket_base::keep_alive @n
  919. * boost::asio::socket_base::linger @n
  920. * boost::asio::socket_base::receive_buffer_size @n
  921. * boost::asio::socket_base::receive_low_watermark @n
  922. * boost::asio::socket_base::reuse_address @n
  923. * boost::asio::socket_base::send_buffer_size @n
  924. * boost::asio::socket_base::send_low_watermark @n
  925. * boost::asio::ip::multicast::join_group @n
  926. * boost::asio::ip::multicast::leave_group @n
  927. * boost::asio::ip::multicast::enable_loopback @n
  928. * boost::asio::ip::multicast::outbound_interface @n
  929. * boost::asio::ip::multicast::hops @n
  930. * boost::asio::ip::tcp::no_delay
  931. *
  932. * @par Example
  933. * Setting the IPPROTO_TCP/TCP_NODELAY option:
  934. * @code
  935. * boost::asio::ip::tcp::socket socket(my_context);
  936. * ...
  937. * boost::asio::ip::tcp::no_delay option(true);
  938. * socket.set_option(option);
  939. * @endcode
  940. */
  941. template <typename SettableSocketOption>
  942. void set_option(const SettableSocketOption& option)
  943. {
  944. boost::system::error_code ec;
  945. impl_.get_service().set_option(impl_.get_implementation(), option, ec);
  946. boost::asio::detail::throw_error(ec, "set_option");
  947. }
  948. /// Set an option on the socket.
  949. /**
  950. * This function is used to set an option on the socket.
  951. *
  952. * @param option The new option value to be set on the socket.
  953. *
  954. * @param ec Set to indicate what error occurred, if any.
  955. *
  956. * @sa SettableSocketOption @n
  957. * boost::asio::socket_base::broadcast @n
  958. * boost::asio::socket_base::do_not_route @n
  959. * boost::asio::socket_base::keep_alive @n
  960. * boost::asio::socket_base::linger @n
  961. * boost::asio::socket_base::receive_buffer_size @n
  962. * boost::asio::socket_base::receive_low_watermark @n
  963. * boost::asio::socket_base::reuse_address @n
  964. * boost::asio::socket_base::send_buffer_size @n
  965. * boost::asio::socket_base::send_low_watermark @n
  966. * boost::asio::ip::multicast::join_group @n
  967. * boost::asio::ip::multicast::leave_group @n
  968. * boost::asio::ip::multicast::enable_loopback @n
  969. * boost::asio::ip::multicast::outbound_interface @n
  970. * boost::asio::ip::multicast::hops @n
  971. * boost::asio::ip::tcp::no_delay
  972. *
  973. * @par Example
  974. * Setting the IPPROTO_TCP/TCP_NODELAY option:
  975. * @code
  976. * boost::asio::ip::tcp::socket socket(my_context);
  977. * ...
  978. * boost::asio::ip::tcp::no_delay option(true);
  979. * boost::system::error_code ec;
  980. * socket.set_option(option, ec);
  981. * if (ec)
  982. * {
  983. * // An error occurred.
  984. * }
  985. * @endcode
  986. */
  987. template <typename SettableSocketOption>
  988. BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option,
  989. boost::system::error_code& ec)
  990. {
  991. impl_.get_service().set_option(impl_.get_implementation(), option, ec);
  992. BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
  993. }
  994. /// Get an option from the socket.
  995. /**
  996. * This function is used to get the current value of an option on the socket.
  997. *
  998. * @param option The option value to be obtained from the socket.
  999. *
  1000. * @throws boost::system::system_error Thrown on failure.
  1001. *
  1002. * @sa GettableSocketOption @n
  1003. * boost::asio::socket_base::broadcast @n
  1004. * boost::asio::socket_base::do_not_route @n
  1005. * boost::asio::socket_base::keep_alive @n
  1006. * boost::asio::socket_base::linger @n
  1007. * boost::asio::socket_base::receive_buffer_size @n
  1008. * boost::asio::socket_base::receive_low_watermark @n
  1009. * boost::asio::socket_base::reuse_address @n
  1010. * boost::asio::socket_base::send_buffer_size @n
  1011. * boost::asio::socket_base::send_low_watermark @n
  1012. * boost::asio::ip::multicast::join_group @n
  1013. * boost::asio::ip::multicast::leave_group @n
  1014. * boost::asio::ip::multicast::enable_loopback @n
  1015. * boost::asio::ip::multicast::outbound_interface @n
  1016. * boost::asio::ip::multicast::hops @n
  1017. * boost::asio::ip::tcp::no_delay
  1018. *
  1019. * @par Example
  1020. * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
  1021. * @code
  1022. * boost::asio::ip::tcp::socket socket(my_context);
  1023. * ...
  1024. * boost::asio::ip::tcp::socket::keep_alive option;
  1025. * socket.get_option(option);
  1026. * bool is_set = option.value();
  1027. * @endcode
  1028. */
  1029. template <typename GettableSocketOption>
  1030. void get_option(GettableSocketOption& option) const
  1031. {
  1032. boost::system::error_code ec;
  1033. impl_.get_service().get_option(impl_.get_implementation(), option, ec);
  1034. boost::asio::detail::throw_error(ec, "get_option");
  1035. }
  1036. /// Get an option from the socket.
  1037. /**
  1038. * This function is used to get the current value of an option on the socket.
  1039. *
  1040. * @param option The option value to be obtained from the socket.
  1041. *
  1042. * @param ec Set to indicate what error occurred, if any.
  1043. *
  1044. * @sa GettableSocketOption @n
  1045. * boost::asio::socket_base::broadcast @n
  1046. * boost::asio::socket_base::do_not_route @n
  1047. * boost::asio::socket_base::keep_alive @n
  1048. * boost::asio::socket_base::linger @n
  1049. * boost::asio::socket_base::receive_buffer_size @n
  1050. * boost::asio::socket_base::receive_low_watermark @n
  1051. * boost::asio::socket_base::reuse_address @n
  1052. * boost::asio::socket_base::send_buffer_size @n
  1053. * boost::asio::socket_base::send_low_watermark @n
  1054. * boost::asio::ip::multicast::join_group @n
  1055. * boost::asio::ip::multicast::leave_group @n
  1056. * boost::asio::ip::multicast::enable_loopback @n
  1057. * boost::asio::ip::multicast::outbound_interface @n
  1058. * boost::asio::ip::multicast::hops @n
  1059. * boost::asio::ip::tcp::no_delay
  1060. *
  1061. * @par Example
  1062. * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
  1063. * @code
  1064. * boost::asio::ip::tcp::socket socket(my_context);
  1065. * ...
  1066. * boost::asio::ip::tcp::socket::keep_alive option;
  1067. * boost::system::error_code ec;
  1068. * socket.get_option(option, ec);
  1069. * if (ec)
  1070. * {
  1071. * // An error occurred.
  1072. * }
  1073. * bool is_set = option.value();
  1074. * @endcode
  1075. */
  1076. template <typename GettableSocketOption>
  1077. BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option,
  1078. boost::system::error_code& ec) const
  1079. {
  1080. impl_.get_service().get_option(impl_.get_implementation(), option, ec);
  1081. BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
  1082. }
  1083. /// Perform an IO control command on the socket.
  1084. /**
  1085. * This function is used to execute an IO control command on the socket.
  1086. *
  1087. * @param command The IO control command to be performed on the socket.
  1088. *
  1089. * @throws boost::system::system_error Thrown on failure.
  1090. *
  1091. * @sa IoControlCommand @n
  1092. * boost::asio::socket_base::bytes_readable @n
  1093. * boost::asio::socket_base::non_blocking_io
  1094. *
  1095. * @par Example
  1096. * Getting the number of bytes ready to read:
  1097. * @code
  1098. * boost::asio::ip::tcp::socket socket(my_context);
  1099. * ...
  1100. * boost::asio::ip::tcp::socket::bytes_readable command;
  1101. * socket.io_control(command);
  1102. * std::size_t bytes_readable = command.get();
  1103. * @endcode
  1104. */
  1105. template <typename IoControlCommand>
  1106. void io_control(IoControlCommand& command)
  1107. {
  1108. boost::system::error_code ec;
  1109. impl_.get_service().io_control(impl_.get_implementation(), command, ec);
  1110. boost::asio::detail::throw_error(ec, "io_control");
  1111. }
  1112. /// Perform an IO control command on the socket.
  1113. /**
  1114. * This function is used to execute an IO control command on the socket.
  1115. *
  1116. * @param command The IO control command to be performed on the socket.
  1117. *
  1118. * @param ec Set to indicate what error occurred, if any.
  1119. *
  1120. * @sa IoControlCommand @n
  1121. * boost::asio::socket_base::bytes_readable @n
  1122. * boost::asio::socket_base::non_blocking_io
  1123. *
  1124. * @par Example
  1125. * Getting the number of bytes ready to read:
  1126. * @code
  1127. * boost::asio::ip::tcp::socket socket(my_context);
  1128. * ...
  1129. * boost::asio::ip::tcp::socket::bytes_readable command;
  1130. * boost::system::error_code ec;
  1131. * socket.io_control(command, ec);
  1132. * if (ec)
  1133. * {
  1134. * // An error occurred.
  1135. * }
  1136. * std::size_t bytes_readable = command.get();
  1137. * @endcode
  1138. */
  1139. template <typename IoControlCommand>
  1140. BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command,
  1141. boost::system::error_code& ec)
  1142. {
  1143. impl_.get_service().io_control(impl_.get_implementation(), command, ec);
  1144. BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
  1145. }
  1146. /// Gets the non-blocking mode of the socket.
  1147. /**
  1148. * @returns @c true if the socket's synchronous operations will fail with
  1149. * boost::asio::error::would_block if they are unable to perform the requested
  1150. * operation immediately. If @c false, synchronous operations will block
  1151. * until complete.
  1152. *
  1153. * @note The non-blocking mode has no effect on the behaviour of asynchronous
  1154. * operations. Asynchronous operations will never fail with the error
  1155. * boost::asio::error::would_block.
  1156. */
  1157. bool non_blocking() const
  1158. {
  1159. return impl_.get_service().non_blocking(impl_.get_implementation());
  1160. }
  1161. /// Sets the non-blocking mode of the socket.
  1162. /**
  1163. * @param mode If @c true, the socket's synchronous operations will fail with
  1164. * boost::asio::error::would_block if they are unable to perform the requested
  1165. * operation immediately. If @c false, synchronous operations will block
  1166. * until complete.
  1167. *
  1168. * @throws boost::system::system_error Thrown on failure.
  1169. *
  1170. * @note The non-blocking mode has no effect on the behaviour of asynchronous
  1171. * operations. Asynchronous operations will never fail with the error
  1172. * boost::asio::error::would_block.
  1173. */
  1174. void non_blocking(bool mode)
  1175. {
  1176. boost::system::error_code ec;
  1177. impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec);
  1178. boost::asio::detail::throw_error(ec, "non_blocking");
  1179. }
  1180. /// Sets the non-blocking mode of the socket.
  1181. /**
  1182. * @param mode If @c true, the socket's synchronous operations will fail with
  1183. * boost::asio::error::would_block if they are unable to perform the requested
  1184. * operation immediately. If @c false, synchronous operations will block
  1185. * until complete.
  1186. *
  1187. * @param ec Set to indicate what error occurred, if any.
  1188. *
  1189. * @note The non-blocking mode has no effect on the behaviour of asynchronous
  1190. * operations. Asynchronous operations will never fail with the error
  1191. * boost::asio::error::would_block.
  1192. */
  1193. BOOST_ASIO_SYNC_OP_VOID non_blocking(
  1194. bool mode, boost::system::error_code& ec)
  1195. {
  1196. impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec);
  1197. BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
  1198. }
  1199. /// Gets the non-blocking mode of the native socket implementation.
  1200. /**
  1201. * This function is used to retrieve the non-blocking mode of the underlying
  1202. * native socket. This mode has no effect on the behaviour of the socket
  1203. * object's synchronous operations.
  1204. *
  1205. * @returns @c true if the underlying socket is in non-blocking mode and
  1206. * direct system calls may fail with boost::asio::error::would_block (or the
  1207. * equivalent system error).
  1208. *
  1209. * @note The current non-blocking mode is cached by the socket object.
  1210. * Consequently, the return value may be incorrect if the non-blocking mode
  1211. * was set directly on the native socket.
  1212. *
  1213. * @par Example
  1214. * This function is intended to allow the encapsulation of arbitrary
  1215. * non-blocking system calls as asynchronous operations, in a way that is
  1216. * transparent to the user of the socket object. The following example
  1217. * illustrates how Linux's @c sendfile system call might be encapsulated:
  1218. * @code template <typename Handler>
  1219. * struct sendfile_op
  1220. * {
  1221. * tcp::socket& sock_;
  1222. * int fd_;
  1223. * Handler handler_;
  1224. * off_t offset_;
  1225. * std::size_t total_bytes_transferred_;
  1226. *
  1227. * // Function call operator meeting WriteHandler requirements.
  1228. * // Used as the handler for the async_write_some operation.
  1229. * void operator()(boost::system::error_code ec, std::size_t)
  1230. * {
  1231. * // Put the underlying socket into non-blocking mode.
  1232. * if (!ec)
  1233. * if (!sock_.native_non_blocking())
  1234. * sock_.native_non_blocking(true, ec);
  1235. *
  1236. * if (!ec)
  1237. * {
  1238. * for (;;)
  1239. * {
  1240. * // Try the system call.
  1241. * errno = 0;
  1242. * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
  1243. * ec = boost::system::error_code(n < 0 ? errno : 0,
  1244. * boost::asio::error::get_system_category());
  1245. * total_bytes_transferred_ += ec ? 0 : n;
  1246. *
  1247. * // Retry operation immediately if interrupted by signal.
  1248. * if (ec == boost::asio::error::interrupted)
  1249. * continue;
  1250. *
  1251. * // Check if we need to run the operation again.
  1252. * if (ec == boost::asio::error::would_block
  1253. * || ec == boost::asio::error::try_again)
  1254. * {
  1255. * // We have to wait for the socket to become ready again.
  1256. * sock_.async_wait(tcp::socket::wait_write, *this);
  1257. * return;
  1258. * }
  1259. *
  1260. * if (ec || n == 0)
  1261. * {
  1262. * // An error occurred, or we have reached the end of the file.
  1263. * // Either way we must exit the loop so we can call the handler.
  1264. * break;
  1265. * }
  1266. *
  1267. * // Loop around to try calling sendfile again.
  1268. * }
  1269. * }
  1270. *
  1271. * // Pass result back to user's handler.
  1272. * handler_(ec, total_bytes_transferred_);
  1273. * }
  1274. * };
  1275. *
  1276. * template <typename Handler>
  1277. * void async_sendfile(tcp::socket& sock, int fd, Handler h)
  1278. * {
  1279. * sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
  1280. * sock.async_wait(tcp::socket::wait_write, op);
  1281. * } @endcode
  1282. */
  1283. bool native_non_blocking() const
  1284. {
  1285. return impl_.get_service().native_non_blocking(impl_.get_implementation());
  1286. }
  1287. /// Sets the non-blocking mode of the native socket implementation.
  1288. /**
  1289. * This function is used to modify the non-blocking mode of the underlying
  1290. * native socket. It has no effect on the behaviour of the socket object's
  1291. * synchronous operations.
  1292. *
  1293. * @param mode If @c true, the underlying socket is put into non-blocking
  1294. * mode and direct system calls may fail with boost::asio::error::would_block
  1295. * (or the equivalent system error).
  1296. *
  1297. * @throws boost::system::system_error Thrown on failure. If the @c mode is
  1298. * @c false, but the current value of @c non_blocking() is @c true, this
  1299. * function fails with boost::asio::error::invalid_argument, as the
  1300. * combination does not make sense.
  1301. *
  1302. * @par Example
  1303. * This function is intended to allow the encapsulation of arbitrary
  1304. * non-blocking system calls as asynchronous operations, in a way that is
  1305. * transparent to the user of the socket object. The following example
  1306. * illustrates how Linux's @c sendfile system call might be encapsulated:
  1307. * @code template <typename Handler>
  1308. * struct sendfile_op
  1309. * {
  1310. * tcp::socket& sock_;
  1311. * int fd_;
  1312. * Handler handler_;
  1313. * off_t offset_;
  1314. * std::size_t total_bytes_transferred_;
  1315. *
  1316. * // Function call operator meeting WriteHandler requirements.
  1317. * // Used as the handler for the async_write_some operation.
  1318. * void operator()(boost::system::error_code ec, std::size_t)
  1319. * {
  1320. * // Put the underlying socket into non-blocking mode.
  1321. * if (!ec)
  1322. * if (!sock_.native_non_blocking())
  1323. * sock_.native_non_blocking(true, ec);
  1324. *
  1325. * if (!ec)
  1326. * {
  1327. * for (;;)
  1328. * {
  1329. * // Try the system call.
  1330. * errno = 0;
  1331. * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
  1332. * ec = boost::system::error_code(n < 0 ? errno : 0,
  1333. * boost::asio::error::get_system_category());
  1334. * total_bytes_transferred_ += ec ? 0 : n;
  1335. *
  1336. * // Retry operation immediately if interrupted by signal.
  1337. * if (ec == boost::asio::error::interrupted)
  1338. * continue;
  1339. *
  1340. * // Check if we need to run the operation again.
  1341. * if (ec == boost::asio::error::would_block
  1342. * || ec == boost::asio::error::try_again)
  1343. * {
  1344. * // We have to wait for the socket to become ready again.
  1345. * sock_.async_wait(tcp::socket::wait_write, *this);
  1346. * return;
  1347. * }
  1348. *
  1349. * if (ec || n == 0)
  1350. * {
  1351. * // An error occurred, or we have reached the end of the file.
  1352. * // Either way we must exit the loop so we can call the handler.
  1353. * break;
  1354. * }
  1355. *
  1356. * // Loop around to try calling sendfile again.
  1357. * }
  1358. * }
  1359. *
  1360. * // Pass result back to user's handler.
  1361. * handler_(ec, total_bytes_transferred_);
  1362. * }
  1363. * };
  1364. *
  1365. * template <typename Handler>
  1366. * void async_sendfile(tcp::socket& sock, int fd, Handler h)
  1367. * {
  1368. * sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
  1369. * sock.async_wait(tcp::socket::wait_write, op);
  1370. * } @endcode
  1371. */
  1372. void native_non_blocking(bool mode)
  1373. {
  1374. boost::system::error_code ec;
  1375. impl_.get_service().native_non_blocking(
  1376. impl_.get_implementation(), mode, ec);
  1377. boost::asio::detail::throw_error(ec, "native_non_blocking");
  1378. }
  1379. /// Sets the non-blocking mode of the native socket implementation.
  1380. /**
  1381. * This function is used to modify the non-blocking mode of the underlying
  1382. * native socket. It has no effect on the behaviour of the socket object's
  1383. * synchronous operations.
  1384. *
  1385. * @param mode If @c true, the underlying socket is put into non-blocking
  1386. * mode and direct system calls may fail with boost::asio::error::would_block
  1387. * (or the equivalent system error).
  1388. *
  1389. * @param ec Set to indicate what error occurred, if any. If the @c mode is
  1390. * @c false, but the current value of @c non_blocking() is @c true, this
  1391. * function fails with boost::asio::error::invalid_argument, as the
  1392. * combination does not make sense.
  1393. *
  1394. * @par Example
  1395. * This function is intended to allow the encapsulation of arbitrary
  1396. * non-blocking system calls as asynchronous operations, in a way that is
  1397. * transparent to the user of the socket object. The following example
  1398. * illustrates how Linux's @c sendfile system call might be encapsulated:
  1399. * @code template <typename Handler>
  1400. * struct sendfile_op
  1401. * {
  1402. * tcp::socket& sock_;
  1403. * int fd_;
  1404. * Handler handler_;
  1405. * off_t offset_;
  1406. * std::size_t total_bytes_transferred_;
  1407. *
  1408. * // Function call operator meeting WriteHandler requirements.
  1409. * // Used as the handler for the async_write_some operation.
  1410. * void operator()(boost::system::error_code ec, std::size_t)
  1411. * {
  1412. * // Put the underlying socket into non-blocking mode.
  1413. * if (!ec)
  1414. * if (!sock_.native_non_blocking())
  1415. * sock_.native_non_blocking(true, ec);
  1416. *
  1417. * if (!ec)
  1418. * {
  1419. * for (;;)
  1420. * {
  1421. * // Try the system call.
  1422. * errno = 0;
  1423. * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
  1424. * ec = boost::system::error_code(n < 0 ? errno : 0,
  1425. * boost::asio::error::get_system_category());
  1426. * total_bytes_transferred_ += ec ? 0 : n;
  1427. *
  1428. * // Retry operation immediately if interrupted by signal.
  1429. * if (ec == boost::asio::error::interrupted)
  1430. * continue;
  1431. *
  1432. * // Check if we need to run the operation again.
  1433. * if (ec == boost::asio::error::would_block
  1434. * || ec == boost::asio::error::try_again)
  1435. * {
  1436. * // We have to wait for the socket to become ready again.
  1437. * sock_.async_wait(tcp::socket::wait_write, *this);
  1438. * return;
  1439. * }
  1440. *
  1441. * if (ec || n == 0)
  1442. * {
  1443. * // An error occurred, or we have reached the end of the file.
  1444. * // Either way we must exit the loop so we can call the handler.
  1445. * break;
  1446. * }
  1447. *
  1448. * // Loop around to try calling sendfile again.
  1449. * }
  1450. * }
  1451. *
  1452. * // Pass result back to user's handler.
  1453. * handler_(ec, total_bytes_transferred_);
  1454. * }
  1455. * };
  1456. *
  1457. * template <typename Handler>
  1458. * void async_sendfile(tcp::socket& sock, int fd, Handler h)
  1459. * {
  1460. * sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
  1461. * sock.async_wait(tcp::socket::wait_write, op);
  1462. * } @endcode
  1463. */
  1464. BOOST_ASIO_SYNC_OP_VOID native_non_blocking(
  1465. bool mode, boost::system::error_code& ec)
  1466. {
  1467. impl_.get_service().native_non_blocking(
  1468. impl_.get_implementation(), mode, ec);
  1469. BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
  1470. }
  1471. /// Get the local endpoint of the socket.
  1472. /**
  1473. * This function is used to obtain the locally bound endpoint of the socket.
  1474. *
  1475. * @returns An object that represents the local endpoint of the socket.
  1476. *
  1477. * @throws boost::system::system_error Thrown on failure.
  1478. *
  1479. * @par Example
  1480. * @code
  1481. * boost::asio::ip::tcp::socket socket(my_context);
  1482. * ...
  1483. * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint();
  1484. * @endcode
  1485. */
  1486. endpoint_type local_endpoint() const
  1487. {
  1488. boost::system::error_code ec;
  1489. endpoint_type ep = impl_.get_service().local_endpoint(
  1490. impl_.get_implementation(), ec);
  1491. boost::asio::detail::throw_error(ec, "local_endpoint");
  1492. return ep;
  1493. }
  1494. /// Get the local endpoint of the socket.
  1495. /**
  1496. * This function is used to obtain the locally bound endpoint of the socket.
  1497. *
  1498. * @param ec Set to indicate what error occurred, if any.
  1499. *
  1500. * @returns An object that represents the local endpoint of the socket.
  1501. * Returns a default-constructed endpoint object if an error occurred.
  1502. *
  1503. * @par Example
  1504. * @code
  1505. * boost::asio::ip::tcp::socket socket(my_context);
  1506. * ...
  1507. * boost::system::error_code ec;
  1508. * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec);
  1509. * if (ec)
  1510. * {
  1511. * // An error occurred.
  1512. * }
  1513. * @endcode
  1514. */
  1515. endpoint_type local_endpoint(boost::system::error_code& ec) const
  1516. {
  1517. return impl_.get_service().local_endpoint(impl_.get_implementation(), ec);
  1518. }
  1519. /// Get the remote endpoint of the socket.
  1520. /**
  1521. * This function is used to obtain the remote endpoint of the socket.
  1522. *
  1523. * @returns An object that represents the remote endpoint of the socket.
  1524. *
  1525. * @throws boost::system::system_error Thrown on failure.
  1526. *
  1527. * @par Example
  1528. * @code
  1529. * boost::asio::ip::tcp::socket socket(my_context);
  1530. * ...
  1531. * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint();
  1532. * @endcode
  1533. */
  1534. endpoint_type remote_endpoint() const
  1535. {
  1536. boost::system::error_code ec;
  1537. endpoint_type ep = impl_.get_service().remote_endpoint(
  1538. impl_.get_implementation(), ec);
  1539. boost::asio::detail::throw_error(ec, "remote_endpoint");
  1540. return ep;
  1541. }
  1542. /// Get the remote endpoint of the socket.
  1543. /**
  1544. * This function is used to obtain the remote endpoint of the socket.
  1545. *
  1546. * @param ec Set to indicate what error occurred, if any.
  1547. *
  1548. * @returns An object that represents the remote endpoint of the socket.
  1549. * Returns a default-constructed endpoint object if an error occurred.
  1550. *
  1551. * @par Example
  1552. * @code
  1553. * boost::asio::ip::tcp::socket socket(my_context);
  1554. * ...
  1555. * boost::system::error_code ec;
  1556. * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec);
  1557. * if (ec)
  1558. * {
  1559. * // An error occurred.
  1560. * }
  1561. * @endcode
  1562. */
  1563. endpoint_type remote_endpoint(boost::system::error_code& ec) const
  1564. {
  1565. return impl_.get_service().remote_endpoint(impl_.get_implementation(), ec);
  1566. }
  1567. /// Disable sends or receives on the socket.
  1568. /**
  1569. * This function is used to disable send operations, receive operations, or
  1570. * both.
  1571. *
  1572. * @param what Determines what types of operation will no longer be allowed.
  1573. *
  1574. * @throws boost::system::system_error Thrown on failure.
  1575. *
  1576. * @par Example
  1577. * Shutting down the send side of the socket:
  1578. * @code
  1579. * boost::asio::ip::tcp::socket socket(my_context);
  1580. * ...
  1581. * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send);
  1582. * @endcode
  1583. */
  1584. void shutdown(shutdown_type what)
  1585. {
  1586. boost::system::error_code ec;
  1587. impl_.get_service().shutdown(impl_.get_implementation(), what, ec);
  1588. boost::asio::detail::throw_error(ec, "shutdown");
  1589. }
  1590. /// Disable sends or receives on the socket.
  1591. /**
  1592. * This function is used to disable send operations, receive operations, or
  1593. * both.
  1594. *
  1595. * @param what Determines what types of operation will no longer be allowed.
  1596. *
  1597. * @param ec Set to indicate what error occurred, if any.
  1598. *
  1599. * @par Example
  1600. * Shutting down the send side of the socket:
  1601. * @code
  1602. * boost::asio::ip::tcp::socket socket(my_context);
  1603. * ...
  1604. * boost::system::error_code ec;
  1605. * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec);
  1606. * if (ec)
  1607. * {
  1608. * // An error occurred.
  1609. * }
  1610. * @endcode
  1611. */
  1612. BOOST_ASIO_SYNC_OP_VOID shutdown(shutdown_type what,
  1613. boost::system::error_code& ec)
  1614. {
  1615. impl_.get_service().shutdown(impl_.get_implementation(), what, ec);
  1616. BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
  1617. }
  1618. /// Wait for the socket to become ready to read, ready to write, or to have
  1619. /// pending error conditions.
  1620. /**
  1621. * This function is used to perform a blocking wait for a socket to enter
  1622. * a ready to read, write or error condition state.
  1623. *
  1624. * @param w Specifies the desired socket state.
  1625. *
  1626. * @par Example
  1627. * Waiting for a socket to become readable.
  1628. * @code
  1629. * boost::asio::ip::tcp::socket socket(my_context);
  1630. * ...
  1631. * socket.wait(boost::asio::ip::tcp::socket::wait_read);
  1632. * @endcode
  1633. */
  1634. void wait(wait_type w)
  1635. {
  1636. boost::system::error_code ec;
  1637. impl_.get_service().wait(impl_.get_implementation(), w, ec);
  1638. boost::asio::detail::throw_error(ec, "wait");
  1639. }
  1640. /// Wait for the socket to become ready to read, ready to write, or to have
  1641. /// pending error conditions.
  1642. /**
  1643. * This function is used to perform a blocking wait for a socket to enter
  1644. * a ready to read, write or error condition state.
  1645. *
  1646. * @param w Specifies the desired socket state.
  1647. *
  1648. * @param ec Set to indicate what error occurred, if any.
  1649. *
  1650. * @par Example
  1651. * Waiting for a socket to become readable.
  1652. * @code
  1653. * boost::asio::ip::tcp::socket socket(my_context);
  1654. * ...
  1655. * boost::system::error_code ec;
  1656. * socket.wait(boost::asio::ip::tcp::socket::wait_read, ec);
  1657. * @endcode
  1658. */
  1659. BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec)
  1660. {
  1661. impl_.get_service().wait(impl_.get_implementation(), w, ec);
  1662. BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
  1663. }
  1664. /// Asynchronously wait for the socket to become ready to read, ready to
  1665. /// write, or to have pending error conditions.
  1666. /**
  1667. * This function is used to perform an asynchronous wait for a socket to enter
  1668. * a ready to read, write or error condition state.
  1669. *
  1670. * @param w Specifies the desired socket state.
  1671. *
  1672. * @param handler The handler to be called when the wait operation completes.
  1673. * Copies will be made of the handler as required. The function signature of
  1674. * the handler must be:
  1675. * @code void handler(
  1676. * const boost::system::error_code& error // Result of operation
  1677. * ); @endcode
  1678. * Regardless of whether the asynchronous operation completes immediately or
  1679. * not, the handler will not be invoked from within this function. On
  1680. * immediate completion, invocation of the handler will be performed in a
  1681. * manner equivalent to using boost::asio::post().
  1682. *
  1683. * @par Example
  1684. * @code
  1685. * void wait_handler(const boost::system::error_code& error)
  1686. * {
  1687. * if (!error)
  1688. * {
  1689. * // Wait succeeded.
  1690. * }
  1691. * }
  1692. *
  1693. * ...
  1694. *
  1695. * boost::asio::ip::tcp::socket socket(my_context);
  1696. * ...
  1697. * socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler);
  1698. * @endcode
  1699. */
  1700. template <
  1701. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
  1702. WaitHandler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
  1703. BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WaitHandler,
  1704. void (boost::system::error_code))
  1705. async_wait(wait_type w,
  1706. BOOST_ASIO_MOVE_ARG(WaitHandler) handler
  1707. BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
  1708. {
  1709. return async_initiate<WaitHandler, void (boost::system::error_code)>(
  1710. initiate_async_wait(this), handler, w);
  1711. }
  1712. protected:
  1713. /// Protected destructor to prevent deletion through this type.
  1714. /**
  1715. * This function destroys the socket, cancelling any outstanding asynchronous
  1716. * operations associated with the socket as if by calling @c cancel.
  1717. */
  1718. ~basic_socket()
  1719. {
  1720. }
  1721. #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
  1722. detail::io_object_impl<
  1723. detail::null_socket_service<Protocol>, Executor> impl_;
  1724. #elif defined(BOOST_ASIO_HAS_IOCP)
  1725. detail::io_object_impl<
  1726. detail::win_iocp_socket_service<Protocol>, Executor> impl_;
  1727. #else
  1728. detail::io_object_impl<
  1729. detail::reactive_socket_service<Protocol>, Executor> impl_;
  1730. #endif
  1731. private:
  1732. // Disallow copying and assignment.
  1733. basic_socket(const basic_socket&) BOOST_ASIO_DELETED;
  1734. basic_socket& operator=(const basic_socket&) BOOST_ASIO_DELETED;
  1735. class initiate_async_connect
  1736. {
  1737. public:
  1738. typedef Executor executor_type;
  1739. explicit initiate_async_connect(basic_socket* self)
  1740. : self_(self)
  1741. {
  1742. }
  1743. executor_type get_executor() const BOOST_ASIO_NOEXCEPT
  1744. {
  1745. return self_->get_executor();
  1746. }
  1747. template <typename ConnectHandler>
  1748. void operator()(BOOST_ASIO_MOVE_ARG(ConnectHandler) handler,
  1749. const endpoint_type& peer_endpoint,
  1750. const boost::system::error_code& open_ec) const
  1751. {
  1752. // If you get an error on the following line it means that your handler
  1753. // does not meet the documented type requirements for a ConnectHandler.
  1754. BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check;
  1755. if (open_ec)
  1756. {
  1757. boost::asio::post(self_->impl_.get_executor(),
  1758. boost::asio::detail::bind_handler(
  1759. BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler), open_ec));
  1760. }
  1761. else
  1762. {
  1763. detail::non_const_lvalue<ConnectHandler> handler2(handler);
  1764. self_->impl_.get_service().async_connect(
  1765. self_->impl_.get_implementation(), peer_endpoint,
  1766. handler2.value, self_->impl_.get_implementation_executor());
  1767. }
  1768. }
  1769. private:
  1770. basic_socket* self_;
  1771. };
  1772. class initiate_async_wait
  1773. {
  1774. public:
  1775. typedef Executor executor_type;
  1776. explicit initiate_async_wait(basic_socket* self)
  1777. : self_(self)
  1778. {
  1779. }
  1780. executor_type get_executor() const BOOST_ASIO_NOEXCEPT
  1781. {
  1782. return self_->get_executor();
  1783. }
  1784. template <typename WaitHandler>
  1785. void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, wait_type w) const
  1786. {
  1787. // If you get an error on the following line it means that your handler
  1788. // does not meet the documented type requirements for a WaitHandler.
  1789. BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
  1790. detail::non_const_lvalue<WaitHandler> handler2(handler);
  1791. self_->impl_.get_service().async_wait(
  1792. self_->impl_.get_implementation(), w, handler2.value,
  1793. self_->impl_.get_implementation_executor());
  1794. }
  1795. private:
  1796. basic_socket* self_;
  1797. };
  1798. };
  1799. } // namespace asio
  1800. } // namespace boost
  1801. #include <boost/asio/detail/pop_options.hpp>
  1802. #endif // BOOST_ASIO_BASIC_SOCKET_HPP