basic_raw_socket.hpp 43 KB

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