basic_socket.hpp 63 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859
  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)
  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 <typename ConnectHandler>
  890. BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler,
  891. void (boost::system::error_code))
  892. async_connect(const endpoint_type& peer_endpoint,
  893. BOOST_ASIO_MOVE_ARG(ConnectHandler) handler)
  894. {
  895. boost::system::error_code open_ec;
  896. if (!is_open())
  897. {
  898. const protocol_type protocol = peer_endpoint.protocol();
  899. impl_.get_service().open(impl_.get_implementation(), protocol, open_ec);
  900. }
  901. return async_initiate<ConnectHandler, void (boost::system::error_code)>(
  902. initiate_async_connect(), handler, this, peer_endpoint, open_ec);
  903. }
  904. /// Set an option on the socket.
  905. /**
  906. * This function is used to set an option on the socket.
  907. *
  908. * @param option The new option value to be set on the socket.
  909. *
  910. * @throws boost::system::system_error Thrown on failure.
  911. *
  912. * @sa SettableSocketOption @n
  913. * boost::asio::socket_base::broadcast @n
  914. * boost::asio::socket_base::do_not_route @n
  915. * boost::asio::socket_base::keep_alive @n
  916. * boost::asio::socket_base::linger @n
  917. * boost::asio::socket_base::receive_buffer_size @n
  918. * boost::asio::socket_base::receive_low_watermark @n
  919. * boost::asio::socket_base::reuse_address @n
  920. * boost::asio::socket_base::send_buffer_size @n
  921. * boost::asio::socket_base::send_low_watermark @n
  922. * boost::asio::ip::multicast::join_group @n
  923. * boost::asio::ip::multicast::leave_group @n
  924. * boost::asio::ip::multicast::enable_loopback @n
  925. * boost::asio::ip::multicast::outbound_interface @n
  926. * boost::asio::ip::multicast::hops @n
  927. * boost::asio::ip::tcp::no_delay
  928. *
  929. * @par Example
  930. * Setting the IPPROTO_TCP/TCP_NODELAY option:
  931. * @code
  932. * boost::asio::ip::tcp::socket socket(my_context);
  933. * ...
  934. * boost::asio::ip::tcp::no_delay option(true);
  935. * socket.set_option(option);
  936. * @endcode
  937. */
  938. template <typename SettableSocketOption>
  939. void set_option(const SettableSocketOption& option)
  940. {
  941. boost::system::error_code ec;
  942. impl_.get_service().set_option(impl_.get_implementation(), option, ec);
  943. boost::asio::detail::throw_error(ec, "set_option");
  944. }
  945. /// Set an option on the socket.
  946. /**
  947. * This function is used to set an option on the socket.
  948. *
  949. * @param option The new option value to be set on the socket.
  950. *
  951. * @param ec Set to indicate what error occurred, if any.
  952. *
  953. * @sa SettableSocketOption @n
  954. * boost::asio::socket_base::broadcast @n
  955. * boost::asio::socket_base::do_not_route @n
  956. * boost::asio::socket_base::keep_alive @n
  957. * boost::asio::socket_base::linger @n
  958. * boost::asio::socket_base::receive_buffer_size @n
  959. * boost::asio::socket_base::receive_low_watermark @n
  960. * boost::asio::socket_base::reuse_address @n
  961. * boost::asio::socket_base::send_buffer_size @n
  962. * boost::asio::socket_base::send_low_watermark @n
  963. * boost::asio::ip::multicast::join_group @n
  964. * boost::asio::ip::multicast::leave_group @n
  965. * boost::asio::ip::multicast::enable_loopback @n
  966. * boost::asio::ip::multicast::outbound_interface @n
  967. * boost::asio::ip::multicast::hops @n
  968. * boost::asio::ip::tcp::no_delay
  969. *
  970. * @par Example
  971. * Setting the IPPROTO_TCP/TCP_NODELAY option:
  972. * @code
  973. * boost::asio::ip::tcp::socket socket(my_context);
  974. * ...
  975. * boost::asio::ip::tcp::no_delay option(true);
  976. * boost::system::error_code ec;
  977. * socket.set_option(option, ec);
  978. * if (ec)
  979. * {
  980. * // An error occurred.
  981. * }
  982. * @endcode
  983. */
  984. template <typename SettableSocketOption>
  985. BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option,
  986. boost::system::error_code& ec)
  987. {
  988. impl_.get_service().set_option(impl_.get_implementation(), option, ec);
  989. BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
  990. }
  991. /// Get an option from the socket.
  992. /**
  993. * This function is used to get the current value of an option on the socket.
  994. *
  995. * @param option The option value to be obtained from the socket.
  996. *
  997. * @throws boost::system::system_error Thrown on failure.
  998. *
  999. * @sa GettableSocketOption @n
  1000. * boost::asio::socket_base::broadcast @n
  1001. * boost::asio::socket_base::do_not_route @n
  1002. * boost::asio::socket_base::keep_alive @n
  1003. * boost::asio::socket_base::linger @n
  1004. * boost::asio::socket_base::receive_buffer_size @n
  1005. * boost::asio::socket_base::receive_low_watermark @n
  1006. * boost::asio::socket_base::reuse_address @n
  1007. * boost::asio::socket_base::send_buffer_size @n
  1008. * boost::asio::socket_base::send_low_watermark @n
  1009. * boost::asio::ip::multicast::join_group @n
  1010. * boost::asio::ip::multicast::leave_group @n
  1011. * boost::asio::ip::multicast::enable_loopback @n
  1012. * boost::asio::ip::multicast::outbound_interface @n
  1013. * boost::asio::ip::multicast::hops @n
  1014. * boost::asio::ip::tcp::no_delay
  1015. *
  1016. * @par Example
  1017. * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
  1018. * @code
  1019. * boost::asio::ip::tcp::socket socket(my_context);
  1020. * ...
  1021. * boost::asio::ip::tcp::socket::keep_alive option;
  1022. * socket.get_option(option);
  1023. * bool is_set = option.value();
  1024. * @endcode
  1025. */
  1026. template <typename GettableSocketOption>
  1027. void get_option(GettableSocketOption& option) const
  1028. {
  1029. boost::system::error_code ec;
  1030. impl_.get_service().get_option(impl_.get_implementation(), option, ec);
  1031. boost::asio::detail::throw_error(ec, "get_option");
  1032. }
  1033. /// Get an option from the socket.
  1034. /**
  1035. * This function is used to get the current value of an option on the socket.
  1036. *
  1037. * @param option The option value to be obtained from the socket.
  1038. *
  1039. * @param ec Set to indicate what error occurred, if any.
  1040. *
  1041. * @sa GettableSocketOption @n
  1042. * boost::asio::socket_base::broadcast @n
  1043. * boost::asio::socket_base::do_not_route @n
  1044. * boost::asio::socket_base::keep_alive @n
  1045. * boost::asio::socket_base::linger @n
  1046. * boost::asio::socket_base::receive_buffer_size @n
  1047. * boost::asio::socket_base::receive_low_watermark @n
  1048. * boost::asio::socket_base::reuse_address @n
  1049. * boost::asio::socket_base::send_buffer_size @n
  1050. * boost::asio::socket_base::send_low_watermark @n
  1051. * boost::asio::ip::multicast::join_group @n
  1052. * boost::asio::ip::multicast::leave_group @n
  1053. * boost::asio::ip::multicast::enable_loopback @n
  1054. * boost::asio::ip::multicast::outbound_interface @n
  1055. * boost::asio::ip::multicast::hops @n
  1056. * boost::asio::ip::tcp::no_delay
  1057. *
  1058. * @par Example
  1059. * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
  1060. * @code
  1061. * boost::asio::ip::tcp::socket socket(my_context);
  1062. * ...
  1063. * boost::asio::ip::tcp::socket::keep_alive option;
  1064. * boost::system::error_code ec;
  1065. * socket.get_option(option, ec);
  1066. * if (ec)
  1067. * {
  1068. * // An error occurred.
  1069. * }
  1070. * bool is_set = option.value();
  1071. * @endcode
  1072. */
  1073. template <typename GettableSocketOption>
  1074. BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option,
  1075. boost::system::error_code& ec) const
  1076. {
  1077. impl_.get_service().get_option(impl_.get_implementation(), option, ec);
  1078. BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
  1079. }
  1080. /// Perform an IO control command on the socket.
  1081. /**
  1082. * This function is used to execute an IO control command on the socket.
  1083. *
  1084. * @param command The IO control command to be performed on the socket.
  1085. *
  1086. * @throws boost::system::system_error Thrown on failure.
  1087. *
  1088. * @sa IoControlCommand @n
  1089. * boost::asio::socket_base::bytes_readable @n
  1090. * boost::asio::socket_base::non_blocking_io
  1091. *
  1092. * @par Example
  1093. * Getting the number of bytes ready to read:
  1094. * @code
  1095. * boost::asio::ip::tcp::socket socket(my_context);
  1096. * ...
  1097. * boost::asio::ip::tcp::socket::bytes_readable command;
  1098. * socket.io_control(command);
  1099. * std::size_t bytes_readable = command.get();
  1100. * @endcode
  1101. */
  1102. template <typename IoControlCommand>
  1103. void io_control(IoControlCommand& command)
  1104. {
  1105. boost::system::error_code ec;
  1106. impl_.get_service().io_control(impl_.get_implementation(), command, ec);
  1107. boost::asio::detail::throw_error(ec, "io_control");
  1108. }
  1109. /// Perform an IO control command on the socket.
  1110. /**
  1111. * This function is used to execute an IO control command on the socket.
  1112. *
  1113. * @param command The IO control command to be performed on the socket.
  1114. *
  1115. * @param ec Set to indicate what error occurred, if any.
  1116. *
  1117. * @sa IoControlCommand @n
  1118. * boost::asio::socket_base::bytes_readable @n
  1119. * boost::asio::socket_base::non_blocking_io
  1120. *
  1121. * @par Example
  1122. * Getting the number of bytes ready to read:
  1123. * @code
  1124. * boost::asio::ip::tcp::socket socket(my_context);
  1125. * ...
  1126. * boost::asio::ip::tcp::socket::bytes_readable command;
  1127. * boost::system::error_code ec;
  1128. * socket.io_control(command, ec);
  1129. * if (ec)
  1130. * {
  1131. * // An error occurred.
  1132. * }
  1133. * std::size_t bytes_readable = command.get();
  1134. * @endcode
  1135. */
  1136. template <typename IoControlCommand>
  1137. BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command,
  1138. boost::system::error_code& ec)
  1139. {
  1140. impl_.get_service().io_control(impl_.get_implementation(), command, ec);
  1141. BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
  1142. }
  1143. /// Gets the non-blocking mode of the socket.
  1144. /**
  1145. * @returns @c true if the socket's synchronous operations will fail with
  1146. * boost::asio::error::would_block if they are unable to perform the requested
  1147. * operation immediately. If @c false, synchronous operations will block
  1148. * until complete.
  1149. *
  1150. * @note The non-blocking mode has no effect on the behaviour of asynchronous
  1151. * operations. Asynchronous operations will never fail with the error
  1152. * boost::asio::error::would_block.
  1153. */
  1154. bool non_blocking() const
  1155. {
  1156. return impl_.get_service().non_blocking(impl_.get_implementation());
  1157. }
  1158. /// Sets the non-blocking mode of the socket.
  1159. /**
  1160. * @param mode If @c true, the socket's synchronous operations will fail with
  1161. * boost::asio::error::would_block if they are unable to perform the requested
  1162. * operation immediately. If @c false, synchronous operations will block
  1163. * until complete.
  1164. *
  1165. * @throws boost::system::system_error Thrown on failure.
  1166. *
  1167. * @note The non-blocking mode has no effect on the behaviour of asynchronous
  1168. * operations. Asynchronous operations will never fail with the error
  1169. * boost::asio::error::would_block.
  1170. */
  1171. void non_blocking(bool mode)
  1172. {
  1173. boost::system::error_code ec;
  1174. impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec);
  1175. boost::asio::detail::throw_error(ec, "non_blocking");
  1176. }
  1177. /// Sets the non-blocking mode of the socket.
  1178. /**
  1179. * @param mode If @c true, the socket's synchronous operations will fail with
  1180. * boost::asio::error::would_block if they are unable to perform the requested
  1181. * operation immediately. If @c false, synchronous operations will block
  1182. * until complete.
  1183. *
  1184. * @param ec Set to indicate what error occurred, if any.
  1185. *
  1186. * @note The non-blocking mode has no effect on the behaviour of asynchronous
  1187. * operations. Asynchronous operations will never fail with the error
  1188. * boost::asio::error::would_block.
  1189. */
  1190. BOOST_ASIO_SYNC_OP_VOID non_blocking(
  1191. bool mode, boost::system::error_code& ec)
  1192. {
  1193. impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec);
  1194. BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
  1195. }
  1196. /// Gets the non-blocking mode of the native socket implementation.
  1197. /**
  1198. * This function is used to retrieve the non-blocking mode of the underlying
  1199. * native socket. This mode has no effect on the behaviour of the socket
  1200. * object's synchronous operations.
  1201. *
  1202. * @returns @c true if the underlying socket is in non-blocking mode and
  1203. * direct system calls may fail with boost::asio::error::would_block (or the
  1204. * equivalent system error).
  1205. *
  1206. * @note The current non-blocking mode is cached by the socket object.
  1207. * Consequently, the return value may be incorrect if the non-blocking mode
  1208. * was set directly on the native socket.
  1209. *
  1210. * @par Example
  1211. * This function is intended to allow the encapsulation of arbitrary
  1212. * non-blocking system calls as asynchronous operations, in a way that is
  1213. * transparent to the user of the socket object. The following example
  1214. * illustrates how Linux's @c sendfile system call might be encapsulated:
  1215. * @code template <typename Handler>
  1216. * struct sendfile_op
  1217. * {
  1218. * tcp::socket& sock_;
  1219. * int fd_;
  1220. * Handler handler_;
  1221. * off_t offset_;
  1222. * std::size_t total_bytes_transferred_;
  1223. *
  1224. * // Function call operator meeting WriteHandler requirements.
  1225. * // Used as the handler for the async_write_some operation.
  1226. * void operator()(boost::system::error_code ec, std::size_t)
  1227. * {
  1228. * // Put the underlying socket into non-blocking mode.
  1229. * if (!ec)
  1230. * if (!sock_.native_non_blocking())
  1231. * sock_.native_non_blocking(true, ec);
  1232. *
  1233. * if (!ec)
  1234. * {
  1235. * for (;;)
  1236. * {
  1237. * // Try the system call.
  1238. * errno = 0;
  1239. * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
  1240. * ec = boost::system::error_code(n < 0 ? errno : 0,
  1241. * boost::asio::error::get_system_category());
  1242. * total_bytes_transferred_ += ec ? 0 : n;
  1243. *
  1244. * // Retry operation immediately if interrupted by signal.
  1245. * if (ec == boost::asio::error::interrupted)
  1246. * continue;
  1247. *
  1248. * // Check if we need to run the operation again.
  1249. * if (ec == boost::asio::error::would_block
  1250. * || ec == boost::asio::error::try_again)
  1251. * {
  1252. * // We have to wait for the socket to become ready again.
  1253. * sock_.async_wait(tcp::socket::wait_write, *this);
  1254. * return;
  1255. * }
  1256. *
  1257. * if (ec || n == 0)
  1258. * {
  1259. * // An error occurred, or we have reached the end of the file.
  1260. * // Either way we must exit the loop so we can call the handler.
  1261. * break;
  1262. * }
  1263. *
  1264. * // Loop around to try calling sendfile again.
  1265. * }
  1266. * }
  1267. *
  1268. * // Pass result back to user's handler.
  1269. * handler_(ec, total_bytes_transferred_);
  1270. * }
  1271. * };
  1272. *
  1273. * template <typename Handler>
  1274. * void async_sendfile(tcp::socket& sock, int fd, Handler h)
  1275. * {
  1276. * sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
  1277. * sock.async_wait(tcp::socket::wait_write, op);
  1278. * } @endcode
  1279. */
  1280. bool native_non_blocking() const
  1281. {
  1282. return impl_.get_service().native_non_blocking(impl_.get_implementation());
  1283. }
  1284. /// Sets the non-blocking mode of the native socket implementation.
  1285. /**
  1286. * This function is used to modify the non-blocking mode of the underlying
  1287. * native socket. It has no effect on the behaviour of the socket object's
  1288. * synchronous operations.
  1289. *
  1290. * @param mode If @c true, the underlying socket is put into non-blocking
  1291. * mode and direct system calls may fail with boost::asio::error::would_block
  1292. * (or the equivalent system error).
  1293. *
  1294. * @throws boost::system::system_error Thrown on failure. If the @c mode is
  1295. * @c false, but the current value of @c non_blocking() is @c true, this
  1296. * function fails with boost::asio::error::invalid_argument, as the
  1297. * combination does not make sense.
  1298. *
  1299. * @par Example
  1300. * This function is intended to allow the encapsulation of arbitrary
  1301. * non-blocking system calls as asynchronous operations, in a way that is
  1302. * transparent to the user of the socket object. The following example
  1303. * illustrates how Linux's @c sendfile system call might be encapsulated:
  1304. * @code template <typename Handler>
  1305. * struct sendfile_op
  1306. * {
  1307. * tcp::socket& sock_;
  1308. * int fd_;
  1309. * Handler handler_;
  1310. * off_t offset_;
  1311. * std::size_t total_bytes_transferred_;
  1312. *
  1313. * // Function call operator meeting WriteHandler requirements.
  1314. * // Used as the handler for the async_write_some operation.
  1315. * void operator()(boost::system::error_code ec, std::size_t)
  1316. * {
  1317. * // Put the underlying socket into non-blocking mode.
  1318. * if (!ec)
  1319. * if (!sock_.native_non_blocking())
  1320. * sock_.native_non_blocking(true, ec);
  1321. *
  1322. * if (!ec)
  1323. * {
  1324. * for (;;)
  1325. * {
  1326. * // Try the system call.
  1327. * errno = 0;
  1328. * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
  1329. * ec = boost::system::error_code(n < 0 ? errno : 0,
  1330. * boost::asio::error::get_system_category());
  1331. * total_bytes_transferred_ += ec ? 0 : n;
  1332. *
  1333. * // Retry operation immediately if interrupted by signal.
  1334. * if (ec == boost::asio::error::interrupted)
  1335. * continue;
  1336. *
  1337. * // Check if we need to run the operation again.
  1338. * if (ec == boost::asio::error::would_block
  1339. * || ec == boost::asio::error::try_again)
  1340. * {
  1341. * // We have to wait for the socket to become ready again.
  1342. * sock_.async_wait(tcp::socket::wait_write, *this);
  1343. * return;
  1344. * }
  1345. *
  1346. * if (ec || n == 0)
  1347. * {
  1348. * // An error occurred, or we have reached the end of the file.
  1349. * // Either way we must exit the loop so we can call the handler.
  1350. * break;
  1351. * }
  1352. *
  1353. * // Loop around to try calling sendfile again.
  1354. * }
  1355. * }
  1356. *
  1357. * // Pass result back to user's handler.
  1358. * handler_(ec, total_bytes_transferred_);
  1359. * }
  1360. * };
  1361. *
  1362. * template <typename Handler>
  1363. * void async_sendfile(tcp::socket& sock, int fd, Handler h)
  1364. * {
  1365. * sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
  1366. * sock.async_wait(tcp::socket::wait_write, op);
  1367. * } @endcode
  1368. */
  1369. void native_non_blocking(bool mode)
  1370. {
  1371. boost::system::error_code ec;
  1372. impl_.get_service().native_non_blocking(
  1373. impl_.get_implementation(), mode, ec);
  1374. boost::asio::detail::throw_error(ec, "native_non_blocking");
  1375. }
  1376. /// Sets the non-blocking mode of the native socket implementation.
  1377. /**
  1378. * This function is used to modify the non-blocking mode of the underlying
  1379. * native socket. It has no effect on the behaviour of the socket object's
  1380. * synchronous operations.
  1381. *
  1382. * @param mode If @c true, the underlying socket is put into non-blocking
  1383. * mode and direct system calls may fail with boost::asio::error::would_block
  1384. * (or the equivalent system error).
  1385. *
  1386. * @param ec Set to indicate what error occurred, if any. If the @c mode is
  1387. * @c false, but the current value of @c non_blocking() is @c true, this
  1388. * function fails with boost::asio::error::invalid_argument, as the
  1389. * combination does not make sense.
  1390. *
  1391. * @par Example
  1392. * This function is intended to allow the encapsulation of arbitrary
  1393. * non-blocking system calls as asynchronous operations, in a way that is
  1394. * transparent to the user of the socket object. The following example
  1395. * illustrates how Linux's @c sendfile system call might be encapsulated:
  1396. * @code template <typename Handler>
  1397. * struct sendfile_op
  1398. * {
  1399. * tcp::socket& sock_;
  1400. * int fd_;
  1401. * Handler handler_;
  1402. * off_t offset_;
  1403. * std::size_t total_bytes_transferred_;
  1404. *
  1405. * // Function call operator meeting WriteHandler requirements.
  1406. * // Used as the handler for the async_write_some operation.
  1407. * void operator()(boost::system::error_code ec, std::size_t)
  1408. * {
  1409. * // Put the underlying socket into non-blocking mode.
  1410. * if (!ec)
  1411. * if (!sock_.native_non_blocking())
  1412. * sock_.native_non_blocking(true, ec);
  1413. *
  1414. * if (!ec)
  1415. * {
  1416. * for (;;)
  1417. * {
  1418. * // Try the system call.
  1419. * errno = 0;
  1420. * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
  1421. * ec = boost::system::error_code(n < 0 ? errno : 0,
  1422. * boost::asio::error::get_system_category());
  1423. * total_bytes_transferred_ += ec ? 0 : n;
  1424. *
  1425. * // Retry operation immediately if interrupted by signal.
  1426. * if (ec == boost::asio::error::interrupted)
  1427. * continue;
  1428. *
  1429. * // Check if we need to run the operation again.
  1430. * if (ec == boost::asio::error::would_block
  1431. * || ec == boost::asio::error::try_again)
  1432. * {
  1433. * // We have to wait for the socket to become ready again.
  1434. * sock_.async_wait(tcp::socket::wait_write, *this);
  1435. * return;
  1436. * }
  1437. *
  1438. * if (ec || n == 0)
  1439. * {
  1440. * // An error occurred, or we have reached the end of the file.
  1441. * // Either way we must exit the loop so we can call the handler.
  1442. * break;
  1443. * }
  1444. *
  1445. * // Loop around to try calling sendfile again.
  1446. * }
  1447. * }
  1448. *
  1449. * // Pass result back to user's handler.
  1450. * handler_(ec, total_bytes_transferred_);
  1451. * }
  1452. * };
  1453. *
  1454. * template <typename Handler>
  1455. * void async_sendfile(tcp::socket& sock, int fd, Handler h)
  1456. * {
  1457. * sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
  1458. * sock.async_wait(tcp::socket::wait_write, op);
  1459. * } @endcode
  1460. */
  1461. BOOST_ASIO_SYNC_OP_VOID native_non_blocking(
  1462. bool mode, boost::system::error_code& ec)
  1463. {
  1464. impl_.get_service().native_non_blocking(
  1465. impl_.get_implementation(), mode, ec);
  1466. BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
  1467. }
  1468. /// Get the local endpoint of the socket.
  1469. /**
  1470. * This function is used to obtain the locally bound endpoint of the socket.
  1471. *
  1472. * @returns An object that represents the local endpoint of the socket.
  1473. *
  1474. * @throws boost::system::system_error Thrown on failure.
  1475. *
  1476. * @par Example
  1477. * @code
  1478. * boost::asio::ip::tcp::socket socket(my_context);
  1479. * ...
  1480. * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint();
  1481. * @endcode
  1482. */
  1483. endpoint_type local_endpoint() const
  1484. {
  1485. boost::system::error_code ec;
  1486. endpoint_type ep = impl_.get_service().local_endpoint(
  1487. impl_.get_implementation(), ec);
  1488. boost::asio::detail::throw_error(ec, "local_endpoint");
  1489. return ep;
  1490. }
  1491. /// Get the local endpoint of the socket.
  1492. /**
  1493. * This function is used to obtain the locally bound endpoint of the socket.
  1494. *
  1495. * @param ec Set to indicate what error occurred, if any.
  1496. *
  1497. * @returns An object that represents the local endpoint of the socket.
  1498. * Returns a default-constructed endpoint object if an error occurred.
  1499. *
  1500. * @par Example
  1501. * @code
  1502. * boost::asio::ip::tcp::socket socket(my_context);
  1503. * ...
  1504. * boost::system::error_code ec;
  1505. * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec);
  1506. * if (ec)
  1507. * {
  1508. * // An error occurred.
  1509. * }
  1510. * @endcode
  1511. */
  1512. endpoint_type local_endpoint(boost::system::error_code& ec) const
  1513. {
  1514. return impl_.get_service().local_endpoint(impl_.get_implementation(), ec);
  1515. }
  1516. /// Get the remote endpoint of the socket.
  1517. /**
  1518. * This function is used to obtain the remote endpoint of the socket.
  1519. *
  1520. * @returns An object that represents the remote endpoint of the socket.
  1521. *
  1522. * @throws boost::system::system_error Thrown on failure.
  1523. *
  1524. * @par Example
  1525. * @code
  1526. * boost::asio::ip::tcp::socket socket(my_context);
  1527. * ...
  1528. * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint();
  1529. * @endcode
  1530. */
  1531. endpoint_type remote_endpoint() const
  1532. {
  1533. boost::system::error_code ec;
  1534. endpoint_type ep = impl_.get_service().remote_endpoint(
  1535. impl_.get_implementation(), ec);
  1536. boost::asio::detail::throw_error(ec, "remote_endpoint");
  1537. return ep;
  1538. }
  1539. /// Get the remote endpoint of the socket.
  1540. /**
  1541. * This function is used to obtain the remote endpoint of the socket.
  1542. *
  1543. * @param ec Set to indicate what error occurred, if any.
  1544. *
  1545. * @returns An object that represents the remote endpoint of the socket.
  1546. * Returns a default-constructed endpoint object if an error occurred.
  1547. *
  1548. * @par Example
  1549. * @code
  1550. * boost::asio::ip::tcp::socket socket(my_context);
  1551. * ...
  1552. * boost::system::error_code ec;
  1553. * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec);
  1554. * if (ec)
  1555. * {
  1556. * // An error occurred.
  1557. * }
  1558. * @endcode
  1559. */
  1560. endpoint_type remote_endpoint(boost::system::error_code& ec) const
  1561. {
  1562. return impl_.get_service().remote_endpoint(impl_.get_implementation(), ec);
  1563. }
  1564. /// Disable sends or receives on the socket.
  1565. /**
  1566. * This function is used to disable send operations, receive operations, or
  1567. * both.
  1568. *
  1569. * @param what Determines what types of operation will no longer be allowed.
  1570. *
  1571. * @throws boost::system::system_error Thrown on failure.
  1572. *
  1573. * @par Example
  1574. * Shutting down the send side of the socket:
  1575. * @code
  1576. * boost::asio::ip::tcp::socket socket(my_context);
  1577. * ...
  1578. * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send);
  1579. * @endcode
  1580. */
  1581. void shutdown(shutdown_type what)
  1582. {
  1583. boost::system::error_code ec;
  1584. impl_.get_service().shutdown(impl_.get_implementation(), what, ec);
  1585. boost::asio::detail::throw_error(ec, "shutdown");
  1586. }
  1587. /// Disable sends or receives on the socket.
  1588. /**
  1589. * This function is used to disable send operations, receive operations, or
  1590. * both.
  1591. *
  1592. * @param what Determines what types of operation will no longer be allowed.
  1593. *
  1594. * @param ec Set to indicate what error occurred, if any.
  1595. *
  1596. * @par Example
  1597. * Shutting down the send side of the socket:
  1598. * @code
  1599. * boost::asio::ip::tcp::socket socket(my_context);
  1600. * ...
  1601. * boost::system::error_code ec;
  1602. * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec);
  1603. * if (ec)
  1604. * {
  1605. * // An error occurred.
  1606. * }
  1607. * @endcode
  1608. */
  1609. BOOST_ASIO_SYNC_OP_VOID shutdown(shutdown_type what,
  1610. boost::system::error_code& ec)
  1611. {
  1612. impl_.get_service().shutdown(impl_.get_implementation(), what, ec);
  1613. BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
  1614. }
  1615. /// Wait for the socket to become ready to read, ready to write, or to have
  1616. /// pending error conditions.
  1617. /**
  1618. * This function is used to perform a blocking wait for a socket to enter
  1619. * a ready to read, write or error condition state.
  1620. *
  1621. * @param w Specifies the desired socket state.
  1622. *
  1623. * @par Example
  1624. * Waiting for a socket to become readable.
  1625. * @code
  1626. * boost::asio::ip::tcp::socket socket(my_context);
  1627. * ...
  1628. * socket.wait(boost::asio::ip::tcp::socket::wait_read);
  1629. * @endcode
  1630. */
  1631. void wait(wait_type w)
  1632. {
  1633. boost::system::error_code ec;
  1634. impl_.get_service().wait(impl_.get_implementation(), w, ec);
  1635. boost::asio::detail::throw_error(ec, "wait");
  1636. }
  1637. /// Wait for the socket to become ready to read, ready to write, or to have
  1638. /// pending error conditions.
  1639. /**
  1640. * This function is used to perform a blocking wait for a socket to enter
  1641. * a ready to read, write or error condition state.
  1642. *
  1643. * @param w Specifies the desired socket state.
  1644. *
  1645. * @param ec Set to indicate what error occurred, if any.
  1646. *
  1647. * @par Example
  1648. * Waiting for a socket to become readable.
  1649. * @code
  1650. * boost::asio::ip::tcp::socket socket(my_context);
  1651. * ...
  1652. * boost::system::error_code ec;
  1653. * socket.wait(boost::asio::ip::tcp::socket::wait_read, ec);
  1654. * @endcode
  1655. */
  1656. BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec)
  1657. {
  1658. impl_.get_service().wait(impl_.get_implementation(), w, ec);
  1659. BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
  1660. }
  1661. /// Asynchronously wait for the socket to become ready to read, ready to
  1662. /// write, or to have pending error conditions.
  1663. /**
  1664. * This function is used to perform an asynchronous wait for a socket to enter
  1665. * a ready to read, write or error condition state.
  1666. *
  1667. * @param w Specifies the desired socket state.
  1668. *
  1669. * @param handler The handler to be called when the wait operation completes.
  1670. * Copies will be made of the handler as required. The function signature of
  1671. * the handler must be:
  1672. * @code void handler(
  1673. * const boost::system::error_code& error // Result of operation
  1674. * ); @endcode
  1675. * Regardless of whether the asynchronous operation completes immediately or
  1676. * not, the handler will not be invoked from within this function. On
  1677. * immediate completion, invocation of the handler will be performed in a
  1678. * manner equivalent to using boost::asio::post().
  1679. *
  1680. * @par Example
  1681. * @code
  1682. * void wait_handler(const boost::system::error_code& error)
  1683. * {
  1684. * if (!error)
  1685. * {
  1686. * // Wait succeeded.
  1687. * }
  1688. * }
  1689. *
  1690. * ...
  1691. *
  1692. * boost::asio::ip::tcp::socket socket(my_context);
  1693. * ...
  1694. * socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler);
  1695. * @endcode
  1696. */
  1697. template <typename WaitHandler>
  1698. BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
  1699. void (boost::system::error_code))
  1700. async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
  1701. {
  1702. return async_initiate<WaitHandler, void (boost::system::error_code)>(
  1703. initiate_async_wait(), handler, this, w);
  1704. }
  1705. protected:
  1706. /// Protected destructor to prevent deletion through this type.
  1707. /**
  1708. * This function destroys the socket, cancelling any outstanding asynchronous
  1709. * operations associated with the socket as if by calling @c cancel.
  1710. */
  1711. ~basic_socket()
  1712. {
  1713. }
  1714. #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
  1715. detail::io_object_impl<
  1716. detail::null_socket_service<Protocol>, Executor> impl_;
  1717. #elif defined(BOOST_ASIO_HAS_IOCP)
  1718. detail::io_object_impl<
  1719. detail::win_iocp_socket_service<Protocol>, Executor> impl_;
  1720. #else
  1721. detail::io_object_impl<
  1722. detail::reactive_socket_service<Protocol>, Executor> impl_;
  1723. #endif
  1724. private:
  1725. // Disallow copying and assignment.
  1726. basic_socket(const basic_socket&) BOOST_ASIO_DELETED;
  1727. basic_socket& operator=(const basic_socket&) BOOST_ASIO_DELETED;
  1728. struct initiate_async_connect
  1729. {
  1730. template <typename ConnectHandler>
  1731. void operator()(BOOST_ASIO_MOVE_ARG(ConnectHandler) handler,
  1732. basic_socket* self, const endpoint_type& peer_endpoint,
  1733. const boost::system::error_code& open_ec) const
  1734. {
  1735. // If you get an error on the following line it means that your handler
  1736. // does not meet the documented type requirements for a ConnectHandler.
  1737. BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check;
  1738. if (open_ec)
  1739. {
  1740. boost::asio::post(self->impl_.get_executor(),
  1741. boost::asio::detail::bind_handler(
  1742. BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler), open_ec));
  1743. }
  1744. else
  1745. {
  1746. detail::non_const_lvalue<ConnectHandler> handler2(handler);
  1747. self->impl_.get_service().async_connect(
  1748. self->impl_.get_implementation(), peer_endpoint,
  1749. handler2.value, self->impl_.get_implementation_executor());
  1750. }
  1751. }
  1752. };
  1753. struct initiate_async_wait
  1754. {
  1755. template <typename WaitHandler>
  1756. void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler,
  1757. basic_socket* self, wait_type w) const
  1758. {
  1759. // If you get an error on the following line it means that your handler
  1760. // does not meet the documented type requirements for a WaitHandler.
  1761. BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
  1762. detail::non_const_lvalue<WaitHandler> handler2(handler);
  1763. self->impl_.get_service().async_wait(
  1764. self->impl_.get_implementation(), w, handler2.value,
  1765. self->impl_.get_implementation_executor());
  1766. }
  1767. };
  1768. };
  1769. } // namespace asio
  1770. } // namespace boost
  1771. #include <boost/asio/detail/pop_options.hpp>
  1772. #endif // BOOST_ASIO_BASIC_SOCKET_HPP