basic_raw_socket.hpp 46 KB

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