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