basic_socket.hpp 64 KB

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