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