basic_datagram_socket.hpp 41 KB

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