|
||||
File indexing completed on 2025-01-18 09:29:06
0001 // 0002 // basic_stream_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_STREAM_SOCKET_HPP 0012 #define BOOST_ASIO_BASIC_STREAM_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/async_result.hpp> 0021 #include <boost/asio/basic_socket.hpp> 0022 #include <boost/asio/detail/handler_type_requirements.hpp> 0023 #include <boost/asio/detail/non_const_lvalue.hpp> 0024 #include <boost/asio/detail/throw_error.hpp> 0025 #include <boost/asio/error.hpp> 0026 0027 #include <boost/asio/detail/push_options.hpp> 0028 0029 namespace boost { 0030 namespace asio { 0031 0032 #if !defined(BOOST_ASIO_BASIC_STREAM_SOCKET_FWD_DECL) 0033 #define BOOST_ASIO_BASIC_STREAM_SOCKET_FWD_DECL 0034 0035 // Forward declaration with defaulted arguments. 0036 template <typename Protocol, typename Executor = any_io_executor> 0037 class basic_stream_socket; 0038 0039 #endif // !defined(BOOST_ASIO_BASIC_STREAM_SOCKET_FWD_DECL) 0040 0041 /// Provides stream-oriented socket functionality. 0042 /** 0043 * The basic_stream_socket class template provides asynchronous and blocking 0044 * stream-oriented socket functionality. 0045 * 0046 * @par Thread Safety 0047 * @e Distinct @e objects: Safe.@n 0048 * @e Shared @e objects: Unsafe. 0049 * 0050 * Synchronous @c send, @c receive, @c connect, and @c shutdown operations are 0051 * thread safe with respect to each other, if the underlying operating system 0052 * calls are also thread safe. This means that it is permitted to perform 0053 * concurrent calls to these synchronous operations on a single socket object. 0054 * Other synchronous operations, such as @c open or @c close, are not thread 0055 * safe. 0056 * 0057 * @par Concepts: 0058 * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. 0059 */ 0060 template <typename Protocol, typename Executor> 0061 class basic_stream_socket 0062 : public basic_socket<Protocol, Executor> 0063 { 0064 private: 0065 class initiate_async_send; 0066 class initiate_async_receive; 0067 0068 public: 0069 /// The type of the executor associated with the object. 0070 typedef Executor executor_type; 0071 0072 /// Rebinds the socket type to another executor. 0073 template <typename Executor1> 0074 struct rebind_executor 0075 { 0076 /// The socket type when rebound to the specified executor. 0077 typedef basic_stream_socket<Protocol, Executor1> other; 0078 }; 0079 0080 /// The native representation of a socket. 0081 #if defined(GENERATING_DOCUMENTATION) 0082 typedef implementation_defined native_handle_type; 0083 #else 0084 typedef typename basic_socket<Protocol, 0085 Executor>::native_handle_type native_handle_type; 0086 #endif 0087 0088 /// The protocol type. 0089 typedef Protocol protocol_type; 0090 0091 /// The endpoint type. 0092 typedef typename Protocol::endpoint endpoint_type; 0093 0094 /// Construct a basic_stream_socket without opening it. 0095 /** 0096 * This constructor creates a stream socket without opening it. The socket 0097 * needs to be opened and then connected or accepted before data can be sent 0098 * or received on it. 0099 * 0100 * @param ex The I/O executor that the socket will use, by default, to 0101 * dispatch handlers for any asynchronous operations performed on the socket. 0102 */ 0103 explicit basic_stream_socket(const executor_type& ex) 0104 : basic_socket<Protocol, Executor>(ex) 0105 { 0106 } 0107 0108 /// Construct a basic_stream_socket without opening it. 0109 /** 0110 * This constructor creates a stream socket without opening it. The socket 0111 * needs to be opened and then connected or accepted before data can be sent 0112 * or received on it. 0113 * 0114 * @param context An execution context which provides the I/O executor that 0115 * the socket will use, by default, to dispatch handlers for any asynchronous 0116 * operations performed on the socket. 0117 */ 0118 template <typename ExecutionContext> 0119 explicit basic_stream_socket(ExecutionContext& context, 0120 constraint_t< 0121 is_convertible<ExecutionContext&, execution_context&>::value 0122 > = 0) 0123 : basic_socket<Protocol, Executor>(context) 0124 { 0125 } 0126 0127 /// Construct and open a basic_stream_socket. 0128 /** 0129 * This constructor creates and opens a stream socket. The socket needs to be 0130 * connected or accepted before data can be sent or received on it. 0131 * 0132 * @param ex The I/O executor that the socket will use, by default, to 0133 * dispatch handlers for any asynchronous operations performed on the socket. 0134 * 0135 * @param protocol An object specifying protocol parameters to be used. 0136 * 0137 * @throws boost::system::system_error Thrown on failure. 0138 */ 0139 basic_stream_socket(const executor_type& ex, const protocol_type& protocol) 0140 : basic_socket<Protocol, Executor>(ex, protocol) 0141 { 0142 } 0143 0144 /// Construct and open a basic_stream_socket. 0145 /** 0146 * This constructor creates and opens a stream socket. The socket needs to be 0147 * connected or accepted before data can be sent or received on it. 0148 * 0149 * @param context An execution context which provides the I/O executor that 0150 * the socket will use, by default, to dispatch handlers for any asynchronous 0151 * operations performed on the socket. 0152 * 0153 * @param protocol An object specifying protocol parameters to be used. 0154 * 0155 * @throws boost::system::system_error Thrown on failure. 0156 */ 0157 template <typename ExecutionContext> 0158 basic_stream_socket(ExecutionContext& context, const protocol_type& protocol, 0159 constraint_t< 0160 is_convertible<ExecutionContext&, execution_context&>::value, 0161 defaulted_constraint 0162 > = defaulted_constraint()) 0163 : basic_socket<Protocol, Executor>(context, protocol) 0164 { 0165 } 0166 0167 /// Construct a basic_stream_socket, opening it and binding it to the given 0168 /// local endpoint. 0169 /** 0170 * This constructor creates a stream socket and automatically opens it bound 0171 * to the specified endpoint on the local machine. The protocol used is the 0172 * protocol associated with the given endpoint. 0173 * 0174 * @param ex The I/O executor that the socket will use, by default, to 0175 * dispatch handlers for any asynchronous operations performed on the socket. 0176 * 0177 * @param endpoint An endpoint on the local machine to which the stream 0178 * socket will be bound. 0179 * 0180 * @throws boost::system::system_error Thrown on failure. 0181 */ 0182 basic_stream_socket(const executor_type& ex, const endpoint_type& endpoint) 0183 : basic_socket<Protocol, Executor>(ex, endpoint) 0184 { 0185 } 0186 0187 /// Construct a basic_stream_socket, opening it and binding it to the given 0188 /// local endpoint. 0189 /** 0190 * This constructor creates a stream socket and automatically opens it bound 0191 * to the specified endpoint on the local machine. The protocol used is the 0192 * 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 stream 0199 * socket will be bound. 0200 * 0201 * @throws boost::system::system_error Thrown on failure. 0202 */ 0203 template <typename ExecutionContext> 0204 basic_stream_socket(ExecutionContext& context, const endpoint_type& endpoint, 0205 constraint_t< 0206 is_convertible<ExecutionContext&, execution_context&>::value 0207 > = 0) 0208 : basic_socket<Protocol, Executor>(context, endpoint) 0209 { 0210 } 0211 0212 /// Construct a basic_stream_socket on an existing native socket. 0213 /** 0214 * This constructor creates a stream socket object to hold an existing native 0215 * socket. 0216 * 0217 * @param ex The I/O executor that the socket will use, by default, to 0218 * dispatch handlers for any asynchronous operations performed on the socket. 0219 * 0220 * @param protocol An object specifying protocol parameters to be used. 0221 * 0222 * @param native_socket The new underlying socket implementation. 0223 * 0224 * @throws boost::system::system_error Thrown on failure. 0225 */ 0226 basic_stream_socket(const executor_type& ex, 0227 const protocol_type& protocol, const native_handle_type& native_socket) 0228 : basic_socket<Protocol, Executor>(ex, protocol, native_socket) 0229 { 0230 } 0231 0232 /// Construct a basic_stream_socket on an existing native socket. 0233 /** 0234 * This constructor creates a stream socket object to hold an existing native 0235 * socket. 0236 * 0237 * @param context An execution context which provides the I/O executor that 0238 * the socket will use, by default, to dispatch handlers for any asynchronous 0239 * operations performed on the socket. 0240 * 0241 * @param protocol An object specifying protocol parameters to be used. 0242 * 0243 * @param native_socket The new underlying socket implementation. 0244 * 0245 * @throws boost::system::system_error Thrown on failure. 0246 */ 0247 template <typename ExecutionContext> 0248 basic_stream_socket(ExecutionContext& context, 0249 const protocol_type& protocol, const native_handle_type& native_socket, 0250 constraint_t< 0251 is_convertible<ExecutionContext&, execution_context&>::value 0252 > = 0) 0253 : basic_socket<Protocol, Executor>(context, protocol, native_socket) 0254 { 0255 } 0256 0257 /// Move-construct a basic_stream_socket from another. 0258 /** 0259 * This constructor moves a stream socket from one object to another. 0260 * 0261 * @param other The other basic_stream_socket object from which the move 0262 * will occur. 0263 * 0264 * @note Following the move, the moved-from object is in the same state as if 0265 * constructed using the @c basic_stream_socket(const executor_type&) 0266 * constructor. 0267 */ 0268 basic_stream_socket(basic_stream_socket&& other) noexcept 0269 : basic_socket<Protocol, Executor>(std::move(other)) 0270 { 0271 } 0272 0273 /// Move-assign a basic_stream_socket from another. 0274 /** 0275 * This assignment operator moves a stream socket from one object to another. 0276 * 0277 * @param other The other basic_stream_socket object from which the move 0278 * will occur. 0279 * 0280 * @note Following the move, the moved-from object is in the same state as if 0281 * constructed using the @c basic_stream_socket(const executor_type&) 0282 * constructor. 0283 */ 0284 basic_stream_socket& operator=(basic_stream_socket&& other) 0285 { 0286 basic_socket<Protocol, Executor>::operator=(std::move(other)); 0287 return *this; 0288 } 0289 0290 /// Move-construct a basic_stream_socket from a socket of another protocol 0291 /// type. 0292 /** 0293 * This constructor moves a stream socket from one object to another. 0294 * 0295 * @param other The other basic_stream_socket object from which the move 0296 * will occur. 0297 * 0298 * @note Following the move, the moved-from object is in the same state as if 0299 * constructed using the @c basic_stream_socket(const executor_type&) 0300 * constructor. 0301 */ 0302 template <typename Protocol1, typename Executor1> 0303 basic_stream_socket(basic_stream_socket<Protocol1, Executor1>&& other, 0304 constraint_t< 0305 is_convertible<Protocol1, Protocol>::value 0306 && is_convertible<Executor1, Executor>::value 0307 > = 0) 0308 : basic_socket<Protocol, Executor>(std::move(other)) 0309 { 0310 } 0311 0312 /// Move-assign a basic_stream_socket from a socket of another protocol type. 0313 /** 0314 * This assignment operator moves a stream socket from one object to another. 0315 * 0316 * @param other The other basic_stream_socket object from which the move 0317 * will occur. 0318 * 0319 * @note Following the move, the moved-from object is in the same state as if 0320 * constructed using the @c basic_stream_socket(const executor_type&) 0321 * constructor. 0322 */ 0323 template <typename Protocol1, typename Executor1> 0324 constraint_t< 0325 is_convertible<Protocol1, Protocol>::value 0326 && is_convertible<Executor1, Executor>::value, 0327 basic_stream_socket& 0328 > operator=(basic_stream_socket<Protocol1, Executor1>&& other) 0329 { 0330 basic_socket<Protocol, Executor>::operator=(std::move(other)); 0331 return *this; 0332 } 0333 0334 /// Destroys the socket. 0335 /** 0336 * This function destroys the socket, cancelling any outstanding asynchronous 0337 * operations associated with the socket as if by calling @c cancel. 0338 */ 0339 ~basic_stream_socket() 0340 { 0341 } 0342 0343 /// Send some data on the socket. 0344 /** 0345 * This function is used to send data on the stream socket. The function 0346 * call will block until one or more bytes of the data has been sent 0347 * successfully, or an until error occurs. 0348 * 0349 * @param buffers One or more data buffers to be sent on the socket. 0350 * 0351 * @returns The number of bytes sent. 0352 * 0353 * @throws boost::system::system_error Thrown on failure. 0354 * 0355 * @note The send operation may not transmit all of the data to the peer. 0356 * Consider using the @ref write function if you need to ensure that all data 0357 * is written before the blocking operation completes. 0358 * 0359 * @par Example 0360 * To send a single data buffer use the @ref buffer function as follows: 0361 * @code 0362 * socket.send(boost::asio::buffer(data, size)); 0363 * @endcode 0364 * See the @ref buffer documentation for information on sending multiple 0365 * buffers in one go, and how to use it with arrays, boost::array or 0366 * std::vector. 0367 */ 0368 template <typename ConstBufferSequence> 0369 std::size_t send(const ConstBufferSequence& buffers) 0370 { 0371 boost::system::error_code ec; 0372 std::size_t s = this->impl_.get_service().send( 0373 this->impl_.get_implementation(), buffers, 0, ec); 0374 boost::asio::detail::throw_error(ec, "send"); 0375 return s; 0376 } 0377 0378 /// Send some data on the socket. 0379 /** 0380 * This function is used to send data on the stream socket. The function 0381 * call will block until one or more bytes of the data has been sent 0382 * successfully, or an until error occurs. 0383 * 0384 * @param buffers One or more data buffers to be sent on the socket. 0385 * 0386 * @param flags Flags specifying how the send call is to be made. 0387 * 0388 * @returns The number of bytes sent. 0389 * 0390 * @throws boost::system::system_error Thrown on failure. 0391 * 0392 * @note The send operation may not transmit all of the data to the peer. 0393 * Consider using the @ref write function if you need to ensure that all data 0394 * is written before the blocking operation completes. 0395 * 0396 * @par Example 0397 * To send a single data buffer use the @ref buffer function as follows: 0398 * @code 0399 * socket.send(boost::asio::buffer(data, size), 0); 0400 * @endcode 0401 * See the @ref buffer documentation for information on sending multiple 0402 * buffers in one go, and how to use it with arrays, boost::array or 0403 * std::vector. 0404 */ 0405 template <typename ConstBufferSequence> 0406 std::size_t send(const ConstBufferSequence& buffers, 0407 socket_base::message_flags flags) 0408 { 0409 boost::system::error_code ec; 0410 std::size_t s = this->impl_.get_service().send( 0411 this->impl_.get_implementation(), buffers, flags, ec); 0412 boost::asio::detail::throw_error(ec, "send"); 0413 return s; 0414 } 0415 0416 /// Send some data on the socket. 0417 /** 0418 * This function is used to send data on the stream socket. The function 0419 * call will block until one or more bytes of the data has been sent 0420 * successfully, or an until error occurs. 0421 * 0422 * @param buffers One or more data buffers to be sent on the socket. 0423 * 0424 * @param flags Flags specifying how the send call is to be made. 0425 * 0426 * @param ec Set to indicate what error occurred, if any. 0427 * 0428 * @returns The number of bytes sent. Returns 0 if an error occurred. 0429 * 0430 * @note The send operation may not transmit all of the data to the peer. 0431 * Consider using the @ref write function if you need to ensure that all data 0432 * is written before the blocking operation completes. 0433 */ 0434 template <typename ConstBufferSequence> 0435 std::size_t send(const ConstBufferSequence& buffers, 0436 socket_base::message_flags flags, boost::system::error_code& ec) 0437 { 0438 return this->impl_.get_service().send( 0439 this->impl_.get_implementation(), buffers, flags, ec); 0440 } 0441 0442 /// Start an asynchronous send. 0443 /** 0444 * This function is used to asynchronously send data on the stream socket. 0445 * It is an initiating function for an @ref asynchronous_operation, and always 0446 * returns immediately. 0447 * 0448 * @param buffers One or more data buffers to be sent on the socket. Although 0449 * the buffers object may be copied as necessary, ownership of the underlying 0450 * memory blocks is retained by the caller, which must guarantee that they 0451 * remain valid until the completion handler is called. 0452 * 0453 * @param token The @ref completion_token that will be used to produce a 0454 * completion handler, which will be called when the send completes. 0455 * Potential completion tokens include @ref use_future, @ref use_awaitable, 0456 * @ref yield_context, or a function object with the correct completion 0457 * signature. The function signature of the completion handler must be: 0458 * @code void handler( 0459 * const boost::system::error_code& error, // Result of operation. 0460 * std::size_t bytes_transferred // Number of bytes sent. 0461 * ); @endcode 0462 * Regardless of whether the asynchronous operation completes immediately or 0463 * not, the completion handler will not be invoked from within this function. 0464 * On immediate completion, invocation of the handler will be performed in a 0465 * manner equivalent to using boost::asio::post(). 0466 * 0467 * @par Completion Signature 0468 * @code void(boost::system::error_code, std::size_t) @endcode 0469 * 0470 * @note The send operation may not transmit all of the data to the peer. 0471 * Consider using the @ref async_write function if you need to ensure that all 0472 * data is written before the asynchronous operation completes. 0473 * 0474 * @par Example 0475 * To send a single data buffer use the @ref buffer function as follows: 0476 * @code 0477 * socket.async_send(boost::asio::buffer(data, size), handler); 0478 * @endcode 0479 * See the @ref buffer documentation for information on sending multiple 0480 * buffers in one go, and how to use it with arrays, boost::array or 0481 * std::vector. 0482 * 0483 * @par Per-Operation Cancellation 0484 * On POSIX or Windows operating systems, this asynchronous operation supports 0485 * cancellation for the following boost::asio::cancellation_type values: 0486 * 0487 * @li @c cancellation_type::terminal 0488 * 0489 * @li @c cancellation_type::partial 0490 * 0491 * @li @c cancellation_type::total 0492 */ 0493 template <typename ConstBufferSequence, 0494 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, 0495 std::size_t)) WriteToken = default_completion_token_t<executor_type>> 0496 auto async_send(const ConstBufferSequence& buffers, 0497 WriteToken&& token = default_completion_token_t<executor_type>()) 0498 -> decltype( 0499 async_initiate<WriteToken, 0500 void (boost::system::error_code, std::size_t)>( 0501 declval<initiate_async_send>(), token, 0502 buffers, socket_base::message_flags(0))) 0503 { 0504 return async_initiate<WriteToken, 0505 void (boost::system::error_code, std::size_t)>( 0506 initiate_async_send(this), token, 0507 buffers, socket_base::message_flags(0)); 0508 } 0509 0510 /// Start an asynchronous send. 0511 /** 0512 * This function is used to asynchronously send data on the stream socket. 0513 * It is an initiating function for an @ref asynchronous_operation, and always 0514 * returns immediately. 0515 * 0516 * @param buffers One or more data buffers to be sent on the socket. Although 0517 * the buffers object may be copied as necessary, ownership of the underlying 0518 * memory blocks is retained by the caller, which must guarantee that they 0519 * remain valid until the completion handler is called. 0520 * 0521 * @param flags Flags specifying how the send call is to be made. 0522 * 0523 * @param token The @ref completion_token that will be used to produce a 0524 * completion handler, which will be called when the send completes. 0525 * Potential completion tokens include @ref use_future, @ref use_awaitable, 0526 * @ref yield_context, or a function object with the correct completion 0527 * signature. The function signature of the completion handler must be: 0528 * @code void handler( 0529 * const boost::system::error_code& error, // Result of operation. 0530 * std::size_t bytes_transferred // Number of bytes sent. 0531 * ); @endcode 0532 * Regardless of whether the asynchronous operation completes immediately or 0533 * not, the completion handler will not be invoked from within this function. 0534 * On immediate completion, invocation of the handler will be performed in a 0535 * manner equivalent to using boost::asio::post(). 0536 * 0537 * @par Completion Signature 0538 * @code void(boost::system::error_code, std::size_t) @endcode 0539 * 0540 * @note The send operation may not transmit all of the data to the peer. 0541 * Consider using the @ref async_write function if you need to ensure that all 0542 * data is written before the asynchronous operation completes. 0543 * 0544 * @par Example 0545 * To send a single data buffer use the @ref buffer function as follows: 0546 * @code 0547 * socket.async_send(boost::asio::buffer(data, size), 0, handler); 0548 * @endcode 0549 * See the @ref buffer documentation for information on sending multiple 0550 * buffers in one go, and how to use it with arrays, boost::array or 0551 * std::vector. 0552 * 0553 * @par Per-Operation Cancellation 0554 * On POSIX or Windows operating systems, this asynchronous operation supports 0555 * cancellation for the following boost::asio::cancellation_type values: 0556 * 0557 * @li @c cancellation_type::terminal 0558 * 0559 * @li @c cancellation_type::partial 0560 * 0561 * @li @c cancellation_type::total 0562 */ 0563 template <typename ConstBufferSequence, 0564 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, 0565 std::size_t)) WriteToken = default_completion_token_t<executor_type>> 0566 auto async_send(const ConstBufferSequence& buffers, 0567 socket_base::message_flags flags, 0568 WriteToken&& token = default_completion_token_t<executor_type>()) 0569 -> decltype( 0570 async_initiate<WriteToken, 0571 void (boost::system::error_code, std::size_t)>( 0572 declval<initiate_async_send>(), token, buffers, flags)) 0573 { 0574 return async_initiate<WriteToken, 0575 void (boost::system::error_code, std::size_t)>( 0576 initiate_async_send(this), token, buffers, flags); 0577 } 0578 0579 /// Receive some data on the socket. 0580 /** 0581 * This function is used to receive data on the stream socket. The function 0582 * call will block until one or more bytes of data has been received 0583 * successfully, or until an error occurs. 0584 * 0585 * @param buffers One or more buffers into which the data will be received. 0586 * 0587 * @returns The number of bytes received. 0588 * 0589 * @throws boost::system::system_error Thrown on failure. An error code of 0590 * boost::asio::error::eof indicates that the connection was closed by the 0591 * peer. 0592 * 0593 * @note The receive operation may not receive all of the requested number of 0594 * bytes. Consider using the @ref read function if you need to ensure that the 0595 * requested amount of data is read before the blocking operation completes. 0596 * 0597 * @par Example 0598 * To receive into a single data buffer use the @ref buffer function as 0599 * follows: 0600 * @code 0601 * socket.receive(boost::asio::buffer(data, size)); 0602 * @endcode 0603 * See the @ref buffer documentation for information on receiving into 0604 * multiple buffers in one go, and how to use it with arrays, boost::array or 0605 * std::vector. 0606 */ 0607 template <typename MutableBufferSequence> 0608 std::size_t receive(const MutableBufferSequence& buffers) 0609 { 0610 boost::system::error_code ec; 0611 std::size_t s = this->impl_.get_service().receive( 0612 this->impl_.get_implementation(), buffers, 0, ec); 0613 boost::asio::detail::throw_error(ec, "receive"); 0614 return s; 0615 } 0616 0617 /// Receive some data on the socket. 0618 /** 0619 * This function is used to receive data on the stream socket. The function 0620 * call will block until one or more bytes of data has been received 0621 * successfully, or until an error occurs. 0622 * 0623 * @param buffers One or more buffers into which the data will be received. 0624 * 0625 * @param flags Flags specifying how the receive call is to be made. 0626 * 0627 * @returns The number of bytes received. 0628 * 0629 * @throws boost::system::system_error Thrown on failure. An error code of 0630 * boost::asio::error::eof indicates that the connection was closed by the 0631 * peer. 0632 * 0633 * @note The receive operation may not receive all of the requested number of 0634 * bytes. Consider using the @ref read function if you need to ensure that the 0635 * requested amount of data is read before the blocking operation completes. 0636 * 0637 * @par Example 0638 * To receive into a single data buffer use the @ref buffer function as 0639 * follows: 0640 * @code 0641 * socket.receive(boost::asio::buffer(data, size), 0); 0642 * @endcode 0643 * See the @ref buffer documentation for information on receiving into 0644 * multiple buffers in one go, and how to use it with arrays, boost::array or 0645 * std::vector. 0646 */ 0647 template <typename MutableBufferSequence> 0648 std::size_t receive(const MutableBufferSequence& buffers, 0649 socket_base::message_flags flags) 0650 { 0651 boost::system::error_code ec; 0652 std::size_t s = this->impl_.get_service().receive( 0653 this->impl_.get_implementation(), buffers, flags, ec); 0654 boost::asio::detail::throw_error(ec, "receive"); 0655 return s; 0656 } 0657 0658 /// Receive some data on a connected socket. 0659 /** 0660 * This function is used to receive data on the stream socket. The function 0661 * call will block until one or more bytes of data has been received 0662 * successfully, or until an error occurs. 0663 * 0664 * @param buffers One or more buffers into which the data will be received. 0665 * 0666 * @param flags Flags specifying how the receive call is to be made. 0667 * 0668 * @param ec Set to indicate what error occurred, if any. 0669 * 0670 * @returns The number of bytes received. Returns 0 if an error occurred. 0671 * 0672 * @note The receive operation may not receive all of the requested number of 0673 * bytes. Consider using the @ref read function if you need to ensure that the 0674 * requested amount of data is read before the blocking operation completes. 0675 */ 0676 template <typename MutableBufferSequence> 0677 std::size_t receive(const MutableBufferSequence& buffers, 0678 socket_base::message_flags flags, boost::system::error_code& ec) 0679 { 0680 return this->impl_.get_service().receive( 0681 this->impl_.get_implementation(), buffers, flags, ec); 0682 } 0683 0684 /// Start an asynchronous receive. 0685 /** 0686 * This function is used to asynchronously receive data from the stream 0687 * socket. It is an initiating function for an @ref asynchronous_operation, 0688 * and always returns immediately. 0689 * 0690 * @param buffers One or more buffers into which the data will be received. 0691 * Although the buffers object may be copied as necessary, ownership of the 0692 * underlying memory blocks is retained by the caller, which must guarantee 0693 * that they remain valid until the completion handler is called. 0694 * 0695 * @param token The @ref completion_token that will be used to produce a 0696 * completion handler, which will be called when the receive completes. 0697 * Potential completion tokens include @ref use_future, @ref use_awaitable, 0698 * @ref yield_context, or a function object with the correct completion 0699 * signature. The function signature of the completion handler must be: 0700 * @code void handler( 0701 * const boost::system::error_code& error, // Result of operation. 0702 * std::size_t bytes_transferred // Number of bytes received. 0703 * ); @endcode 0704 * Regardless of whether the asynchronous operation completes immediately or 0705 * not, the completion handler will not be invoked from within this function. 0706 * On immediate completion, invocation of the handler will be performed in a 0707 * manner equivalent to using boost::asio::post(). 0708 * 0709 * @par Completion Signature 0710 * @code void(boost::system::error_code, std::size_t) @endcode 0711 * 0712 * @note The receive operation may not receive all of the requested number of 0713 * bytes. Consider using the @ref async_read function if you need to ensure 0714 * that the requested amount of data is received before the asynchronous 0715 * operation completes. 0716 * 0717 * @par Example 0718 * To receive into a single data buffer use the @ref buffer function as 0719 * follows: 0720 * @code 0721 * socket.async_receive(boost::asio::buffer(data, size), handler); 0722 * @endcode 0723 * See the @ref buffer documentation for information on receiving into 0724 * multiple buffers in one go, and how to use it with arrays, boost::array or 0725 * std::vector. 0726 * 0727 * @par Per-Operation Cancellation 0728 * On POSIX or Windows operating systems, this asynchronous operation supports 0729 * cancellation for the following boost::asio::cancellation_type values: 0730 * 0731 * @li @c cancellation_type::terminal 0732 * 0733 * @li @c cancellation_type::partial 0734 * 0735 * @li @c cancellation_type::total 0736 */ 0737 template <typename MutableBufferSequence, 0738 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, 0739 std::size_t)) ReadToken = default_completion_token_t<executor_type>> 0740 auto async_receive(const MutableBufferSequence& buffers, 0741 ReadToken&& token = default_completion_token_t<executor_type>()) 0742 -> decltype( 0743 async_initiate<ReadToken, 0744 void (boost::system::error_code, std::size_t)>( 0745 declval<initiate_async_receive>(), token, 0746 buffers, socket_base::message_flags(0))) 0747 { 0748 return async_initiate<ReadToken, 0749 void (boost::system::error_code, std::size_t)>( 0750 initiate_async_receive(this), token, 0751 buffers, socket_base::message_flags(0)); 0752 } 0753 0754 /// Start an asynchronous receive. 0755 /** 0756 * This function is used to asynchronously receive data from the stream 0757 * socket. It is an initiating function for an @ref asynchronous_operation, 0758 * and always returns immediately. 0759 * 0760 * @param buffers One or more buffers into which the data will be received. 0761 * Although the buffers object may be copied as necessary, ownership of the 0762 * underlying memory blocks is retained by the caller, which must guarantee 0763 * that they remain valid until the completion handler is called. 0764 * 0765 * @param flags Flags specifying how the receive call is to be made. 0766 * 0767 * @param token The @ref completion_token that will be used to produce a 0768 * completion handler, which will be called when the receive completes. 0769 * Potential completion tokens include @ref use_future, @ref use_awaitable, 0770 * @ref yield_context, or a function object with the correct completion 0771 * signature. The function signature of the completion handler must be: 0772 * @code void handler( 0773 * const boost::system::error_code& error, // Result of operation. 0774 * std::size_t bytes_transferred // Number of bytes received. 0775 * ); @endcode 0776 * Regardless of whether the asynchronous operation completes immediately or 0777 * not, the completion handler will not be invoked from within this function. 0778 * On immediate completion, invocation of the handler will be performed in a 0779 * manner equivalent to using boost::asio::post(). 0780 * 0781 * @par Completion Signature 0782 * @code void(boost::system::error_code, std::size_t) @endcode 0783 * 0784 * @note The receive operation may not receive all of the requested number of 0785 * bytes. Consider using the @ref async_read function if you need to ensure 0786 * that the requested amount of data is received before the asynchronous 0787 * operation completes. 0788 * 0789 * @par Example 0790 * To receive into a single data buffer use the @ref buffer function as 0791 * follows: 0792 * @code 0793 * socket.async_receive(boost::asio::buffer(data, size), 0, handler); 0794 * @endcode 0795 * See the @ref buffer documentation for information on receiving into 0796 * multiple buffers in one go, and how to use it with arrays, boost::array or 0797 * std::vector. 0798 * 0799 * @par Per-Operation Cancellation 0800 * On POSIX or Windows operating systems, this asynchronous operation supports 0801 * cancellation for the following boost::asio::cancellation_type values: 0802 * 0803 * @li @c cancellation_type::terminal 0804 * 0805 * @li @c cancellation_type::partial 0806 * 0807 * @li @c cancellation_type::total 0808 */ 0809 template <typename MutableBufferSequence, 0810 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, 0811 std::size_t)) ReadToken = default_completion_token_t<executor_type>> 0812 auto async_receive(const MutableBufferSequence& buffers, 0813 socket_base::message_flags flags, 0814 ReadToken&& token = default_completion_token_t<executor_type>()) 0815 -> decltype( 0816 async_initiate<ReadToken, 0817 void (boost::system::error_code, std::size_t)>( 0818 declval<initiate_async_receive>(), token, buffers, flags)) 0819 { 0820 return async_initiate<ReadToken, 0821 void (boost::system::error_code, std::size_t)>( 0822 initiate_async_receive(this), token, buffers, flags); 0823 } 0824 0825 /// Write some data to the socket. 0826 /** 0827 * This function is used to write data to the stream socket. The function call 0828 * will block until one or more bytes of the data has been written 0829 * successfully, or until an error occurs. 0830 * 0831 * @param buffers One or more data buffers to be written to the socket. 0832 * 0833 * @returns The number of bytes written. 0834 * 0835 * @throws boost::system::system_error Thrown on failure. An error code of 0836 * boost::asio::error::eof indicates that the connection was closed by the 0837 * peer. 0838 * 0839 * @note The write_some operation may not transmit all of the data to the 0840 * peer. Consider using the @ref write function if you need to ensure that 0841 * all data is written before the blocking operation completes. 0842 * 0843 * @par Example 0844 * To write a single data buffer use the @ref buffer function as follows: 0845 * @code 0846 * socket.write_some(boost::asio::buffer(data, size)); 0847 * @endcode 0848 * See the @ref buffer documentation for information on writing multiple 0849 * buffers in one go, and how to use it with arrays, boost::array or 0850 * std::vector. 0851 */ 0852 template <typename ConstBufferSequence> 0853 std::size_t write_some(const ConstBufferSequence& buffers) 0854 { 0855 boost::system::error_code ec; 0856 std::size_t s = this->impl_.get_service().send( 0857 this->impl_.get_implementation(), buffers, 0, ec); 0858 boost::asio::detail::throw_error(ec, "write_some"); 0859 return s; 0860 } 0861 0862 /// Write some data to the socket. 0863 /** 0864 * This function is used to write data to the stream socket. The function call 0865 * will block until one or more bytes of the data has been written 0866 * successfully, or until an error occurs. 0867 * 0868 * @param buffers One or more data buffers to be written to the socket. 0869 * 0870 * @param ec Set to indicate what error occurred, if any. 0871 * 0872 * @returns The number of bytes written. Returns 0 if an error occurred. 0873 * 0874 * @note The write_some operation may not transmit all of the data to the 0875 * peer. Consider using the @ref write function if you need to ensure that 0876 * all data is written before the blocking operation completes. 0877 */ 0878 template <typename ConstBufferSequence> 0879 std::size_t write_some(const ConstBufferSequence& buffers, 0880 boost::system::error_code& ec) 0881 { 0882 return this->impl_.get_service().send( 0883 this->impl_.get_implementation(), buffers, 0, ec); 0884 } 0885 0886 /// Start an asynchronous write. 0887 /** 0888 * This function is used to asynchronously write data to the stream socket. 0889 * It is an initiating function for an @ref asynchronous_operation, and always 0890 * returns immediately. 0891 * 0892 * @param buffers One or more data buffers to be written to the socket. 0893 * Although the buffers object may be copied as necessary, ownership of the 0894 * underlying memory blocks is retained by the caller, which must guarantee 0895 * that they remain valid until the completion handler is called. 0896 * 0897 * @param token The @ref completion_token that will be used to produce a 0898 * completion handler, which will be called when the write completes. 0899 * Potential completion tokens include @ref use_future, @ref use_awaitable, 0900 * @ref yield_context, or a function object with the correct completion 0901 * signature. The function signature of the completion handler must be: 0902 * @code void handler( 0903 * const boost::system::error_code& error, // Result of operation. 0904 * std::size_t bytes_transferred // Number of bytes written. 0905 * ); @endcode 0906 * Regardless of whether the asynchronous operation completes immediately or 0907 * not, the completion handler will not be invoked from within this function. 0908 * On immediate completion, invocation of the handler will be performed in a 0909 * manner equivalent to using boost::asio::post(). 0910 * 0911 * @par Completion Signature 0912 * @code void(boost::system::error_code, std::size_t) @endcode 0913 * 0914 * @note The write operation may not transmit all of the data to the peer. 0915 * Consider using the @ref async_write function if you need to ensure that all 0916 * data is written before the asynchronous operation completes. 0917 * 0918 * @par Example 0919 * To write a single data buffer use the @ref buffer function as follows: 0920 * @code 0921 * socket.async_write_some(boost::asio::buffer(data, size), handler); 0922 * @endcode 0923 * See the @ref buffer documentation for information on writing multiple 0924 * buffers in one go, and how to use it with arrays, boost::array or 0925 * std::vector. 0926 * 0927 * @par Per-Operation Cancellation 0928 * On POSIX or Windows operating systems, this asynchronous operation supports 0929 * cancellation for the following boost::asio::cancellation_type values: 0930 * 0931 * @li @c cancellation_type::terminal 0932 * 0933 * @li @c cancellation_type::partial 0934 * 0935 * @li @c cancellation_type::total 0936 */ 0937 template <typename ConstBufferSequence, 0938 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, 0939 std::size_t)) WriteToken = default_completion_token_t<executor_type>> 0940 auto async_write_some(const ConstBufferSequence& buffers, 0941 WriteToken&& token = default_completion_token_t<executor_type>()) 0942 -> decltype( 0943 async_initiate<WriteToken, 0944 void (boost::system::error_code, std::size_t)>( 0945 declval<initiate_async_send>(), token, 0946 buffers, socket_base::message_flags(0))) 0947 { 0948 return async_initiate<WriteToken, 0949 void (boost::system::error_code, std::size_t)>( 0950 initiate_async_send(this), token, 0951 buffers, socket_base::message_flags(0)); 0952 } 0953 0954 /// Read some data from the socket. 0955 /** 0956 * This function is used to read data from the stream socket. The function 0957 * call will block until one or more bytes of data has been read successfully, 0958 * or until an error occurs. 0959 * 0960 * @param buffers One or more buffers into which the data will be read. 0961 * 0962 * @returns The number of bytes read. 0963 * 0964 * @throws boost::system::system_error Thrown on failure. An error code of 0965 * boost::asio::error::eof indicates that the connection was closed by the 0966 * peer. 0967 * 0968 * @note The read_some operation may not read all of the requested number of 0969 * bytes. Consider using the @ref read function if you need to ensure that 0970 * the requested amount of data is read before the blocking operation 0971 * completes. 0972 * 0973 * @par Example 0974 * To read into a single data buffer use the @ref buffer function as follows: 0975 * @code 0976 * socket.read_some(boost::asio::buffer(data, size)); 0977 * @endcode 0978 * See the @ref buffer documentation for information on reading into multiple 0979 * buffers in one go, and how to use it with arrays, boost::array or 0980 * std::vector. 0981 */ 0982 template <typename MutableBufferSequence> 0983 std::size_t read_some(const MutableBufferSequence& buffers) 0984 { 0985 boost::system::error_code ec; 0986 std::size_t s = this->impl_.get_service().receive( 0987 this->impl_.get_implementation(), buffers, 0, ec); 0988 boost::asio::detail::throw_error(ec, "read_some"); 0989 return s; 0990 } 0991 0992 /// Read some data from the socket. 0993 /** 0994 * This function is used to read data from the stream socket. The function 0995 * call will block until one or more bytes of data has been read successfully, 0996 * or until an error occurs. 0997 * 0998 * @param buffers One or more buffers into which the data will be read. 0999 * 1000 * @param ec Set to indicate what error occurred, if any. 1001 * 1002 * @returns The number of bytes read. Returns 0 if an error occurred. 1003 * 1004 * @note The read_some operation may not read all of the requested number of 1005 * bytes. Consider using the @ref read function if you need to ensure that 1006 * the requested amount of data is read before the blocking operation 1007 * completes. 1008 */ 1009 template <typename MutableBufferSequence> 1010 std::size_t read_some(const MutableBufferSequence& buffers, 1011 boost::system::error_code& ec) 1012 { 1013 return this->impl_.get_service().receive( 1014 this->impl_.get_implementation(), buffers, 0, ec); 1015 } 1016 1017 /// Start an asynchronous read. 1018 /** 1019 * This function is used to asynchronously read data from the stream socket. 1020 * socket. It is an initiating function for an @ref asynchronous_operation, 1021 * and always returns immediately. 1022 * 1023 * @param buffers One or more buffers into which the data will be read. 1024 * Although the buffers object may be copied as necessary, ownership of the 1025 * underlying memory blocks is retained by the caller, which must guarantee 1026 * that they remain valid until the completion handler is called. 1027 * 1028 * @param token The @ref completion_token that will be used to produce a 1029 * completion handler, which will be called when the read completes. 1030 * Potential completion tokens include @ref use_future, @ref use_awaitable, 1031 * @ref yield_context, or a function object with the correct completion 1032 * signature. The function signature of the completion handler must be: 1033 * @code void handler( 1034 * const boost::system::error_code& error, // Result of operation. 1035 * std::size_t bytes_transferred // Number of bytes read. 1036 * ); @endcode 1037 * Regardless of whether the asynchronous operation completes immediately or 1038 * not, the completion handler will not be invoked from within this function. 1039 * On immediate completion, invocation of the handler will be performed in a 1040 * manner equivalent to using boost::asio::post(). 1041 * 1042 * @par Completion Signature 1043 * @code void(boost::system::error_code, std::size_t) @endcode 1044 * 1045 * @note The read operation may not read all of the requested number of bytes. 1046 * Consider using the @ref async_read function if you need to ensure that the 1047 * requested amount of data is read before the asynchronous operation 1048 * completes. 1049 * 1050 * @par Example 1051 * To read into a single data buffer use the @ref buffer function as follows: 1052 * @code 1053 * socket.async_read_some(boost::asio::buffer(data, size), handler); 1054 * @endcode 1055 * See the @ref buffer documentation for information on reading into multiple 1056 * buffers in one go, and how to use it with arrays, boost::array or 1057 * std::vector. 1058 * 1059 * @par Per-Operation Cancellation 1060 * On POSIX or Windows operating systems, this asynchronous operation supports 1061 * cancellation for the following boost::asio::cancellation_type values: 1062 * 1063 * @li @c cancellation_type::terminal 1064 * 1065 * @li @c cancellation_type::partial 1066 * 1067 * @li @c cancellation_type::total 1068 */ 1069 template <typename MutableBufferSequence, 1070 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, 1071 std::size_t)) ReadToken = default_completion_token_t<executor_type>> 1072 auto async_read_some(const MutableBufferSequence& buffers, 1073 ReadToken&& token = default_completion_token_t<executor_type>()) 1074 -> decltype( 1075 async_initiate<ReadToken, 1076 void (boost::system::error_code, std::size_t)>( 1077 declval<initiate_async_receive>(), token, 1078 buffers, socket_base::message_flags(0))) 1079 { 1080 return async_initiate<ReadToken, 1081 void (boost::system::error_code, std::size_t)>( 1082 initiate_async_receive(this), token, 1083 buffers, socket_base::message_flags(0)); 1084 } 1085 1086 private: 1087 // Disallow copying and assignment. 1088 basic_stream_socket(const basic_stream_socket&) = delete; 1089 basic_stream_socket& operator=(const basic_stream_socket&) = delete; 1090 1091 class initiate_async_send 1092 { 1093 public: 1094 typedef Executor executor_type; 1095 1096 explicit initiate_async_send(basic_stream_socket* self) 1097 : self_(self) 1098 { 1099 } 1100 1101 const executor_type& get_executor() const noexcept 1102 { 1103 return self_->get_executor(); 1104 } 1105 1106 template <typename WriteHandler, typename ConstBufferSequence> 1107 void operator()(WriteHandler&& handler, 1108 const ConstBufferSequence& buffers, 1109 socket_base::message_flags flags) const 1110 { 1111 // If you get an error on the following line it means that your handler 1112 // does not meet the documented type requirements for a WriteHandler. 1113 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; 1114 1115 detail::non_const_lvalue<WriteHandler> handler2(handler); 1116 self_->impl_.get_service().async_send( 1117 self_->impl_.get_implementation(), buffers, flags, 1118 handler2.value, self_->impl_.get_executor()); 1119 } 1120 1121 private: 1122 basic_stream_socket* self_; 1123 }; 1124 1125 class initiate_async_receive 1126 { 1127 public: 1128 typedef Executor executor_type; 1129 1130 explicit initiate_async_receive(basic_stream_socket* self) 1131 : self_(self) 1132 { 1133 } 1134 1135 const executor_type& get_executor() const noexcept 1136 { 1137 return self_->get_executor(); 1138 } 1139 1140 template <typename ReadHandler, typename MutableBufferSequence> 1141 void operator()(ReadHandler&& handler, 1142 const MutableBufferSequence& buffers, 1143 socket_base::message_flags flags) const 1144 { 1145 // If you get an error on the following line it means that your handler 1146 // does not meet the documented type requirements for a ReadHandler. 1147 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; 1148 1149 detail::non_const_lvalue<ReadHandler> handler2(handler); 1150 self_->impl_.get_service().async_receive( 1151 self_->impl_.get_implementation(), buffers, flags, 1152 handler2.value, self_->impl_.get_executor()); 1153 } 1154 1155 private: 1156 basic_stream_socket* self_; 1157 }; 1158 }; 1159 1160 } // namespace asio 1161 } // namespace boost 1162 1163 #include <boost/asio/detail/pop_options.hpp> 1164 1165 #endif // BOOST_ASIO_BASIC_STREAM_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 |