basic_seq_packet_socket.hpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565
  1. //
  2. // basic_seq_packet_socket.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2015 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_SEQ_PACKET_SOCKET_HPP
  11. #define ASIO_BASIC_SEQ_PACKET_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/error.hpp"
  21. #include "asio/seq_packet_socket_service.hpp"
  22. #include "asio/detail/push_options.hpp"
  23. namespace asio {
  24. /// Provides sequenced packet socket functionality.
  25. /**
  26. * The basic_seq_packet_socket class template provides asynchronous and blocking
  27. * sequenced packet socket functionality.
  28. *
  29. * @par Thread Safety
  30. * @e Distinct @e objects: Safe.@n
  31. * @e Shared @e objects: Unsafe.
  32. */
  33. template <typename Protocol,
  34. typename SeqPacketSocketService = seq_packet_socket_service<Protocol> >
  35. class basic_seq_packet_socket
  36. : public basic_socket<Protocol, SeqPacketSocketService>
  37. {
  38. public:
  39. /// (Deprecated: Use native_handle_type.) The native representation of a
  40. /// socket.
  41. typedef typename SeqPacketSocketService::native_handle_type native_type;
  42. /// The native representation of a socket.
  43. typedef typename SeqPacketSocketService::native_handle_type
  44. native_handle_type;
  45. /// The protocol type.
  46. typedef Protocol protocol_type;
  47. /// The endpoint type.
  48. typedef typename Protocol::endpoint endpoint_type;
  49. /// Construct a basic_seq_packet_socket without opening it.
  50. /**
  51. * This constructor creates a sequenced packet socket without opening it. The
  52. * socket needs to be opened and then connected or accepted before data can
  53. * be sent or received on it.
  54. *
  55. * @param io_service The io_service object that the sequenced packet socket
  56. * will use to dispatch handlers for any asynchronous operations performed on
  57. * the socket.
  58. */
  59. explicit basic_seq_packet_socket(asio::io_service& io_service)
  60. : basic_socket<Protocol, SeqPacketSocketService>(io_service)
  61. {
  62. }
  63. /// Construct and open a basic_seq_packet_socket.
  64. /**
  65. * This constructor creates and opens a sequenced_packet socket. The socket
  66. * needs to be connected or accepted before data can be sent or received on
  67. * it.
  68. *
  69. * @param io_service The io_service object that the sequenced packet socket
  70. * will use to dispatch handlers for any asynchronous operations performed on
  71. * the socket.
  72. *
  73. * @param protocol An object specifying protocol parameters to be used.
  74. *
  75. * @throws asio::system_error Thrown on failure.
  76. */
  77. basic_seq_packet_socket(asio::io_service& io_service,
  78. const protocol_type& protocol)
  79. : basic_socket<Protocol, SeqPacketSocketService>(io_service, protocol)
  80. {
  81. }
  82. /// Construct a basic_seq_packet_socket, opening it and binding it to the
  83. /// given local endpoint.
  84. /**
  85. * This constructor creates a sequenced packet socket and automatically opens
  86. * it bound to the specified endpoint on the local machine. The protocol used
  87. * is the protocol associated with the given endpoint.
  88. *
  89. * @param io_service The io_service object that the sequenced packet socket
  90. * will use to dispatch handlers for any asynchronous operations performed on
  91. * the socket.
  92. *
  93. * @param endpoint An endpoint on the local machine to which the sequenced
  94. * packet socket will be bound.
  95. *
  96. * @throws asio::system_error Thrown on failure.
  97. */
  98. basic_seq_packet_socket(asio::io_service& io_service,
  99. const endpoint_type& endpoint)
  100. : basic_socket<Protocol, SeqPacketSocketService>(io_service, endpoint)
  101. {
  102. }
  103. /// Construct a basic_seq_packet_socket on an existing native socket.
  104. /**
  105. * This constructor creates a sequenced packet socket object to hold an
  106. * existing native socket.
  107. *
  108. * @param io_service The io_service object that the sequenced packet socket
  109. * will use to dispatch handlers for any asynchronous operations performed on
  110. * the socket.
  111. *
  112. * @param protocol An object specifying protocol parameters to be used.
  113. *
  114. * @param native_socket The new underlying socket implementation.
  115. *
  116. * @throws asio::system_error Thrown on failure.
  117. */
  118. basic_seq_packet_socket(asio::io_service& io_service,
  119. const protocol_type& protocol, const native_handle_type& native_socket)
  120. : basic_socket<Protocol, SeqPacketSocketService>(
  121. io_service, protocol, native_socket)
  122. {
  123. }
  124. #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  125. /// Move-construct a basic_seq_packet_socket from another.
  126. /**
  127. * This constructor moves a sequenced packet socket from one object to
  128. * another.
  129. *
  130. * @param other The other basic_seq_packet_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_seq_packet_socket(io_service&) constructor.
  135. */
  136. basic_seq_packet_socket(basic_seq_packet_socket&& other)
  137. : basic_socket<Protocol, SeqPacketSocketService>(
  138. ASIO_MOVE_CAST(basic_seq_packet_socket)(other))
  139. {
  140. }
  141. /// Move-assign a basic_seq_packet_socket from another.
  142. /**
  143. * This assignment operator moves a sequenced packet socket from one object to
  144. * another.
  145. *
  146. * @param other The other basic_seq_packet_socket object from which the move
  147. * will occur.
  148. *
  149. * @note Following the move, the moved-from object is in the same state as if
  150. * constructed using the @c basic_seq_packet_socket(io_service&) constructor.
  151. */
  152. basic_seq_packet_socket& operator=(basic_seq_packet_socket&& other)
  153. {
  154. basic_socket<Protocol, SeqPacketSocketService>::operator=(
  155. ASIO_MOVE_CAST(basic_seq_packet_socket)(other));
  156. return *this;
  157. }
  158. /// Move-construct a basic_seq_packet_socket from a socket of another protocol
  159. /// type.
  160. /**
  161. * This constructor moves a sequenced packet socket from one object to
  162. * another.
  163. *
  164. * @param other The other basic_seq_packet_socket object from which the move
  165. * will occur.
  166. *
  167. * @note Following the move, the moved-from object is in the same state as if
  168. * constructed using the @c basic_seq_packet_socket(io_service&) constructor.
  169. */
  170. template <typename Protocol1, typename SeqPacketSocketService1>
  171. basic_seq_packet_socket(
  172. basic_seq_packet_socket<Protocol1, SeqPacketSocketService1>&& other,
  173. typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
  174. : basic_socket<Protocol, SeqPacketSocketService>(
  175. ASIO_MOVE_CAST2(basic_seq_packet_socket<
  176. Protocol1, SeqPacketSocketService1>)(other))
  177. {
  178. }
  179. /// Move-assign a basic_seq_packet_socket from a socket of another protocol
  180. /// type.
  181. /**
  182. * This assignment operator moves a sequenced packet socket from one object to
  183. * another.
  184. *
  185. * @param other The other basic_seq_packet_socket object from which the move
  186. * will occur.
  187. *
  188. * @note Following the move, the moved-from object is in the same state as if
  189. * constructed using the @c basic_seq_packet_socket(io_service&) constructor.
  190. */
  191. template <typename Protocol1, typename SeqPacketSocketService1>
  192. typename enable_if<is_convertible<Protocol1, Protocol>::value,
  193. basic_seq_packet_socket>::type& operator=(
  194. basic_seq_packet_socket<Protocol1, SeqPacketSocketService1>&& other)
  195. {
  196. basic_socket<Protocol, SeqPacketSocketService>::operator=(
  197. ASIO_MOVE_CAST2(basic_seq_packet_socket<
  198. Protocol1, SeqPacketSocketService1>)(other));
  199. return *this;
  200. }
  201. #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  202. /// Send some data on the socket.
  203. /**
  204. * This function is used to send data on the sequenced packet socket. The
  205. * function call will block until the data has been sent successfully, or an
  206. * until error occurs.
  207. *
  208. * @param buffers One or more data buffers to be sent on the socket.
  209. *
  210. * @param flags Flags specifying how the send call is to be made.
  211. *
  212. * @returns The number of bytes sent.
  213. *
  214. * @throws asio::system_error Thrown on failure.
  215. *
  216. * @par Example
  217. * To send a single data buffer use the @ref buffer function as follows:
  218. * @code
  219. * socket.send(asio::buffer(data, size), 0);
  220. * @endcode
  221. * See the @ref buffer documentation for information on sending multiple
  222. * buffers in one go, and how to use it with arrays, boost::array or
  223. * std::vector.
  224. */
  225. template <typename ConstBufferSequence>
  226. std::size_t send(const ConstBufferSequence& buffers,
  227. socket_base::message_flags flags)
  228. {
  229. asio::error_code ec;
  230. std::size_t s = this->get_service().send(
  231. this->get_implementation(), buffers, flags, ec);
  232. asio::detail::throw_error(ec, "send");
  233. return s;
  234. }
  235. /// Send some data on the socket.
  236. /**
  237. * This function is used to send data on the sequenced packet socket. The
  238. * function call will block the data has been sent successfully, or an until
  239. * error occurs.
  240. *
  241. * @param buffers One or more data buffers to be sent on the socket.
  242. *
  243. * @param flags Flags specifying how the send call is to be made.
  244. *
  245. * @param ec Set to indicate what error occurred, if any.
  246. *
  247. * @returns The number of bytes sent. Returns 0 if an error occurred.
  248. *
  249. * @note The send operation may not transmit all of the data to the peer.
  250. * Consider using the @ref write function if you need to ensure that all data
  251. * is written before the blocking operation completes.
  252. */
  253. template <typename ConstBufferSequence>
  254. std::size_t send(const ConstBufferSequence& buffers,
  255. socket_base::message_flags flags, asio::error_code& ec)
  256. {
  257. return this->get_service().send(
  258. this->get_implementation(), buffers, flags, ec);
  259. }
  260. /// Start an asynchronous send.
  261. /**
  262. * This function is used to asynchronously send data on the sequenced packet
  263. * socket. The function call always returns immediately.
  264. *
  265. * @param buffers One or more data buffers to be sent on the socket. Although
  266. * the buffers object may be copied as necessary, ownership of the underlying
  267. * memory blocks is retained by the caller, which must guarantee that they
  268. * remain valid until the handler is called.
  269. *
  270. * @param flags Flags specifying how the send call is to be made.
  271. *
  272. * @param handler The handler to be called when the send operation completes.
  273. * Copies will be made of the handler as required. The function signature of
  274. * the handler must be:
  275. * @code void handler(
  276. * const asio::error_code& error, // Result of operation.
  277. * std::size_t bytes_transferred // Number of bytes sent.
  278. * ); @endcode
  279. * Regardless of whether the asynchronous operation completes immediately or
  280. * not, the handler will not be invoked from within this function. Invocation
  281. * of the handler will be performed in a manner equivalent to using
  282. * asio::io_service::post().
  283. *
  284. * @par Example
  285. * To send a single data buffer use the @ref buffer function as follows:
  286. * @code
  287. * socket.async_send(asio::buffer(data, size), 0, handler);
  288. * @endcode
  289. * See the @ref buffer documentation for information on sending multiple
  290. * buffers in one go, and how to use it with arrays, boost::array or
  291. * std::vector.
  292. */
  293. template <typename ConstBufferSequence, typename WriteHandler>
  294. ASIO_INITFN_RESULT_TYPE(WriteHandler,
  295. void (asio::error_code, std::size_t))
  296. async_send(const ConstBufferSequence& buffers,
  297. socket_base::message_flags flags,
  298. ASIO_MOVE_ARG(WriteHandler) handler)
  299. {
  300. // If you get an error on the following line it means that your handler does
  301. // not meet the documented type requirements for a WriteHandler.
  302. ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
  303. return this->get_service().async_send(this->get_implementation(),
  304. buffers, flags, ASIO_MOVE_CAST(WriteHandler)(handler));
  305. }
  306. /// Receive some data on the socket.
  307. /**
  308. * This function is used to receive data on the sequenced packet socket. The
  309. * function call will block until data has been received successfully, or
  310. * until an error occurs.
  311. *
  312. * @param buffers One or more buffers into which the data will be received.
  313. *
  314. * @param out_flags After the receive call completes, contains flags
  315. * associated with the received data. For example, if the
  316. * socket_base::message_end_of_record bit is set then the received data marks
  317. * the end of a record.
  318. *
  319. * @returns The number of bytes received.
  320. *
  321. * @throws asio::system_error Thrown on failure. An error code of
  322. * asio::error::eof indicates that the connection was closed by the
  323. * peer.
  324. *
  325. * @par Example
  326. * To receive into a single data buffer use the @ref buffer function as
  327. * follows:
  328. * @code
  329. * socket.receive(asio::buffer(data, size), out_flags);
  330. * @endcode
  331. * See the @ref buffer documentation for information on receiving into
  332. * multiple buffers in one go, and how to use it with arrays, boost::array or
  333. * std::vector.
  334. */
  335. template <typename MutableBufferSequence>
  336. std::size_t receive(const MutableBufferSequence& buffers,
  337. socket_base::message_flags& out_flags)
  338. {
  339. asio::error_code ec;
  340. std::size_t s = this->get_service().receive(
  341. this->get_implementation(), buffers, 0, out_flags, ec);
  342. asio::detail::throw_error(ec, "receive");
  343. return s;
  344. }
  345. /// Receive some data on the socket.
  346. /**
  347. * This function is used to receive data on the sequenced packet socket. The
  348. * function call will block until data has been received successfully, or
  349. * until an error occurs.
  350. *
  351. * @param buffers One or more buffers into which the data will be received.
  352. *
  353. * @param in_flags Flags specifying how the receive call is to be made.
  354. *
  355. * @param out_flags After the receive call completes, contains flags
  356. * associated with the received data. For example, if the
  357. * socket_base::message_end_of_record bit is set then the received data marks
  358. * the end of a record.
  359. *
  360. * @returns The number of bytes received.
  361. *
  362. * @throws asio::system_error Thrown on failure. An error code of
  363. * asio::error::eof indicates that the connection was closed by the
  364. * peer.
  365. *
  366. * @note The receive operation may not receive all of the requested number of
  367. * bytes. Consider using the @ref read function if you need to ensure that the
  368. * requested amount of data is read before the blocking operation completes.
  369. *
  370. * @par Example
  371. * To receive into a single data buffer use the @ref buffer function as
  372. * follows:
  373. * @code
  374. * socket.receive(asio::buffer(data, size), 0, out_flags);
  375. * @endcode
  376. * See the @ref buffer documentation for information on receiving into
  377. * multiple buffers in one go, and how to use it with arrays, boost::array or
  378. * std::vector.
  379. */
  380. template <typename MutableBufferSequence>
  381. std::size_t receive(const MutableBufferSequence& buffers,
  382. socket_base::message_flags in_flags,
  383. socket_base::message_flags& out_flags)
  384. {
  385. asio::error_code ec;
  386. std::size_t s = this->get_service().receive(
  387. this->get_implementation(), buffers, in_flags, out_flags, ec);
  388. asio::detail::throw_error(ec, "receive");
  389. return s;
  390. }
  391. /// Receive some data on a connected socket.
  392. /**
  393. * This function is used to receive data on the sequenced packet socket. The
  394. * function call will block until data has been received successfully, or
  395. * until an error occurs.
  396. *
  397. * @param buffers One or more buffers into which the data will be received.
  398. *
  399. * @param in_flags Flags specifying how the receive call is to be made.
  400. *
  401. * @param out_flags After the receive call completes, contains flags
  402. * associated with the received data. For example, if the
  403. * socket_base::message_end_of_record bit is set then the received data marks
  404. * the end of a record.
  405. *
  406. * @param ec Set to indicate what error occurred, if any.
  407. *
  408. * @returns The number of bytes received. Returns 0 if an error occurred.
  409. *
  410. * @note The receive operation may not receive all of the requested number of
  411. * bytes. Consider using the @ref read function if you need to ensure that the
  412. * requested amount of data is read before the blocking operation completes.
  413. */
  414. template <typename MutableBufferSequence>
  415. std::size_t receive(const MutableBufferSequence& buffers,
  416. socket_base::message_flags in_flags,
  417. socket_base::message_flags& out_flags, asio::error_code& ec)
  418. {
  419. return this->get_service().receive(this->get_implementation(),
  420. buffers, in_flags, out_flags, ec);
  421. }
  422. /// Start an asynchronous receive.
  423. /**
  424. * This function is used to asynchronously receive data from the sequenced
  425. * packet socket. The function call always returns immediately.
  426. *
  427. * @param buffers One or more buffers into which the data will be received.
  428. * Although the buffers object may be copied as necessary, ownership of the
  429. * underlying memory blocks is retained by the caller, which must guarantee
  430. * that they remain valid until the handler is called.
  431. *
  432. * @param out_flags Once the asynchronous operation completes, contains flags
  433. * associated with the received data. For example, if the
  434. * socket_base::message_end_of_record bit is set then the received data marks
  435. * the end of a record. The caller must guarantee that the referenced
  436. * variable remains valid until the handler is called.
  437. *
  438. * @param handler The handler to be called when the receive operation
  439. * completes. Copies will be made of the handler as required. The function
  440. * signature of the handler must be:
  441. * @code void handler(
  442. * const asio::error_code& error, // Result of operation.
  443. * std::size_t bytes_transferred // Number of bytes received.
  444. * ); @endcode
  445. * Regardless of whether the asynchronous operation completes immediately or
  446. * not, the handler will not be invoked from within this function. Invocation
  447. * of the handler will be performed in a manner equivalent to using
  448. * asio::io_service::post().
  449. *
  450. * @par Example
  451. * To receive into a single data buffer use the @ref buffer function as
  452. * follows:
  453. * @code
  454. * socket.async_receive(asio::buffer(data, size), out_flags, handler);
  455. * @endcode
  456. * See the @ref buffer documentation for information on receiving into
  457. * multiple buffers in one go, and how to use it with arrays, boost::array or
  458. * std::vector.
  459. */
  460. template <typename MutableBufferSequence, typename ReadHandler>
  461. ASIO_INITFN_RESULT_TYPE(ReadHandler,
  462. void (asio::error_code, std::size_t))
  463. async_receive(const MutableBufferSequence& buffers,
  464. socket_base::message_flags& out_flags,
  465. ASIO_MOVE_ARG(ReadHandler) handler)
  466. {
  467. // If you get an error on the following line it means that your handler does
  468. // not meet the documented type requirements for a ReadHandler.
  469. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
  470. return this->get_service().async_receive(
  471. this->get_implementation(), buffers, 0, out_flags,
  472. ASIO_MOVE_CAST(ReadHandler)(handler));
  473. }
  474. /// Start an asynchronous receive.
  475. /**
  476. * This function is used to asynchronously receive data from the sequenced
  477. * data socket. The function call always returns immediately.
  478. *
  479. * @param buffers One or more buffers into which the data will be received.
  480. * Although the buffers object may be copied as necessary, ownership of the
  481. * underlying memory blocks is retained by the caller, which must guarantee
  482. * that they remain valid until the handler is called.
  483. *
  484. * @param in_flags Flags specifying how the receive call is to be made.
  485. *
  486. * @param out_flags Once the asynchronous operation completes, contains flags
  487. * associated with the received data. For example, if the
  488. * socket_base::message_end_of_record bit is set then the received data marks
  489. * the end of a record. The caller must guarantee that the referenced
  490. * variable remains valid until the handler is called.
  491. *
  492. * @param handler The handler to be called when the receive operation
  493. * completes. Copies will be made of the handler as required. The function
  494. * signature of the handler must be:
  495. * @code void handler(
  496. * const asio::error_code& error, // Result of operation.
  497. * std::size_t bytes_transferred // Number of bytes received.
  498. * ); @endcode
  499. * Regardless of whether the asynchronous operation completes immediately or
  500. * not, the handler will not be invoked from within this function. Invocation
  501. * of the handler will be performed in a manner equivalent to using
  502. * asio::io_service::post().
  503. *
  504. * @par Example
  505. * To receive into a single data buffer use the @ref buffer function as
  506. * follows:
  507. * @code
  508. * socket.async_receive(
  509. * asio::buffer(data, size),
  510. * 0, out_flags, handler);
  511. * @endcode
  512. * See the @ref buffer documentation for information on receiving into
  513. * multiple buffers in one go, and how to use it with arrays, boost::array or
  514. * std::vector.
  515. */
  516. template <typename MutableBufferSequence, typename ReadHandler>
  517. ASIO_INITFN_RESULT_TYPE(ReadHandler,
  518. void (asio::error_code, std::size_t))
  519. async_receive(const MutableBufferSequence& buffers,
  520. socket_base::message_flags in_flags,
  521. socket_base::message_flags& out_flags,
  522. ASIO_MOVE_ARG(ReadHandler) handler)
  523. {
  524. // If you get an error on the following line it means that your handler does
  525. // not meet the documented type requirements for a ReadHandler.
  526. ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
  527. return this->get_service().async_receive(
  528. this->get_implementation(), buffers, in_flags, out_flags,
  529. ASIO_MOVE_CAST(ReadHandler)(handler));
  530. }
  531. };
  532. } // namespace asio
  533. #include "asio/detail/pop_options.hpp"
  534. #endif // ASIO_BASIC_SEQ_PACKET_SOCKET_HPP