basic_raw_socket.hpp 46 KB

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