basic_socket.hpp 60 KB

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