basic_raw_socket.hpp 39 KB

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