basic_seq_packet_socket.hpp 22 KB

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