basic_datagram_socket.hpp 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212
  1. //
  2. // basic_datagram_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_DATAGRAM_SOCKET_HPP
  11. #define BOOST_ASIO_BASIC_DATAGRAM_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_DATAGRAM_SOCKET_FWD_DECL)
  27. #define BOOST_ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL
  28. // Forward declaration with defaulted arguments.
  29. template <typename Protocol, typename Executor = executor>
  30. class basic_datagram_socket;
  31. #endif // !defined(BOOST_ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL)
  32. /// Provides datagram-oriented socket functionality.
  33. /**
  34. * The basic_datagram_socket class template provides asynchronous and blocking
  35. * datagram-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_datagram_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_datagram_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_datagram_socket without opening it.
  67. /**
  68. * This constructor creates a datagram 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_datagram_socket(const executor_type& ex)
  75. : basic_socket<Protocol, Executor>(ex)
  76. {
  77. }
  78. /// Construct a basic_datagram_socket without opening it.
  79. /**
  80. * This constructor creates a datagram 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_datagram_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_datagram_socket.
  96. /**
  97. * This constructor creates and opens a datagram 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_datagram_socket(const executor_type& ex, const protocol_type& protocol)
  107. : basic_socket<Protocol, Executor>(ex, protocol)
  108. {
  109. }
  110. /// Construct and open a basic_datagram_socket.
  111. /**
  112. * This constructor creates and opens a datagram 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_datagram_socket(ExecutionContext& context,
  124. const protocol_type& protocol,
  125. typename enable_if<
  126. is_convertible<ExecutionContext&, execution_context&>::value
  127. >::type* = 0)
  128. : basic_socket<Protocol, Executor>(context, protocol)
  129. {
  130. }
  131. /// Construct a basic_datagram_socket, opening it and binding it to the given
  132. /// local endpoint.
  133. /**
  134. * This constructor creates a datagram socket and automatically opens it bound
  135. * to the specified endpoint on the local machine. The protocol used is the
  136. * protocol associated with the given endpoint.
  137. *
  138. * @param ex The I/O executor that the socket will use, by default, to
  139. * dispatch handlers for any asynchronous operations performed on the socket.
  140. *
  141. * @param endpoint An endpoint on the local machine to which the datagram
  142. * socket will be bound.
  143. *
  144. * @throws boost::system::system_error Thrown on failure.
  145. */
  146. basic_datagram_socket(const executor_type& ex, const endpoint_type& endpoint)
  147. : basic_socket<Protocol, Executor>(ex, endpoint)
  148. {
  149. }
  150. /// Construct a basic_datagram_socket, opening it and binding it to the given
  151. /// local endpoint.
  152. /**
  153. * This constructor creates a datagram socket and automatically opens it bound
  154. * to the specified endpoint on the local machine. The protocol used is the
  155. * protocol associated with the given endpoint.
  156. *
  157. * @param context An execution context which provides the I/O executor that
  158. * the socket will use, by default, to dispatch handlers for any asynchronous
  159. * operations performed on the socket.
  160. *
  161. * @param endpoint An endpoint on the local machine to which the datagram
  162. * socket will be bound.
  163. *
  164. * @throws boost::system::system_error Thrown on failure.
  165. */
  166. template <typename ExecutionContext>
  167. basic_datagram_socket(ExecutionContext& context,
  168. const endpoint_type& endpoint,
  169. typename enable_if<
  170. is_convertible<ExecutionContext&, execution_context&>::value
  171. >::type* = 0)
  172. : basic_socket<Protocol, Executor>(context, endpoint)
  173. {
  174. }
  175. /// Construct a basic_datagram_socket on an existing native socket.
  176. /**
  177. * This constructor creates a datagram socket object to hold an existing
  178. * native socket.
  179. *
  180. * @param ex The I/O executor that the socket will use, by default, to
  181. * dispatch handlers for any asynchronous operations performed on the socket.
  182. *
  183. * @param protocol An object specifying protocol parameters to be used.
  184. *
  185. * @param native_socket The new underlying socket implementation.
  186. *
  187. * @throws boost::system::system_error Thrown on failure.
  188. */
  189. basic_datagram_socket(const executor_type& ex,
  190. const protocol_type& protocol, const native_handle_type& native_socket)
  191. : basic_socket<Protocol, Executor>(ex, protocol, native_socket)
  192. {
  193. }
  194. /// Construct a basic_datagram_socket on an existing native socket.
  195. /**
  196. * This constructor creates a datagram socket object to hold an existing
  197. * native socket.
  198. *
  199. * @param context An execution context which provides the I/O executor that
  200. * the socket will use, by default, to dispatch handlers for any asynchronous
  201. * operations performed on the socket.
  202. *
  203. * @param protocol An object specifying protocol parameters to be used.
  204. *
  205. * @param native_socket The new underlying socket implementation.
  206. *
  207. * @throws boost::system::system_error Thrown on failure.
  208. */
  209. template <typename ExecutionContext>
  210. basic_datagram_socket(ExecutionContext& context,
  211. const protocol_type& protocol, const native_handle_type& native_socket,
  212. typename enable_if<
  213. is_convertible<ExecutionContext&, execution_context&>::value
  214. >::type* = 0)
  215. : basic_socket<Protocol, Executor>(context, protocol, native_socket)
  216. {
  217. }
  218. #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  219. /// Move-construct a basic_datagram_socket from another.
  220. /**
  221. * This constructor moves a datagram socket from one object to another.
  222. *
  223. * @param other The other basic_datagram_socket object from which the move
  224. * will occur.
  225. *
  226. * @note Following the move, the moved-from object is in the same state as if
  227. * constructed using the @c basic_datagram_socket(const executor_type&)
  228. * constructor.
  229. */
  230. basic_datagram_socket(basic_datagram_socket&& other) BOOST_ASIO_NOEXCEPT
  231. : basic_socket<Protocol, Executor>(std::move(other))
  232. {
  233. }
  234. /// Move-assign a basic_datagram_socket from another.
  235. /**
  236. * This assignment operator moves a datagram socket from one object to
  237. * another.
  238. *
  239. * @param other The other basic_datagram_socket object from which the move
  240. * will occur.
  241. *
  242. * @note Following the move, the moved-from object is in the same state as if
  243. * constructed using the @c basic_datagram_socket(const executor_type&)
  244. * constructor.
  245. */
  246. basic_datagram_socket& operator=(basic_datagram_socket&& other)
  247. {
  248. basic_socket<Protocol, Executor>::operator=(std::move(other));
  249. return *this;
  250. }
  251. /// Move-construct a basic_datagram_socket from a socket of another protocol
  252. /// type.
  253. /**
  254. * This constructor moves a datagram socket from one object to another.
  255. *
  256. * @param other The other basic_datagram_socket object from which the move
  257. * will occur.
  258. *
  259. * @note Following the move, the moved-from object is in the same state as if
  260. * constructed using the @c basic_datagram_socket(const executor_type&)
  261. * constructor.
  262. */
  263. template <typename Protocol1, typename Executor1>
  264. basic_datagram_socket(basic_datagram_socket<Protocol1, Executor1>&& other,
  265. typename enable_if<
  266. is_convertible<Protocol1, Protocol>::value
  267. && is_convertible<Executor1, Executor>::value
  268. >::type* = 0)
  269. : basic_socket<Protocol, Executor>(std::move(other))
  270. {
  271. }
  272. /// Move-assign a basic_datagram_socket from a socket of another protocol
  273. /// type.
  274. /**
  275. * This assignment operator moves a datagram socket from one object to
  276. * another.
  277. *
  278. * @param other The other basic_datagram_socket object from which the move
  279. * will occur.
  280. *
  281. * @note Following the move, the moved-from object is in the same state as if
  282. * constructed using the @c basic_datagram_socket(const executor_type&)
  283. * constructor.
  284. */
  285. template <typename Protocol1, typename Executor1>
  286. typename enable_if<
  287. is_convertible<Protocol1, Protocol>::value
  288. && is_convertible<Executor1, Executor>::value,
  289. basic_datagram_socket&
  290. >::type operator=(basic_datagram_socket<Protocol1, Executor1>&& other)
  291. {
  292. basic_socket<Protocol, Executor>::operator=(std::move(other));
  293. return *this;
  294. }
  295. #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  296. /// Destroys the socket.
  297. /**
  298. * This function destroys the socket, cancelling any outstanding asynchronous
  299. * operations associated with the socket as if by calling @c cancel.
  300. */
  301. ~basic_datagram_socket()
  302. {
  303. }
  304. /// Send some data on a connected socket.
  305. /**
  306. * This function is used to send data on the datagram socket. The function
  307. * call will block until the data has been sent successfully or an error
  308. * occurs.
  309. *
  310. * @param buffers One ore more data buffers to be sent on the socket.
  311. *
  312. * @returns The number of bytes sent.
  313. *
  314. * @throws boost::system::system_error Thrown on failure.
  315. *
  316. * @note The send operation can only be used with a connected socket. Use
  317. * the send_to function to send data on an unconnected datagram socket.
  318. *
  319. * @par Example
  320. * To send a single data buffer use the @ref buffer function as follows:
  321. * @code socket.send(boost::asio::buffer(data, size)); @endcode
  322. * See the @ref buffer documentation for information on sending multiple
  323. * buffers in one go, and how to use it with arrays, boost::array or
  324. * std::vector.
  325. */
  326. template <typename ConstBufferSequence>
  327. std::size_t send(const ConstBufferSequence& buffers)
  328. {
  329. boost::system::error_code ec;
  330. std::size_t s = this->impl_.get_service().send(
  331. this->impl_.get_implementation(), buffers, 0, ec);
  332. boost::asio::detail::throw_error(ec, "send");
  333. return s;
  334. }
  335. /// Send some data on a connected socket.
  336. /**
  337. * This function is used to send data on the datagram socket. The function
  338. * call will block until the data has been sent successfully or an error
  339. * occurs.
  340. *
  341. * @param buffers One ore more data buffers to be sent on the socket.
  342. *
  343. * @param flags Flags specifying how the send call is to be made.
  344. *
  345. * @returns The number of bytes sent.
  346. *
  347. * @throws boost::system::system_error Thrown on failure.
  348. *
  349. * @note The send operation can only be used with a connected socket. Use
  350. * the send_to function to send data on an unconnected datagram socket.
  351. */
  352. template <typename ConstBufferSequence>
  353. std::size_t send(const ConstBufferSequence& buffers,
  354. socket_base::message_flags flags)
  355. {
  356. boost::system::error_code ec;
  357. std::size_t s = this->impl_.get_service().send(
  358. this->impl_.get_implementation(), buffers, flags, ec);
  359. boost::asio::detail::throw_error(ec, "send");
  360. return s;
  361. }
  362. /// Send some data on a connected socket.
  363. /**
  364. * This function is used to send data on the datagram socket. The function
  365. * call will block until the data has been sent successfully or an error
  366. * 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 datagram 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 asynchronously send data on the datagram socket.
  389. * The function call always returns immediately.
  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 datagram
  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 asynchronously send data on the datagram socket.
  439. * The function call always returns immediately.
  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 datagram
  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 a datagram to the specified endpoint.
  480. /**
  481. * This function is used to send a datagram 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 a datagram to the specified endpoint.
  515. /**
  516. * This function is used to send a datagram 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 a datagram to the specified endpoint.
  541. /**
  542. * This function is used to send a datagram 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 a datagram 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 a datagram 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 datagram 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 datagram
  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 datagram 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 datagram
  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 datagram 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 datagram
  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 datagram
  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. * datagram 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 datagram
  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. * datagram 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 a datagram with the endpoint of the sender.
  840. /**
  841. * This function is used to receive a datagram. 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 datagram.
  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 a datagram with the endpoint of the sender.
  876. /**
  877. * This function is used to receive a datagram. 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 datagram.
  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 a datagram with the endpoint of the sender.
  902. /**
  903. * This function is used to receive a datagram. 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 datagram.
  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 a datagram. 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 datagram. 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), 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 a datagram. 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 datagram. 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. class initiate_async_send
  1024. {
  1025. public:
  1026. typedef Executor executor_type;
  1027. explicit initiate_async_send(basic_datagram_socket* self)
  1028. : self_(self)
  1029. {
  1030. }
  1031. executor_type get_executor() const BOOST_ASIO_NOEXCEPT
  1032. {
  1033. return self_->get_executor();
  1034. }
  1035. template <typename WriteHandler, typename ConstBufferSequence>
  1036. void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
  1037. const ConstBufferSequence& buffers,
  1038. socket_base::message_flags flags) const
  1039. {
  1040. // If you get an error on the following line it means that your handler
  1041. // does not meet the documented type requirements for a WriteHandler.
  1042. BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
  1043. detail::non_const_lvalue<WriteHandler> handler2(handler);
  1044. self_->impl_.get_service().async_send(
  1045. self_->impl_.get_implementation(), buffers, flags,
  1046. handler2.value, self_->impl_.get_implementation_executor());
  1047. }
  1048. private:
  1049. basic_datagram_socket* self_;
  1050. };
  1051. class initiate_async_send_to
  1052. {
  1053. public:
  1054. typedef Executor executor_type;
  1055. explicit initiate_async_send_to(basic_datagram_socket* self)
  1056. : self_(self)
  1057. {
  1058. }
  1059. executor_type get_executor() const BOOST_ASIO_NOEXCEPT
  1060. {
  1061. return self_->get_executor();
  1062. }
  1063. template <typename WriteHandler, typename ConstBufferSequence>
  1064. void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
  1065. const ConstBufferSequence& buffers, const endpoint_type& destination,
  1066. socket_base::message_flags flags) const
  1067. {
  1068. // If you get an error on the following line it means that your handler
  1069. // does not meet the documented type requirements for a WriteHandler.
  1070. BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
  1071. detail::non_const_lvalue<WriteHandler> handler2(handler);
  1072. self_->impl_.get_service().async_send_to(
  1073. self_->impl_.get_implementation(), buffers, destination, flags,
  1074. handler2.value, self_->impl_.get_implementation_executor());
  1075. }
  1076. private:
  1077. basic_datagram_socket* self_;
  1078. };
  1079. class initiate_async_receive
  1080. {
  1081. public:
  1082. typedef Executor executor_type;
  1083. explicit initiate_async_receive(basic_datagram_socket* self)
  1084. : self_(self)
  1085. {
  1086. }
  1087. executor_type get_executor() const BOOST_ASIO_NOEXCEPT
  1088. {
  1089. return self_->get_executor();
  1090. }
  1091. template <typename ReadHandler, typename MutableBufferSequence>
  1092. void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
  1093. const MutableBufferSequence& buffers,
  1094. socket_base::message_flags flags) const
  1095. {
  1096. // If you get an error on the following line it means that your handler
  1097. // does not meet the documented type requirements for a ReadHandler.
  1098. BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
  1099. detail::non_const_lvalue<ReadHandler> handler2(handler);
  1100. self_->impl_.get_service().async_receive(
  1101. self_->impl_.get_implementation(), buffers, flags,
  1102. handler2.value, self_->impl_.get_implementation_executor());
  1103. }
  1104. private:
  1105. basic_datagram_socket* self_;
  1106. };
  1107. class initiate_async_receive_from
  1108. {
  1109. public:
  1110. typedef Executor executor_type;
  1111. explicit initiate_async_receive_from(basic_datagram_socket* self)
  1112. : self_(self)
  1113. {
  1114. }
  1115. executor_type get_executor() const BOOST_ASIO_NOEXCEPT
  1116. {
  1117. return self_->get_executor();
  1118. }
  1119. template <typename ReadHandler, typename MutableBufferSequence>
  1120. void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
  1121. const MutableBufferSequence& buffers, endpoint_type* sender_endpoint,
  1122. socket_base::message_flags flags) const
  1123. {
  1124. // If you get an error on the following line it means that your handler
  1125. // does not meet the documented type requirements for a ReadHandler.
  1126. BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
  1127. detail::non_const_lvalue<ReadHandler> handler2(handler);
  1128. self_->impl_.get_service().async_receive_from(
  1129. self_->impl_.get_implementation(), buffers, *sender_endpoint, flags,
  1130. handler2.value, self_->impl_.get_implementation_executor());
  1131. }
  1132. private:
  1133. basic_datagram_socket* self_;
  1134. };
  1135. };
  1136. } // namespace asio
  1137. } // namespace boost
  1138. #include <boost/asio/detail/pop_options.hpp>
  1139. #endif // BOOST_ASIO_BASIC_DATAGRAM_SOCKET_HPP