|
||||
File indexing completed on 2025-01-18 09:29:05
0001 // 0002 // basic_seq_packet_socket.hpp 0003 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 0004 // 0005 // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) 0006 // 0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying 0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 0009 // 0010 0011 #ifndef BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_HPP 0012 #define BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_HPP 0013 0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 0015 # pragma once 0016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 0017 0018 #include <boost/asio/detail/config.hpp> 0019 #include <cstddef> 0020 #include <boost/asio/basic_socket.hpp> 0021 #include <boost/asio/detail/handler_type_requirements.hpp> 0022 #include <boost/asio/detail/throw_error.hpp> 0023 #include <boost/asio/error.hpp> 0024 0025 #include <boost/asio/detail/push_options.hpp> 0026 0027 namespace boost { 0028 namespace asio { 0029 0030 #if !defined(BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL) 0031 #define BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL 0032 0033 // Forward declaration with defaulted arguments. 0034 template <typename Protocol, typename Executor = any_io_executor> 0035 class basic_seq_packet_socket; 0036 0037 #endif // !defined(BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL) 0038 0039 /// Provides sequenced packet socket functionality. 0040 /** 0041 * The basic_seq_packet_socket class template provides asynchronous and blocking 0042 * sequenced packet socket functionality. 0043 * 0044 * @par Thread Safety 0045 * @e Distinct @e objects: Safe.@n 0046 * @e Shared @e objects: Unsafe. 0047 * 0048 * Synchronous @c send, @c receive, @c connect, and @c shutdown operations are 0049 * thread safe with respect to each other, if the underlying operating system 0050 * calls are also thread safe. This means that it is permitted to perform 0051 * concurrent calls to these synchronous operations on a single socket object. 0052 * Other synchronous operations, such as @c open or @c close, are not thread 0053 * safe. 0054 */ 0055 template <typename Protocol, typename Executor> 0056 class basic_seq_packet_socket 0057 : public basic_socket<Protocol, Executor> 0058 { 0059 private: 0060 class initiate_async_send; 0061 class initiate_async_receive_with_flags; 0062 0063 public: 0064 /// The type of the executor associated with the object. 0065 typedef Executor executor_type; 0066 0067 /// Rebinds the socket type to another executor. 0068 template <typename Executor1> 0069 struct rebind_executor 0070 { 0071 /// The socket type when rebound to the specified executor. 0072 typedef basic_seq_packet_socket<Protocol, Executor1> other; 0073 }; 0074 0075 /// The native representation of a socket. 0076 #if defined(GENERATING_DOCUMENTATION) 0077 typedef implementation_defined native_handle_type; 0078 #else 0079 typedef typename basic_socket<Protocol, 0080 Executor>::native_handle_type native_handle_type; 0081 #endif 0082 0083 /// The protocol type. 0084 typedef Protocol protocol_type; 0085 0086 /// The endpoint type. 0087 typedef typename Protocol::endpoint endpoint_type; 0088 0089 /// Construct a basic_seq_packet_socket without opening it. 0090 /** 0091 * This constructor creates a sequenced packet socket without opening it. The 0092 * socket needs to be opened and then connected or accepted before data can 0093 * be sent or received on it. 0094 * 0095 * @param ex The I/O executor that the socket will use, by default, to 0096 * dispatch handlers for any asynchronous operations performed on the socket. 0097 */ 0098 explicit basic_seq_packet_socket(const executor_type& ex) 0099 : basic_socket<Protocol, Executor>(ex) 0100 { 0101 } 0102 0103 /// Construct a basic_seq_packet_socket without opening it. 0104 /** 0105 * This constructor creates a sequenced packet socket without opening it. The 0106 * socket needs to be opened and then connected or accepted before data can 0107 * be sent or received on it. 0108 * 0109 * @param context An execution context which provides the I/O executor that 0110 * the socket will use, by default, to dispatch handlers for any asynchronous 0111 * operations performed on the socket. 0112 */ 0113 template <typename ExecutionContext> 0114 explicit basic_seq_packet_socket(ExecutionContext& context, 0115 constraint_t< 0116 is_convertible<ExecutionContext&, execution_context&>::value 0117 > = 0) 0118 : basic_socket<Protocol, Executor>(context) 0119 { 0120 } 0121 0122 /// Construct and open a basic_seq_packet_socket. 0123 /** 0124 * This constructor creates and opens a sequenced_packet socket. The socket 0125 * needs to be connected or accepted before data can be sent or received on 0126 * it. 0127 * 0128 * @param ex The I/O executor that the socket will use, by default, to 0129 * dispatch handlers for any asynchronous operations performed on the socket. 0130 * 0131 * @param protocol An object specifying protocol parameters to be used. 0132 * 0133 * @throws boost::system::system_error Thrown on failure. 0134 */ 0135 basic_seq_packet_socket(const executor_type& ex, 0136 const protocol_type& protocol) 0137 : basic_socket<Protocol, Executor>(ex, protocol) 0138 { 0139 } 0140 0141 /// Construct and open a basic_seq_packet_socket. 0142 /** 0143 * This constructor creates and opens a sequenced_packet socket. The socket 0144 * needs to be connected or accepted before data can be sent or received on 0145 * it. 0146 * 0147 * @param context An execution context which provides the I/O executor that 0148 * the socket will use, by default, to dispatch handlers for any asynchronous 0149 * operations performed on the socket. 0150 * 0151 * @param protocol An object specifying protocol parameters to be used. 0152 * 0153 * @throws boost::system::system_error Thrown on failure. 0154 */ 0155 template <typename ExecutionContext> 0156 basic_seq_packet_socket(ExecutionContext& context, 0157 const protocol_type& protocol, 0158 constraint_t< 0159 is_convertible<ExecutionContext&, execution_context&>::value, 0160 defaulted_constraint 0161 > = defaulted_constraint()) 0162 : basic_socket<Protocol, Executor>(context, protocol) 0163 { 0164 } 0165 0166 /// Construct a basic_seq_packet_socket, opening it and binding it to the 0167 /// given local endpoint. 0168 /** 0169 * This constructor creates a sequenced packet socket and automatically opens 0170 * it bound to the specified endpoint on the local machine. The protocol used 0171 * is the protocol associated with the given endpoint. 0172 * 0173 * @param ex The I/O executor that the socket will use, by default, to 0174 * dispatch handlers for any asynchronous operations performed on the socket. 0175 * 0176 * @param endpoint An endpoint on the local machine to which the sequenced 0177 * packet socket will be bound. 0178 * 0179 * @throws boost::system::system_error Thrown on failure. 0180 */ 0181 basic_seq_packet_socket(const executor_type& ex, 0182 const endpoint_type& endpoint) 0183 : basic_socket<Protocol, Executor>(ex, endpoint) 0184 { 0185 } 0186 0187 /// Construct a basic_seq_packet_socket, opening it and binding it to the 0188 /// given local endpoint. 0189 /** 0190 * This constructor creates a sequenced packet socket and automatically opens 0191 * it bound to the specified endpoint on the local machine. The protocol used 0192 * is the protocol associated with the given endpoint. 0193 * 0194 * @param context An execution context which provides the I/O executor that 0195 * the socket will use, by default, to dispatch handlers for any asynchronous 0196 * operations performed on the socket. 0197 * 0198 * @param endpoint An endpoint on the local machine to which the sequenced 0199 * packet socket will be bound. 0200 * 0201 * @throws boost::system::system_error Thrown on failure. 0202 */ 0203 template <typename ExecutionContext> 0204 basic_seq_packet_socket(ExecutionContext& context, 0205 const endpoint_type& endpoint, 0206 constraint_t< 0207 is_convertible<ExecutionContext&, execution_context&>::value 0208 > = 0) 0209 : basic_socket<Protocol, Executor>(context, endpoint) 0210 { 0211 } 0212 0213 /// Construct a basic_seq_packet_socket on an existing native socket. 0214 /** 0215 * This constructor creates a sequenced packet socket object to hold an 0216 * existing native socket. 0217 * 0218 * @param ex The I/O executor that the socket will use, by default, to 0219 * dispatch handlers for any asynchronous operations performed on the socket. 0220 * 0221 * @param protocol An object specifying protocol parameters to be used. 0222 * 0223 * @param native_socket The new underlying socket implementation. 0224 * 0225 * @throws boost::system::system_error Thrown on failure. 0226 */ 0227 basic_seq_packet_socket(const executor_type& ex, 0228 const protocol_type& protocol, const native_handle_type& native_socket) 0229 : basic_socket<Protocol, Executor>(ex, protocol, native_socket) 0230 { 0231 } 0232 0233 /// Construct a basic_seq_packet_socket on an existing native socket. 0234 /** 0235 * This constructor creates a sequenced packet socket object to hold an 0236 * existing native socket. 0237 * 0238 * @param context An execution context which provides the I/O executor that 0239 * the socket will use, by default, to dispatch handlers for any asynchronous 0240 * operations performed on the socket. 0241 * 0242 * @param protocol An object specifying protocol parameters to be used. 0243 * 0244 * @param native_socket The new underlying socket implementation. 0245 * 0246 * @throws boost::system::system_error Thrown on failure. 0247 */ 0248 template <typename ExecutionContext> 0249 basic_seq_packet_socket(ExecutionContext& context, 0250 const protocol_type& protocol, const native_handle_type& native_socket, 0251 constraint_t< 0252 is_convertible<ExecutionContext&, execution_context&>::value 0253 > = 0) 0254 : basic_socket<Protocol, Executor>(context, protocol, native_socket) 0255 { 0256 } 0257 0258 /// Move-construct a basic_seq_packet_socket from another. 0259 /** 0260 * This constructor moves a sequenced packet socket from one object to 0261 * another. 0262 * 0263 * @param other The other basic_seq_packet_socket object from which the move 0264 * will occur. 0265 * 0266 * @note Following the move, the moved-from object is in the same state as if 0267 * constructed using the @c basic_seq_packet_socket(const executor_type&) 0268 * constructor. 0269 */ 0270 basic_seq_packet_socket(basic_seq_packet_socket&& other) noexcept 0271 : basic_socket<Protocol, Executor>(std::move(other)) 0272 { 0273 } 0274 0275 /// Move-assign a basic_seq_packet_socket from another. 0276 /** 0277 * This assignment operator moves a sequenced packet socket from one object to 0278 * another. 0279 * 0280 * @param other The other basic_seq_packet_socket object from which the move 0281 * will occur. 0282 * 0283 * @note Following the move, the moved-from object is in the same state as if 0284 * constructed using the @c basic_seq_packet_socket(const executor_type&) 0285 * constructor. 0286 */ 0287 basic_seq_packet_socket& operator=(basic_seq_packet_socket&& other) 0288 { 0289 basic_socket<Protocol, Executor>::operator=(std::move(other)); 0290 return *this; 0291 } 0292 0293 /// Move-construct a basic_seq_packet_socket from a socket of another protocol 0294 /// type. 0295 /** 0296 * This constructor moves a sequenced packet socket from one object to 0297 * another. 0298 * 0299 * @param other The other basic_seq_packet_socket object from which the move 0300 * will occur. 0301 * 0302 * @note Following the move, the moved-from object is in the same state as if 0303 * constructed using the @c basic_seq_packet_socket(const executor_type&) 0304 * constructor. 0305 */ 0306 template <typename Protocol1, typename Executor1> 0307 basic_seq_packet_socket(basic_seq_packet_socket<Protocol1, Executor1>&& other, 0308 constraint_t< 0309 is_convertible<Protocol1, Protocol>::value 0310 && is_convertible<Executor1, Executor>::value 0311 > = 0) 0312 : basic_socket<Protocol, Executor>(std::move(other)) 0313 { 0314 } 0315 0316 /// Move-assign a basic_seq_packet_socket from a socket of another protocol 0317 /// type. 0318 /** 0319 * This assignment operator moves a sequenced packet socket from one object to 0320 * another. 0321 * 0322 * @param other The other basic_seq_packet_socket object from which the move 0323 * will occur. 0324 * 0325 * @note Following the move, the moved-from object is in the same state as if 0326 * constructed using the @c basic_seq_packet_socket(const executor_type&) 0327 * constructor. 0328 */ 0329 template <typename Protocol1, typename Executor1> 0330 constraint_t< 0331 is_convertible<Protocol1, Protocol>::value 0332 && is_convertible<Executor1, Executor>::value, 0333 basic_seq_packet_socket& 0334 > operator=(basic_seq_packet_socket<Protocol1, Executor1>&& other) 0335 { 0336 basic_socket<Protocol, Executor>::operator=(std::move(other)); 0337 return *this; 0338 } 0339 0340 /// Destroys the socket. 0341 /** 0342 * This function destroys the socket, cancelling any outstanding asynchronous 0343 * operations associated with the socket as if by calling @c cancel. 0344 */ 0345 ~basic_seq_packet_socket() 0346 { 0347 } 0348 0349 /// Send some data on the socket. 0350 /** 0351 * This function is used to send data on the sequenced packet socket. The 0352 * function call will block until the data has been sent successfully, or an 0353 * until error occurs. 0354 * 0355 * @param buffers One or more data buffers to be sent on the socket. 0356 * 0357 * @param flags Flags specifying how the send call is to be made. 0358 * 0359 * @returns The number of bytes sent. 0360 * 0361 * @throws boost::system::system_error Thrown on failure. 0362 * 0363 * @par Example 0364 * To send a single data buffer use the @ref buffer function as follows: 0365 * @code 0366 * socket.send(boost::asio::buffer(data, size), 0); 0367 * @endcode 0368 * See the @ref buffer documentation for information on sending multiple 0369 * buffers in one go, and how to use it with arrays, boost::array or 0370 * std::vector. 0371 */ 0372 template <typename ConstBufferSequence> 0373 std::size_t send(const ConstBufferSequence& buffers, 0374 socket_base::message_flags flags) 0375 { 0376 boost::system::error_code ec; 0377 std::size_t s = this->impl_.get_service().send( 0378 this->impl_.get_implementation(), buffers, flags, ec); 0379 boost::asio::detail::throw_error(ec, "send"); 0380 return s; 0381 } 0382 0383 /// Send some data on the socket. 0384 /** 0385 * This function is used to send data on the sequenced packet socket. The 0386 * function call will block the data has been sent successfully, or an until 0387 * error occurs. 0388 * 0389 * @param buffers One or more data buffers to be sent on the socket. 0390 * 0391 * @param flags Flags specifying how the send call is to be made. 0392 * 0393 * @param ec Set to indicate what error occurred, if any. 0394 * 0395 * @returns The number of bytes sent. Returns 0 if an error occurred. 0396 * 0397 * @note The send operation may not transmit all of the data to the peer. 0398 * Consider using the @ref write function if you need to ensure that all data 0399 * is written before the blocking operation completes. 0400 */ 0401 template <typename ConstBufferSequence> 0402 std::size_t send(const ConstBufferSequence& buffers, 0403 socket_base::message_flags flags, boost::system::error_code& ec) 0404 { 0405 return this->impl_.get_service().send( 0406 this->impl_.get_implementation(), buffers, flags, ec); 0407 } 0408 0409 /// Start an asynchronous send. 0410 /** 0411 * This function is used to asynchronously send data on the sequenced packet 0412 * socket. It is an initiating function for an @ref asynchronous_operation, 0413 * and always returns immediately. 0414 * 0415 * @param buffers One or more data buffers to be sent on the socket. Although 0416 * the buffers object may be copied as necessary, ownership of the underlying 0417 * memory blocks is retained by the caller, which must guarantee that they 0418 * remain valid until the completion handler is called. 0419 * 0420 * @param flags Flags specifying how the send call is to be made. 0421 * 0422 * @param token The @ref completion_token that will be used to produce a 0423 * completion handler, which will be called when the send completes. 0424 * Potential completion tokens include @ref use_future, @ref use_awaitable, 0425 * @ref yield_context, or a function object with the correct completion 0426 * signature. The function signature of the completion handler must be: 0427 * @code void handler( 0428 * const boost::system::error_code& error, // Result of operation. 0429 * std::size_t bytes_transferred // Number of bytes sent. 0430 * ); @endcode 0431 * Regardless of whether the asynchronous operation completes immediately or 0432 * not, the completion handler will not be invoked from within this function. 0433 * On immediate completion, invocation of the handler will be performed in a 0434 * manner equivalent to using boost::asio::post(). 0435 * 0436 * @par Completion Signature 0437 * @code void(boost::system::error_code, std::size_t) @endcode 0438 * 0439 * @par Example 0440 * To send a single data buffer use the @ref buffer function as follows: 0441 * @code 0442 * socket.async_send(boost::asio::buffer(data, size), 0, handler); 0443 * @endcode 0444 * See the @ref buffer documentation for information on sending multiple 0445 * buffers in one go, and how to use it with arrays, boost::array or 0446 * std::vector. 0447 * 0448 * @par Per-Operation Cancellation 0449 * On POSIX or Windows operating systems, this asynchronous operation supports 0450 * cancellation for the following boost::asio::cancellation_type values: 0451 * 0452 * @li @c cancellation_type::terminal 0453 * 0454 * @li @c cancellation_type::partial 0455 * 0456 * @li @c cancellation_type::total 0457 */ 0458 template <typename ConstBufferSequence, 0459 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, 0460 std::size_t)) WriteToken 0461 = default_completion_token_t<executor_type>> 0462 auto async_send(const ConstBufferSequence& buffers, 0463 socket_base::message_flags flags, 0464 WriteToken&& token 0465 = default_completion_token_t<executor_type>()) 0466 -> decltype( 0467 async_initiate<WriteToken, 0468 void (boost::system::error_code, std::size_t)>( 0469 declval<initiate_async_send>(), token, buffers, flags)) 0470 { 0471 return async_initiate<WriteToken, 0472 void (boost::system::error_code, std::size_t)>( 0473 initiate_async_send(this), token, buffers, flags); 0474 } 0475 0476 /// Receive some data on the socket. 0477 /** 0478 * This function is used to receive data on the sequenced packet socket. The 0479 * function call will block until data has been received successfully, or 0480 * until an error occurs. 0481 * 0482 * @param buffers One or more buffers into which the data will be received. 0483 * 0484 * @param out_flags After the receive call completes, contains flags 0485 * associated with the received data. For example, if the 0486 * socket_base::message_end_of_record bit is set then the received data marks 0487 * the end of a record. 0488 * 0489 * @returns The number of bytes received. 0490 * 0491 * @throws boost::system::system_error Thrown on failure. An error code of 0492 * boost::asio::error::eof indicates that the connection was closed by the 0493 * peer. 0494 * 0495 * @par Example 0496 * To receive into a single data buffer use the @ref buffer function as 0497 * follows: 0498 * @code 0499 * socket.receive(boost::asio::buffer(data, size), out_flags); 0500 * @endcode 0501 * See the @ref buffer documentation for information on receiving into 0502 * multiple buffers in one go, and how to use it with arrays, boost::array or 0503 * std::vector. 0504 */ 0505 template <typename MutableBufferSequence> 0506 std::size_t receive(const MutableBufferSequence& buffers, 0507 socket_base::message_flags& out_flags) 0508 { 0509 boost::system::error_code ec; 0510 std::size_t s = this->impl_.get_service().receive_with_flags( 0511 this->impl_.get_implementation(), buffers, 0, out_flags, ec); 0512 boost::asio::detail::throw_error(ec, "receive"); 0513 return s; 0514 } 0515 0516 /// Receive some data on the socket. 0517 /** 0518 * This function is used to receive data on the sequenced packet socket. The 0519 * function call will block until data has been received successfully, or 0520 * until an error occurs. 0521 * 0522 * @param buffers One or more buffers into which the data will be received. 0523 * 0524 * @param in_flags Flags specifying how the receive call is to be made. 0525 * 0526 * @param out_flags After the receive call completes, contains flags 0527 * associated with the received data. For example, if the 0528 * socket_base::message_end_of_record bit is set then the received data marks 0529 * the end of a record. 0530 * 0531 * @returns The number of bytes received. 0532 * 0533 * @throws boost::system::system_error Thrown on failure. An error code of 0534 * boost::asio::error::eof indicates that the connection was closed by the 0535 * peer. 0536 * 0537 * @note The receive operation may not receive all of the requested number of 0538 * bytes. Consider using the @ref read function if you need to ensure that the 0539 * requested amount of data is read before the blocking operation completes. 0540 * 0541 * @par Example 0542 * To receive into a single data buffer use the @ref buffer function as 0543 * follows: 0544 * @code 0545 * socket.receive(boost::asio::buffer(data, size), 0, out_flags); 0546 * @endcode 0547 * See the @ref buffer documentation for information on receiving into 0548 * multiple buffers in one go, and how to use it with arrays, boost::array or 0549 * std::vector. 0550 */ 0551 template <typename MutableBufferSequence> 0552 std::size_t receive(const MutableBufferSequence& buffers, 0553 socket_base::message_flags in_flags, 0554 socket_base::message_flags& out_flags) 0555 { 0556 boost::system::error_code ec; 0557 std::size_t s = this->impl_.get_service().receive_with_flags( 0558 this->impl_.get_implementation(), buffers, in_flags, out_flags, ec); 0559 boost::asio::detail::throw_error(ec, "receive"); 0560 return s; 0561 } 0562 0563 /// Receive some data on a connected socket. 0564 /** 0565 * This function is used to receive data on the sequenced packet socket. The 0566 * function call will block until data has been received successfully, or 0567 * until an error occurs. 0568 * 0569 * @param buffers One or more buffers into which the data will be received. 0570 * 0571 * @param in_flags Flags specifying how the receive call is to be made. 0572 * 0573 * @param out_flags After the receive call completes, contains flags 0574 * associated with the received data. For example, if the 0575 * socket_base::message_end_of_record bit is set then the received data marks 0576 * the end of a record. 0577 * 0578 * @param ec Set to indicate what error occurred, if any. 0579 * 0580 * @returns The number of bytes received. Returns 0 if an error occurred. 0581 * 0582 * @note The receive operation may not receive all of the requested number of 0583 * bytes. Consider using the @ref read function if you need to ensure that the 0584 * requested amount of data is read before the blocking operation completes. 0585 */ 0586 template <typename MutableBufferSequence> 0587 std::size_t receive(const MutableBufferSequence& buffers, 0588 socket_base::message_flags in_flags, 0589 socket_base::message_flags& out_flags, boost::system::error_code& ec) 0590 { 0591 return this->impl_.get_service().receive_with_flags( 0592 this->impl_.get_implementation(), buffers, in_flags, out_flags, ec); 0593 } 0594 0595 /// Start an asynchronous receive. 0596 /** 0597 * This function is used to asynchronously receive data from the sequenced 0598 * packet socket. It is an initiating function for an @ref 0599 * asynchronous_operation, and always returns immediately. 0600 * 0601 * @param buffers One or more buffers into which the data will be received. 0602 * Although the buffers object may be copied as necessary, ownership of the 0603 * underlying memory blocks is retained by the caller, which must guarantee 0604 * that they remain valid until the completion handler is called. 0605 * 0606 * @param out_flags Once the asynchronous operation completes, contains flags 0607 * associated with the received data. For example, if the 0608 * socket_base::message_end_of_record bit is set then the received data marks 0609 * the end of a record. The caller must guarantee that the referenced 0610 * variable remains valid until the completion handler is called. 0611 * 0612 * @param token The @ref completion_token that will be used to produce a 0613 * completion handler, which will be called when the receive completes. 0614 * Potential completion tokens include @ref use_future, @ref use_awaitable, 0615 * @ref yield_context, or a function object with the correct completion 0616 * signature. The function signature of the completion handler must be: 0617 * @code void handler( 0618 * const boost::system::error_code& error, // Result of operation. 0619 * std::size_t bytes_transferred // Number of bytes received. 0620 * ); @endcode 0621 * Regardless of whether the asynchronous operation completes immediately or 0622 * not, the completion handler will not be invoked from within this function. 0623 * On immediate completion, invocation of the handler will be performed in a 0624 * manner equivalent to using boost::asio::post(). 0625 * 0626 * @par Completion Signature 0627 * @code void(boost::system::error_code, std::size_t) @endcode 0628 * 0629 * @par Example 0630 * To receive into a single data buffer use the @ref buffer function as 0631 * follows: 0632 * @code 0633 * socket.async_receive(boost::asio::buffer(data, size), out_flags, handler); 0634 * @endcode 0635 * See the @ref buffer documentation for information on receiving into 0636 * multiple buffers in one go, and how to use it with arrays, boost::array or 0637 * std::vector. 0638 * 0639 * @par Per-Operation Cancellation 0640 * On POSIX or Windows operating systems, this asynchronous operation supports 0641 * cancellation for the following boost::asio::cancellation_type values: 0642 * 0643 * @li @c cancellation_type::terminal 0644 * 0645 * @li @c cancellation_type::partial 0646 * 0647 * @li @c cancellation_type::total 0648 */ 0649 template <typename MutableBufferSequence, 0650 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, 0651 std::size_t)) ReadToken = default_completion_token_t<executor_type>> 0652 auto async_receive(const MutableBufferSequence& buffers, 0653 socket_base::message_flags& out_flags, 0654 ReadToken&& token = default_completion_token_t<executor_type>()) 0655 -> decltype( 0656 async_initiate<ReadToken, 0657 void (boost::system::error_code, std::size_t)>( 0658 declval<initiate_async_receive_with_flags>(), token, 0659 buffers, socket_base::message_flags(0), &out_flags)) 0660 { 0661 return async_initiate<ReadToken, 0662 void (boost::system::error_code, std::size_t)>( 0663 initiate_async_receive_with_flags(this), token, 0664 buffers, socket_base::message_flags(0), &out_flags); 0665 } 0666 0667 /// Start an asynchronous receive. 0668 /** 0669 * This function is used to asynchronously receive data from the sequenced 0670 * data socket. It is an initiating function for an @ref 0671 * asynchronous_operation, and always returns immediately. 0672 * 0673 * @param buffers One or more buffers into which the data will be received. 0674 * Although the buffers object may be copied as necessary, ownership of the 0675 * underlying memory blocks is retained by the caller, which must guarantee 0676 * that they remain valid until the completion handler is called. 0677 * 0678 * @param in_flags Flags specifying how the receive call is to be made. 0679 * 0680 * @param out_flags Once the asynchronous operation completes, contains flags 0681 * associated with the received data. For example, if the 0682 * socket_base::message_end_of_record bit is set then the received data marks 0683 * the end of a record. The caller must guarantee that the referenced 0684 * variable remains valid until the completion handler is called. 0685 * 0686 * @param token The @ref completion_token that will be used to produce a 0687 * completion handler, which will be called when the receive completes. 0688 * Potential completion tokens include @ref use_future, @ref use_awaitable, 0689 * @ref yield_context, or a function object with the correct completion 0690 * signature. The function signature of the completion handler must be: 0691 * @code void handler( 0692 * const boost::system::error_code& error, // Result of operation. 0693 * std::size_t bytes_transferred // Number of bytes received. 0694 * ); @endcode 0695 * Regardless of whether the asynchronous operation completes immediately or 0696 * not, the completion handler will not be invoked from within this function. 0697 * On immediate completion, invocation of the handler will be performed in a 0698 * manner equivalent to using boost::asio::post(). 0699 * 0700 * @par Completion Signature 0701 * @code void(boost::system::error_code, std::size_t) @endcode 0702 * 0703 * @par Example 0704 * To receive into a single data buffer use the @ref buffer function as 0705 * follows: 0706 * @code 0707 * socket.async_receive( 0708 * boost::asio::buffer(data, size), 0709 * 0, out_flags, handler); 0710 * @endcode 0711 * See the @ref buffer documentation for information on receiving into 0712 * multiple buffers in one go, and how to use it with arrays, boost::array or 0713 * std::vector. 0714 * 0715 * @par Per-Operation Cancellation 0716 * On POSIX or Windows operating systems, this asynchronous operation supports 0717 * cancellation for the following boost::asio::cancellation_type values: 0718 * 0719 * @li @c cancellation_type::terminal 0720 * 0721 * @li @c cancellation_type::partial 0722 * 0723 * @li @c cancellation_type::total 0724 */ 0725 template <typename MutableBufferSequence, 0726 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, 0727 std::size_t)) ReadToken = default_completion_token_t<executor_type>> 0728 auto async_receive(const MutableBufferSequence& buffers, 0729 socket_base::message_flags in_flags, 0730 socket_base::message_flags& out_flags, 0731 ReadToken&& token = default_completion_token_t<executor_type>()) 0732 -> decltype( 0733 async_initiate<ReadToken, 0734 void (boost::system::error_code, std::size_t)>( 0735 declval<initiate_async_receive_with_flags>(), 0736 token, buffers, in_flags, &out_flags)) 0737 { 0738 return async_initiate<ReadToken, 0739 void (boost::system::error_code, std::size_t)>( 0740 initiate_async_receive_with_flags(this), 0741 token, buffers, in_flags, &out_flags); 0742 } 0743 0744 private: 0745 // Disallow copying and assignment. 0746 basic_seq_packet_socket(const basic_seq_packet_socket&) = delete; 0747 basic_seq_packet_socket& operator=( 0748 const basic_seq_packet_socket&) = delete; 0749 0750 class initiate_async_send 0751 { 0752 public: 0753 typedef Executor executor_type; 0754 0755 explicit initiate_async_send(basic_seq_packet_socket* self) 0756 : self_(self) 0757 { 0758 } 0759 0760 const executor_type& get_executor() const noexcept 0761 { 0762 return self_->get_executor(); 0763 } 0764 0765 template <typename WriteHandler, typename ConstBufferSequence> 0766 void operator()(WriteHandler&& handler, 0767 const ConstBufferSequence& buffers, 0768 socket_base::message_flags flags) const 0769 { 0770 // If you get an error on the following line it means that your handler 0771 // does not meet the documented type requirements for a WriteHandler. 0772 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; 0773 0774 detail::non_const_lvalue<WriteHandler> handler2(handler); 0775 self_->impl_.get_service().async_send( 0776 self_->impl_.get_implementation(), buffers, flags, 0777 handler2.value, self_->impl_.get_executor()); 0778 } 0779 0780 private: 0781 basic_seq_packet_socket* self_; 0782 }; 0783 0784 class initiate_async_receive_with_flags 0785 { 0786 public: 0787 typedef Executor executor_type; 0788 0789 explicit initiate_async_receive_with_flags(basic_seq_packet_socket* self) 0790 : self_(self) 0791 { 0792 } 0793 0794 const executor_type& get_executor() const noexcept 0795 { 0796 return self_->get_executor(); 0797 } 0798 0799 template <typename ReadHandler, typename MutableBufferSequence> 0800 void operator()(ReadHandler&& handler, 0801 const MutableBufferSequence& buffers, 0802 socket_base::message_flags in_flags, 0803 socket_base::message_flags* out_flags) const 0804 { 0805 // If you get an error on the following line it means that your handler 0806 // does not meet the documented type requirements for a ReadHandler. 0807 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; 0808 0809 detail::non_const_lvalue<ReadHandler> handler2(handler); 0810 self_->impl_.get_service().async_receive_with_flags( 0811 self_->impl_.get_implementation(), buffers, in_flags, 0812 *out_flags, handler2.value, self_->impl_.get_executor()); 0813 } 0814 0815 private: 0816 basic_seq_packet_socket* self_; 0817 }; 0818 }; 0819 0820 } // namespace asio 0821 } // namespace boost 0822 0823 #include <boost/asio/detail/pop_options.hpp> 0824 0825 #endif // BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_HPP
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |