1 // 2 // basic_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_SOCKET_HPP 12 #define BOOST_ASIO_BASIC_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/any_io_executor.hpp> 19 #include <boost/asio/detail/config.hpp> 20 #include <boost/asio/async_result.hpp> 21 #include <boost/asio/detail/handler_type_requirements.hpp> 22 #include <boost/asio/detail/io_object_impl.hpp> 23 #include <boost/asio/detail/non_const_lvalue.hpp> 24 #include <boost/asio/detail/throw_error.hpp> 25 #include <boost/asio/detail/type_traits.hpp> 26 #include <boost/asio/error.hpp> 27 #include <boost/asio/execution_context.hpp> 28 #include <boost/asio/post.hpp> 29 #include <boost/asio/socket_base.hpp> 30 31 #if defined(BOOST_ASIO_WINDOWS_RUNTIME) 32 # include <boost/asio/detail/null_socket_service.hpp> 33 #elif defined(BOOST_ASIO_HAS_IOCP) 34 # include <boost/asio/detail/win_iocp_socket_service.hpp> 35 #else 36 # include <boost/asio/detail/reactive_socket_service.hpp> 37 #endif 38 39 #if defined(BOOST_ASIO_HAS_MOVE) 40 # include <utility> 41 #endif // defined(BOOST_ASIO_HAS_MOVE) 42 43 #include <boost/asio/detail/push_options.hpp> 44 45 namespace boost { 46 namespace asio { 47 48 #if !defined(BOOST_ASIO_BASIC_SOCKET_FWD_DECL) 49 #define BOOST_ASIO_BASIC_SOCKET_FWD_DECL 50 51 // Forward declaration with defaulted arguments. 52 template <typename Protocol, typename Executor = any_io_executor> 53 class basic_socket; 54 55 #endif // !defined(BOOST_ASIO_BASIC_SOCKET_FWD_DECL) 56 57 /// Provides socket functionality. 58 /** 59 * The basic_socket class template provides functionality that is common to both 60 * stream-oriented and datagram-oriented sockets. 61 * 62 * @par Thread Safety 63 * @e Distinct @e objects: Safe.@n 64 * @e Shared @e objects: Unsafe. 65 */ 66 template <typename Protocol, typename Executor> 67 class basic_socket 68 : public socket_base 69 { 70 public: 71 /// The type of the executor associated with the object. 72 typedef Executor executor_type; 73 74 /// Rebinds the socket type to another executor. 75 template <typename Executor1> 76 struct rebind_executor 77 { 78 /// The socket type when rebound to the specified executor. 79 typedef basic_socket<Protocol, Executor1> other; 80 }; 81 82 /// The native representation of a socket. 83 #if defined(GENERATING_DOCUMENTATION) 84 typedef implementation_defined native_handle_type; 85 #elif defined(BOOST_ASIO_WINDOWS_RUNTIME) 86 typedef typename detail::null_socket_service< 87 Protocol>::native_handle_type native_handle_type; 88 #elif defined(BOOST_ASIO_HAS_IOCP) 89 typedef typename detail::win_iocp_socket_service< 90 Protocol>::native_handle_type native_handle_type; 91 #else 92 typedef typename detail::reactive_socket_service< 93 Protocol>::native_handle_type native_handle_type; 94 #endif 95 96 /// The protocol type. 97 typedef Protocol protocol_type; 98 99 /// The endpoint type. 100 typedef typename Protocol::endpoint endpoint_type; 101 102 #if !defined(BOOST_ASIO_NO_EXTENSIONS) 103 /// A basic_socket is always the lowest layer. 104 typedef basic_socket<Protocol, Executor> lowest_layer_type; 105 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS) 106 107 /// Construct a basic_socket without opening it. 108 /** 109 * This constructor creates a socket without opening it. 110 * 111 * @param ex The I/O executor that the socket will use, by default, to 112 * dispatch handlers for any asynchronous operations performed on the socket. 113 */ basic_socket(const executor_type & ex)114 explicit basic_socket(const executor_type& ex) 115 : impl_(0, ex) 116 { 117 } 118 119 /// Construct a basic_socket without opening it. 120 /** 121 * This constructor creates a socket without opening it. 122 * 123 * @param context An execution context which provides the I/O executor that 124 * the socket will use, by default, to dispatch handlers for any asynchronous 125 * operations performed on the socket. 126 */ 127 template <typename ExecutionContext> basic_socket(ExecutionContext & context,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value>::type=0)128 explicit basic_socket(ExecutionContext& context, 129 typename constraint< 130 is_convertible<ExecutionContext&, execution_context&>::value 131 >::type = 0) 132 : impl_(0, 0, context) 133 { 134 } 135 136 /// Construct and open a basic_socket. 137 /** 138 * This constructor creates and opens a socket. 139 * 140 * @param ex The I/O executor that the socket will use, by default, to 141 * dispatch handlers for any asynchronous operations performed on the socket. 142 * 143 * @param protocol An object specifying protocol parameters to be used. 144 * 145 * @throws boost::system::system_error Thrown on failure. 146 */ basic_socket(const executor_type & ex,const protocol_type & protocol)147 basic_socket(const executor_type& ex, const protocol_type& protocol) 148 : impl_(0, ex) 149 { 150 boost::system::error_code ec; 151 impl_.get_service().open(impl_.get_implementation(), protocol, ec); 152 boost::asio::detail::throw_error(ec, "open"); 153 } 154 155 /// Construct and open a basic_socket. 156 /** 157 * This constructor creates and opens a socket. 158 * 159 * @param context An execution context which provides the I/O executor that 160 * the socket will use, by default, to dispatch handlers for any asynchronous 161 * operations performed on the socket. 162 * 163 * @param protocol An object specifying protocol parameters to be used. 164 * 165 * @throws boost::system::system_error Thrown on failure. 166 */ 167 template <typename ExecutionContext> basic_socket(ExecutionContext & context,const protocol_type & protocol,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value,defaulted_constraint>::type=defaulted_constraint ())168 basic_socket(ExecutionContext& context, const protocol_type& protocol, 169 typename constraint< 170 is_convertible<ExecutionContext&, execution_context&>::value, 171 defaulted_constraint 172 >::type = defaulted_constraint()) 173 : impl_(0, 0, context) 174 { 175 boost::system::error_code ec; 176 impl_.get_service().open(impl_.get_implementation(), protocol, ec); 177 boost::asio::detail::throw_error(ec, "open"); 178 } 179 180 /// Construct a basic_socket, opening it and binding it to the given local 181 /// endpoint. 182 /** 183 * This constructor creates a socket and automatically opens it bound to the 184 * specified endpoint on the local machine. The protocol used is the protocol 185 * associated with the given endpoint. 186 * 187 * @param ex The I/O executor that the socket will use, by default, to 188 * dispatch handlers for any asynchronous operations performed on the socket. 189 * 190 * @param endpoint An endpoint on the local machine to which the socket will 191 * be bound. 192 * 193 * @throws boost::system::system_error Thrown on failure. 194 */ basic_socket(const executor_type & ex,const endpoint_type & endpoint)195 basic_socket(const executor_type& ex, const endpoint_type& endpoint) 196 : impl_(0, ex) 197 { 198 boost::system::error_code ec; 199 const protocol_type protocol = endpoint.protocol(); 200 impl_.get_service().open(impl_.get_implementation(), protocol, ec); 201 boost::asio::detail::throw_error(ec, "open"); 202 impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); 203 boost::asio::detail::throw_error(ec, "bind"); 204 } 205 206 /// Construct a basic_socket, opening it and binding it to the given local 207 /// endpoint. 208 /** 209 * This constructor creates a socket and automatically opens it bound to the 210 * specified endpoint on the local machine. The protocol used is the protocol 211 * associated with the given endpoint. 212 * 213 * @param context An execution context which provides the I/O executor that 214 * the socket will use, by default, to dispatch handlers for any asynchronous 215 * operations performed on the socket. 216 * 217 * @param endpoint An endpoint on the local machine to which the socket will 218 * be bound. 219 * 220 * @throws boost::system::system_error Thrown on failure. 221 */ 222 template <typename ExecutionContext> basic_socket(ExecutionContext & context,const endpoint_type & endpoint,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value>::type=0)223 basic_socket(ExecutionContext& context, const endpoint_type& endpoint, 224 typename constraint< 225 is_convertible<ExecutionContext&, execution_context&>::value 226 >::type = 0) 227 : impl_(0, 0, context) 228 { 229 boost::system::error_code ec; 230 const protocol_type protocol = endpoint.protocol(); 231 impl_.get_service().open(impl_.get_implementation(), protocol, ec); 232 boost::asio::detail::throw_error(ec, "open"); 233 impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); 234 boost::asio::detail::throw_error(ec, "bind"); 235 } 236 237 /// Construct a basic_socket on an existing native socket. 238 /** 239 * This constructor creates a socket object to hold an existing native socket. 240 * 241 * @param ex The I/O executor that the socket will use, by default, to 242 * dispatch handlers for any asynchronous operations performed on the socket. 243 * 244 * @param protocol An object specifying protocol parameters to be used. 245 * 246 * @param native_socket A native socket. 247 * 248 * @throws boost::system::system_error Thrown on failure. 249 */ basic_socket(const executor_type & ex,const protocol_type & protocol,const native_handle_type & native_socket)250 basic_socket(const executor_type& ex, const protocol_type& protocol, 251 const native_handle_type& native_socket) 252 : impl_(0, ex) 253 { 254 boost::system::error_code ec; 255 impl_.get_service().assign(impl_.get_implementation(), 256 protocol, native_socket, ec); 257 boost::asio::detail::throw_error(ec, "assign"); 258 } 259 260 /// Construct a basic_socket on an existing native socket. 261 /** 262 * This constructor creates a socket object to hold an existing native socket. 263 * 264 * @param context An execution context which provides the I/O executor that 265 * the socket will use, by default, to dispatch handlers for any asynchronous 266 * operations performed on the socket. 267 * 268 * @param protocol An object specifying protocol parameters to be used. 269 * 270 * @param native_socket A native socket. 271 * 272 * @throws boost::system::system_error Thrown on failure. 273 */ 274 template <typename ExecutionContext> basic_socket(ExecutionContext & context,const protocol_type & protocol,const native_handle_type & native_socket,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value>::type=0)275 basic_socket(ExecutionContext& context, const protocol_type& protocol, 276 const native_handle_type& native_socket, 277 typename constraint< 278 is_convertible<ExecutionContext&, execution_context&>::value 279 >::type = 0) 280 : impl_(0, 0, context) 281 { 282 boost::system::error_code ec; 283 impl_.get_service().assign(impl_.get_implementation(), 284 protocol, native_socket, ec); 285 boost::asio::detail::throw_error(ec, "assign"); 286 } 287 288 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) 289 /// Move-construct a basic_socket from another. 290 /** 291 * This constructor moves a socket from one object to another. 292 * 293 * @param other The other basic_socket object from which the move will 294 * occur. 295 * 296 * @note Following the move, the moved-from object is in the same state as if 297 * constructed using the @c basic_socket(const executor_type&) constructor. 298 */ basic_socket(basic_socket && other)299 basic_socket(basic_socket&& other) BOOST_ASIO_NOEXCEPT 300 : impl_(std::move(other.impl_)) 301 { 302 } 303 304 /// Move-assign a basic_socket from another. 305 /** 306 * This assignment operator moves a socket from one object to another. 307 * 308 * @param other The other basic_socket object from which the move will 309 * occur. 310 * 311 * @note Following the move, the moved-from object is in the same state as if 312 * constructed using the @c basic_socket(const executor_type&) constructor. 313 */ operator =(basic_socket && other)314 basic_socket& operator=(basic_socket&& other) 315 { 316 impl_ = std::move(other.impl_); 317 return *this; 318 } 319 320 // All sockets have access to each other's implementations. 321 template <typename Protocol1, typename Executor1> 322 friend class basic_socket; 323 324 /// Move-construct a basic_socket from a socket of another protocol type. 325 /** 326 * This constructor moves a socket from one object to another. 327 * 328 * @param other The other basic_socket object from which the move will 329 * occur. 330 * 331 * @note Following the move, the moved-from object is in the same state as if 332 * constructed using the @c basic_socket(const executor_type&) constructor. 333 */ 334 template <typename Protocol1, typename Executor1> basic_socket(basic_socket<Protocol1,Executor1> && other,typename constraint<is_convertible<Protocol1,Protocol>::value && is_convertible<Executor1,Executor>::value>::type=0)335 basic_socket(basic_socket<Protocol1, Executor1>&& other, 336 typename constraint< 337 is_convertible<Protocol1, Protocol>::value 338 && is_convertible<Executor1, Executor>::value 339 >::type = 0) 340 : impl_(std::move(other.impl_)) 341 { 342 } 343 344 /// Move-assign a basic_socket from a socket of another protocol type. 345 /** 346 * This assignment operator moves a socket from one object to another. 347 * 348 * @param other The other basic_socket object from which the move will 349 * occur. 350 * 351 * @note Following the move, the moved-from object is in the same state as if 352 * constructed using the @c basic_socket(const executor_type&) constructor. 353 */ 354 template <typename Protocol1, typename Executor1> 355 typename constraint< 356 is_convertible<Protocol1, Protocol>::value 357 && is_convertible<Executor1, Executor>::value, 358 basic_socket& operator =(basic_socket<Protocol1,Executor1> && other)359 >::type operator=(basic_socket<Protocol1, Executor1> && other) 360 { 361 basic_socket tmp(std::move(other)); 362 impl_ = std::move(tmp.impl_); 363 return *this; 364 } 365 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) 366 367 /// Get the executor associated with the object. get_executor()368 executor_type get_executor() BOOST_ASIO_NOEXCEPT 369 { 370 return impl_.get_executor(); 371 } 372 373 #if !defined(BOOST_ASIO_NO_EXTENSIONS) 374 /// Get a reference to the lowest layer. 375 /** 376 * This function returns a reference to the lowest layer in a stack of 377 * layers. Since a basic_socket cannot contain any further layers, it simply 378 * returns a reference to itself. 379 * 380 * @return A reference to the lowest layer in the stack of layers. Ownership 381 * is not transferred to the caller. 382 */ lowest_layer()383 lowest_layer_type& lowest_layer() 384 { 385 return *this; 386 } 387 388 /// Get a const reference to the lowest layer. 389 /** 390 * This function returns a const reference to the lowest layer in a stack of 391 * layers. Since a basic_socket cannot contain any further layers, it simply 392 * returns a reference to itself. 393 * 394 * @return A const reference to the lowest layer in the stack of layers. 395 * Ownership is not transferred to the caller. 396 */ lowest_layer() const397 const lowest_layer_type& lowest_layer() const 398 { 399 return *this; 400 } 401 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS) 402 403 /// Open the socket using the specified protocol. 404 /** 405 * This function opens the socket so that it will use the specified protocol. 406 * 407 * @param protocol An object specifying protocol parameters to be used. 408 * 409 * @throws boost::system::system_error Thrown on failure. 410 * 411 * @par Example 412 * @code 413 * boost::asio::ip::tcp::socket socket(my_context); 414 * socket.open(boost::asio::ip::tcp::v4()); 415 * @endcode 416 */ open(const protocol_type & protocol=protocol_type ())417 void open(const protocol_type& protocol = protocol_type()) 418 { 419 boost::system::error_code ec; 420 impl_.get_service().open(impl_.get_implementation(), protocol, ec); 421 boost::asio::detail::throw_error(ec, "open"); 422 } 423 424 /// Open the socket using the specified protocol. 425 /** 426 * This function opens the socket so that it will use the specified protocol. 427 * 428 * @param protocol An object specifying which protocol is to be used. 429 * 430 * @param ec Set to indicate what error occurred, if any. 431 * 432 * @par Example 433 * @code 434 * boost::asio::ip::tcp::socket socket(my_context); 435 * boost::system::error_code ec; 436 * socket.open(boost::asio::ip::tcp::v4(), ec); 437 * if (ec) 438 * { 439 * // An error occurred. 440 * } 441 * @endcode 442 */ open(const protocol_type & protocol,boost::system::error_code & ec)443 BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol, 444 boost::system::error_code& ec) 445 { 446 impl_.get_service().open(impl_.get_implementation(), protocol, ec); 447 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 448 } 449 450 /// Assign an existing native socket to the socket. 451 /* 452 * This function opens the socket to hold an existing native socket. 453 * 454 * @param protocol An object specifying which protocol is to be used. 455 * 456 * @param native_socket A native socket. 457 * 458 * @throws boost::system::system_error Thrown on failure. 459 */ assign(const protocol_type & protocol,const native_handle_type & native_socket)460 void assign(const protocol_type& protocol, 461 const native_handle_type& native_socket) 462 { 463 boost::system::error_code ec; 464 impl_.get_service().assign(impl_.get_implementation(), 465 protocol, native_socket, ec); 466 boost::asio::detail::throw_error(ec, "assign"); 467 } 468 469 /// Assign an existing native socket to the socket. 470 /* 471 * This function opens the socket to hold an existing native socket. 472 * 473 * @param protocol An object specifying which protocol is to be used. 474 * 475 * @param native_socket A native socket. 476 * 477 * @param ec Set to indicate what error occurred, if any. 478 */ assign(const protocol_type & protocol,const native_handle_type & native_socket,boost::system::error_code & ec)479 BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, 480 const native_handle_type& native_socket, boost::system::error_code& ec) 481 { 482 impl_.get_service().assign(impl_.get_implementation(), 483 protocol, native_socket, ec); 484 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 485 } 486 487 /// Determine whether the socket is open. is_open() const488 bool is_open() const 489 { 490 return impl_.get_service().is_open(impl_.get_implementation()); 491 } 492 493 /// Close the socket. 494 /** 495 * This function is used to close the socket. Any asynchronous send, receive 496 * or connect operations will be cancelled immediately, and will complete 497 * with the boost::asio::error::operation_aborted error. 498 * 499 * @throws boost::system::system_error Thrown on failure. Note that, even if 500 * the function indicates an error, the underlying descriptor is closed. 501 * 502 * @note For portable behaviour with respect to graceful closure of a 503 * connected socket, call shutdown() before closing the socket. 504 */ close()505 void close() 506 { 507 boost::system::error_code ec; 508 impl_.get_service().close(impl_.get_implementation(), ec); 509 boost::asio::detail::throw_error(ec, "close"); 510 } 511 512 /// Close the socket. 513 /** 514 * This function is used to close the socket. Any asynchronous send, receive 515 * or connect operations will be cancelled immediately, and will complete 516 * with the boost::asio::error::operation_aborted error. 517 * 518 * @param ec Set to indicate what error occurred, if any. Note that, even if 519 * the function indicates an error, the underlying descriptor is closed. 520 * 521 * @par Example 522 * @code 523 * boost::asio::ip::tcp::socket socket(my_context); 524 * ... 525 * boost::system::error_code ec; 526 * socket.close(ec); 527 * if (ec) 528 * { 529 * // An error occurred. 530 * } 531 * @endcode 532 * 533 * @note For portable behaviour with respect to graceful closure of a 534 * connected socket, call shutdown() before closing the socket. 535 */ close(boost::system::error_code & ec)536 BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) 537 { 538 impl_.get_service().close(impl_.get_implementation(), ec); 539 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 540 } 541 542 /// Release ownership of the underlying native socket. 543 /** 544 * This function causes all outstanding asynchronous connect, send and receive 545 * operations to finish immediately, and the handlers for cancelled operations 546 * will be passed the boost::asio::error::operation_aborted error. Ownership 547 * of the native socket is then transferred to the caller. 548 * 549 * @throws boost::system::system_error Thrown on failure. 550 * 551 * @note This function is unsupported on Windows versions prior to Windows 552 * 8.1, and will fail with boost::asio::error::operation_not_supported on 553 * these platforms. 554 */ 555 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ 556 && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) 557 __declspec(deprecated("This function always fails with " 558 "operation_not_supported when used on Windows versions " 559 "prior to Windows 8.1.")) 560 #endif release()561 native_handle_type release() 562 { 563 boost::system::error_code ec; 564 native_handle_type s = impl_.get_service().release( 565 impl_.get_implementation(), ec); 566 boost::asio::detail::throw_error(ec, "release"); 567 return s; 568 } 569 570 /// Release ownership of the underlying native socket. 571 /** 572 * This function causes all outstanding asynchronous connect, send and receive 573 * operations to finish immediately, and the handlers for cancelled operations 574 * will be passed the boost::asio::error::operation_aborted error. Ownership 575 * of the native socket is then transferred to the caller. 576 * 577 * @param ec Set to indicate what error occurred, if any. 578 * 579 * @note This function is unsupported on Windows versions prior to Windows 580 * 8.1, and will fail with boost::asio::error::operation_not_supported on 581 * these platforms. 582 */ 583 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ 584 && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) 585 __declspec(deprecated("This function always fails with " 586 "operation_not_supported when used on Windows versions " 587 "prior to Windows 8.1.")) 588 #endif release(boost::system::error_code & ec)589 native_handle_type release(boost::system::error_code& ec) 590 { 591 return impl_.get_service().release(impl_.get_implementation(), ec); 592 } 593 594 /// Get the native socket representation. 595 /** 596 * This function may be used to obtain the underlying representation of the 597 * socket. This is intended to allow access to native socket functionality 598 * that is not otherwise provided. 599 */ native_handle()600 native_handle_type native_handle() 601 { 602 return impl_.get_service().native_handle(impl_.get_implementation()); 603 } 604 605 /// Cancel all asynchronous operations associated with the socket. 606 /** 607 * This function causes all outstanding asynchronous connect, send and receive 608 * operations to finish immediately, and the handlers for cancelled operations 609 * will be passed the boost::asio::error::operation_aborted error. 610 * 611 * @throws boost::system::system_error Thrown on failure. 612 * 613 * @note Calls to cancel() will always fail with 614 * boost::asio::error::operation_not_supported when run on Windows XP, Windows 615 * Server 2003, and earlier versions of Windows, unless 616 * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has 617 * two issues that should be considered before enabling its use: 618 * 619 * @li It will only cancel asynchronous operations that were initiated in the 620 * current thread. 621 * 622 * @li It can appear to complete without error, but the request to cancel the 623 * unfinished operations may be silently ignored by the operating system. 624 * Whether it works or not seems to depend on the drivers that are installed. 625 * 626 * For portable cancellation, consider using one of the following 627 * alternatives: 628 * 629 * @li Disable asio's I/O completion port backend by defining 630 * BOOST_ASIO_DISABLE_IOCP. 631 * 632 * @li Use the close() function to simultaneously cancel the outstanding 633 * operations and close the socket. 634 * 635 * When running on Windows Vista, Windows Server 2008, and later, the 636 * CancelIoEx function is always used. This function does not have the 637 * problems described above. 638 */ 639 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ 640 && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ 641 && !defined(BOOST_ASIO_ENABLE_CANCELIO) 642 __declspec(deprecated("By default, this function always fails with " 643 "operation_not_supported when used on Windows XP, Windows Server 2003, " 644 "or earlier. Consult documentation for details.")) 645 #endif cancel()646 void cancel() 647 { 648 boost::system::error_code ec; 649 impl_.get_service().cancel(impl_.get_implementation(), ec); 650 boost::asio::detail::throw_error(ec, "cancel"); 651 } 652 653 /// Cancel all asynchronous operations associated with the socket. 654 /** 655 * This function causes all outstanding asynchronous connect, send and receive 656 * operations to finish immediately, and the handlers for cancelled operations 657 * will be passed the boost::asio::error::operation_aborted error. 658 * 659 * @param ec Set to indicate what error occurred, if any. 660 * 661 * @note Calls to cancel() will always fail with 662 * boost::asio::error::operation_not_supported when run on Windows XP, Windows 663 * Server 2003, and earlier versions of Windows, unless 664 * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has 665 * two issues that should be considered before enabling its use: 666 * 667 * @li It will only cancel asynchronous operations that were initiated in the 668 * current thread. 669 * 670 * @li It can appear to complete without error, but the request to cancel the 671 * unfinished operations may be silently ignored by the operating system. 672 * Whether it works or not seems to depend on the drivers that are installed. 673 * 674 * For portable cancellation, consider using one of the following 675 * alternatives: 676 * 677 * @li Disable asio's I/O completion port backend by defining 678 * BOOST_ASIO_DISABLE_IOCP. 679 * 680 * @li Use the close() function to simultaneously cancel the outstanding 681 * operations and close the socket. 682 * 683 * When running on Windows Vista, Windows Server 2008, and later, the 684 * CancelIoEx function is always used. This function does not have the 685 * problems described above. 686 */ 687 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ 688 && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ 689 && !defined(BOOST_ASIO_ENABLE_CANCELIO) 690 __declspec(deprecated("By default, this function always fails with " 691 "operation_not_supported when used on Windows XP, Windows Server 2003, " 692 "or earlier. Consult documentation for details.")) 693 #endif cancel(boost::system::error_code & ec)694 BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) 695 { 696 impl_.get_service().cancel(impl_.get_implementation(), ec); 697 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 698 } 699 700 /// Determine whether the socket is at the out-of-band data mark. 701 /** 702 * This function is used to check whether the socket input is currently 703 * positioned at the out-of-band data mark. 704 * 705 * @return A bool indicating whether the socket is at the out-of-band data 706 * mark. 707 * 708 * @throws boost::system::system_error Thrown on failure. 709 */ at_mark() const710 bool at_mark() const 711 { 712 boost::system::error_code ec; 713 bool b = impl_.get_service().at_mark(impl_.get_implementation(), ec); 714 boost::asio::detail::throw_error(ec, "at_mark"); 715 return b; 716 } 717 718 /// Determine whether the socket is at the out-of-band data mark. 719 /** 720 * This function is used to check whether the socket input is currently 721 * positioned at the out-of-band data mark. 722 * 723 * @param ec Set to indicate what error occurred, if any. 724 * 725 * @return A bool indicating whether the socket is at the out-of-band data 726 * mark. 727 */ at_mark(boost::system::error_code & ec) const728 bool at_mark(boost::system::error_code& ec) const 729 { 730 return impl_.get_service().at_mark(impl_.get_implementation(), ec); 731 } 732 733 /// Determine the number of bytes available for reading. 734 /** 735 * This function is used to determine the number of bytes that may be read 736 * without blocking. 737 * 738 * @return The number of bytes that may be read without blocking, or 0 if an 739 * error occurs. 740 * 741 * @throws boost::system::system_error Thrown on failure. 742 */ available() const743 std::size_t available() const 744 { 745 boost::system::error_code ec; 746 std::size_t s = impl_.get_service().available( 747 impl_.get_implementation(), ec); 748 boost::asio::detail::throw_error(ec, "available"); 749 return s; 750 } 751 752 /// Determine the number of bytes available for reading. 753 /** 754 * This function is used to determine the number of bytes that may be read 755 * without blocking. 756 * 757 * @param ec Set to indicate what error occurred, if any. 758 * 759 * @return The number of bytes that may be read without blocking, or 0 if an 760 * error occurs. 761 */ available(boost::system::error_code & ec) const762 std::size_t available(boost::system::error_code& ec) const 763 { 764 return impl_.get_service().available(impl_.get_implementation(), ec); 765 } 766 767 /// Bind the socket to the given local endpoint. 768 /** 769 * This function binds the socket to the specified endpoint on the local 770 * machine. 771 * 772 * @param endpoint An endpoint on the local machine to which the socket will 773 * be bound. 774 * 775 * @throws boost::system::system_error Thrown on failure. 776 * 777 * @par Example 778 * @code 779 * boost::asio::ip::tcp::socket socket(my_context); 780 * socket.open(boost::asio::ip::tcp::v4()); 781 * socket.bind(boost::asio::ip::tcp::endpoint( 782 * boost::asio::ip::tcp::v4(), 12345)); 783 * @endcode 784 */ bind(const endpoint_type & endpoint)785 void bind(const endpoint_type& endpoint) 786 { 787 boost::system::error_code ec; 788 impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); 789 boost::asio::detail::throw_error(ec, "bind"); 790 } 791 792 /// Bind the socket to the given local endpoint. 793 /** 794 * This function binds the socket to the specified endpoint on the local 795 * machine. 796 * 797 * @param endpoint An endpoint on the local machine to which the socket will 798 * be bound. 799 * 800 * @param ec Set to indicate what error occurred, if any. 801 * 802 * @par Example 803 * @code 804 * boost::asio::ip::tcp::socket socket(my_context); 805 * socket.open(boost::asio::ip::tcp::v4()); 806 * boost::system::error_code ec; 807 * socket.bind(boost::asio::ip::tcp::endpoint( 808 * boost::asio::ip::tcp::v4(), 12345), ec); 809 * if (ec) 810 * { 811 * // An error occurred. 812 * } 813 * @endcode 814 */ bind(const endpoint_type & endpoint,boost::system::error_code & ec)815 BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, 816 boost::system::error_code& ec) 817 { 818 impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); 819 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 820 } 821 822 /// Connect the socket to the specified endpoint. 823 /** 824 * This function is used to connect a socket to the specified remote endpoint. 825 * The function call will block until the connection is successfully made or 826 * an error occurs. 827 * 828 * The socket is automatically opened if it is not already open. If the 829 * connect fails, and the socket was automatically opened, the socket is 830 * not returned to the closed state. 831 * 832 * @param peer_endpoint The remote endpoint to which the socket will be 833 * connected. 834 * 835 * @throws boost::system::system_error Thrown on failure. 836 * 837 * @par Example 838 * @code 839 * boost::asio::ip::tcp::socket socket(my_context); 840 * boost::asio::ip::tcp::endpoint endpoint( 841 * boost::asio::ip::address::from_string("1.2.3.4"), 12345); 842 * socket.connect(endpoint); 843 * @endcode 844 */ connect(const endpoint_type & peer_endpoint)845 void connect(const endpoint_type& peer_endpoint) 846 { 847 boost::system::error_code ec; 848 if (!is_open()) 849 { 850 impl_.get_service().open(impl_.get_implementation(), 851 peer_endpoint.protocol(), ec); 852 boost::asio::detail::throw_error(ec, "connect"); 853 } 854 impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); 855 boost::asio::detail::throw_error(ec, "connect"); 856 } 857 858 /// Connect the socket to the specified endpoint. 859 /** 860 * This function is used to connect a socket to the specified remote endpoint. 861 * The function call will block until the connection is successfully made or 862 * an error occurs. 863 * 864 * The socket is automatically opened if it is not already open. If the 865 * connect fails, and the socket was automatically opened, the socket is 866 * not returned to the closed state. 867 * 868 * @param peer_endpoint The remote endpoint to which the socket will be 869 * connected. 870 * 871 * @param ec Set to indicate what error occurred, if any. 872 * 873 * @par Example 874 * @code 875 * boost::asio::ip::tcp::socket socket(my_context); 876 * boost::asio::ip::tcp::endpoint endpoint( 877 * boost::asio::ip::address::from_string("1.2.3.4"), 12345); 878 * boost::system::error_code ec; 879 * socket.connect(endpoint, ec); 880 * if (ec) 881 * { 882 * // An error occurred. 883 * } 884 * @endcode 885 */ connect(const endpoint_type & peer_endpoint,boost::system::error_code & ec)886 BOOST_ASIO_SYNC_OP_VOID connect(const endpoint_type& peer_endpoint, 887 boost::system::error_code& ec) 888 { 889 if (!is_open()) 890 { 891 impl_.get_service().open(impl_.get_implementation(), 892 peer_endpoint.protocol(), ec); 893 if (ec) 894 { 895 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 896 } 897 } 898 899 impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); 900 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 901 } 902 903 /// Start an asynchronous connect. 904 /** 905 * This function is used to asynchronously connect a socket to the specified 906 * remote endpoint. The function call always returns immediately. 907 * 908 * The socket is automatically opened if it is not already open. If the 909 * connect fails, and the socket was automatically opened, the socket is 910 * not returned to the closed state. 911 * 912 * @param peer_endpoint The remote endpoint to which the socket will be 913 * connected. Copies will be made of the endpoint object as required. 914 * 915 * @param handler The handler to be called when the connection operation 916 * completes. Copies will be made of the handler as required. The function 917 * signature of the handler must be: 918 * @code void handler( 919 * const boost::system::error_code& error // Result of operation 920 * ); @endcode 921 * Regardless of whether the asynchronous operation completes immediately or 922 * not, the handler will not be invoked from within this function. On 923 * immediate completion, invocation of the handler will be performed in a 924 * manner equivalent to using boost::asio::post(). 925 * 926 * @par Example 927 * @code 928 * void connect_handler(const boost::system::error_code& error) 929 * { 930 * if (!error) 931 * { 932 * // Connect succeeded. 933 * } 934 * } 935 * 936 * ... 937 * 938 * boost::asio::ip::tcp::socket socket(my_context); 939 * boost::asio::ip::tcp::endpoint endpoint( 940 * boost::asio::ip::address::from_string("1.2.3.4"), 12345); 941 * socket.async_connect(endpoint, connect_handler); 942 * @endcode 943 */ 944 template < 945 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code)) 946 ConnectHandler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ConnectHandler,void (boost::system::error_code))947 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ConnectHandler, 948 void (boost::system::error_code)) 949 async_connect(const endpoint_type& peer_endpoint, 950 BOOST_ASIO_MOVE_ARG(ConnectHandler) handler 951 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) 952 { 953 boost::system::error_code open_ec; 954 if (!is_open()) 955 { 956 const protocol_type protocol = peer_endpoint.protocol(); 957 impl_.get_service().open(impl_.get_implementation(), protocol, open_ec); 958 } 959 960 return async_initiate<ConnectHandler, void (boost::system::error_code)>( 961 initiate_async_connect(this), handler, peer_endpoint, open_ec); 962 } 963 964 /// Set an option on the socket. 965 /** 966 * This function is used to set an option on the socket. 967 * 968 * @param option The new option value to be set on the socket. 969 * 970 * @throws boost::system::system_error Thrown on failure. 971 * 972 * @sa SettableSocketOption @n 973 * boost::asio::socket_base::broadcast @n 974 * boost::asio::socket_base::do_not_route @n 975 * boost::asio::socket_base::keep_alive @n 976 * boost::asio::socket_base::linger @n 977 * boost::asio::socket_base::receive_buffer_size @n 978 * boost::asio::socket_base::receive_low_watermark @n 979 * boost::asio::socket_base::reuse_address @n 980 * boost::asio::socket_base::send_buffer_size @n 981 * boost::asio::socket_base::send_low_watermark @n 982 * boost::asio::ip::multicast::join_group @n 983 * boost::asio::ip::multicast::leave_group @n 984 * boost::asio::ip::multicast::enable_loopback @n 985 * boost::asio::ip::multicast::outbound_interface @n 986 * boost::asio::ip::multicast::hops @n 987 * boost::asio::ip::tcp::no_delay 988 * 989 * @par Example 990 * Setting the IPPROTO_TCP/TCP_NODELAY option: 991 * @code 992 * boost::asio::ip::tcp::socket socket(my_context); 993 * ... 994 * boost::asio::ip::tcp::no_delay option(true); 995 * socket.set_option(option); 996 * @endcode 997 */ 998 template <typename SettableSocketOption> set_option(const SettableSocketOption & option)999 void set_option(const SettableSocketOption& option) 1000 { 1001 boost::system::error_code ec; 1002 impl_.get_service().set_option(impl_.get_implementation(), option, ec); 1003 boost::asio::detail::throw_error(ec, "set_option"); 1004 } 1005 1006 /// Set an option on the socket. 1007 /** 1008 * This function is used to set an option on the socket. 1009 * 1010 * @param option The new option value to be set on the socket. 1011 * 1012 * @param ec Set to indicate what error occurred, if any. 1013 * 1014 * @sa SettableSocketOption @n 1015 * boost::asio::socket_base::broadcast @n 1016 * boost::asio::socket_base::do_not_route @n 1017 * boost::asio::socket_base::keep_alive @n 1018 * boost::asio::socket_base::linger @n 1019 * boost::asio::socket_base::receive_buffer_size @n 1020 * boost::asio::socket_base::receive_low_watermark @n 1021 * boost::asio::socket_base::reuse_address @n 1022 * boost::asio::socket_base::send_buffer_size @n 1023 * boost::asio::socket_base::send_low_watermark @n 1024 * boost::asio::ip::multicast::join_group @n 1025 * boost::asio::ip::multicast::leave_group @n 1026 * boost::asio::ip::multicast::enable_loopback @n 1027 * boost::asio::ip::multicast::outbound_interface @n 1028 * boost::asio::ip::multicast::hops @n 1029 * boost::asio::ip::tcp::no_delay 1030 * 1031 * @par Example 1032 * Setting the IPPROTO_TCP/TCP_NODELAY option: 1033 * @code 1034 * boost::asio::ip::tcp::socket socket(my_context); 1035 * ... 1036 * boost::asio::ip::tcp::no_delay option(true); 1037 * boost::system::error_code ec; 1038 * socket.set_option(option, ec); 1039 * if (ec) 1040 * { 1041 * // An error occurred. 1042 * } 1043 * @endcode 1044 */ 1045 template <typename SettableSocketOption> set_option(const SettableSocketOption & option,boost::system::error_code & ec)1046 BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, 1047 boost::system::error_code& ec) 1048 { 1049 impl_.get_service().set_option(impl_.get_implementation(), option, ec); 1050 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 1051 } 1052 1053 /// Get an option from the socket. 1054 /** 1055 * This function is used to get the current value of an option on the socket. 1056 * 1057 * @param option The option value to be obtained from the socket. 1058 * 1059 * @throws boost::system::system_error Thrown on failure. 1060 * 1061 * @sa GettableSocketOption @n 1062 * boost::asio::socket_base::broadcast @n 1063 * boost::asio::socket_base::do_not_route @n 1064 * boost::asio::socket_base::keep_alive @n 1065 * boost::asio::socket_base::linger @n 1066 * boost::asio::socket_base::receive_buffer_size @n 1067 * boost::asio::socket_base::receive_low_watermark @n 1068 * boost::asio::socket_base::reuse_address @n 1069 * boost::asio::socket_base::send_buffer_size @n 1070 * boost::asio::socket_base::send_low_watermark @n 1071 * boost::asio::ip::multicast::join_group @n 1072 * boost::asio::ip::multicast::leave_group @n 1073 * boost::asio::ip::multicast::enable_loopback @n 1074 * boost::asio::ip::multicast::outbound_interface @n 1075 * boost::asio::ip::multicast::hops @n 1076 * boost::asio::ip::tcp::no_delay 1077 * 1078 * @par Example 1079 * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: 1080 * @code 1081 * boost::asio::ip::tcp::socket socket(my_context); 1082 * ... 1083 * boost::asio::ip::tcp::socket::keep_alive option; 1084 * socket.get_option(option); 1085 * bool is_set = option.value(); 1086 * @endcode 1087 */ 1088 template <typename GettableSocketOption> get_option(GettableSocketOption & option) const1089 void get_option(GettableSocketOption& option) const 1090 { 1091 boost::system::error_code ec; 1092 impl_.get_service().get_option(impl_.get_implementation(), option, ec); 1093 boost::asio::detail::throw_error(ec, "get_option"); 1094 } 1095 1096 /// Get an option from the socket. 1097 /** 1098 * This function is used to get the current value of an option on the socket. 1099 * 1100 * @param option The option value to be obtained from the socket. 1101 * 1102 * @param ec Set to indicate what error occurred, if any. 1103 * 1104 * @sa GettableSocketOption @n 1105 * boost::asio::socket_base::broadcast @n 1106 * boost::asio::socket_base::do_not_route @n 1107 * boost::asio::socket_base::keep_alive @n 1108 * boost::asio::socket_base::linger @n 1109 * boost::asio::socket_base::receive_buffer_size @n 1110 * boost::asio::socket_base::receive_low_watermark @n 1111 * boost::asio::socket_base::reuse_address @n 1112 * boost::asio::socket_base::send_buffer_size @n 1113 * boost::asio::socket_base::send_low_watermark @n 1114 * boost::asio::ip::multicast::join_group @n 1115 * boost::asio::ip::multicast::leave_group @n 1116 * boost::asio::ip::multicast::enable_loopback @n 1117 * boost::asio::ip::multicast::outbound_interface @n 1118 * boost::asio::ip::multicast::hops @n 1119 * boost::asio::ip::tcp::no_delay 1120 * 1121 * @par Example 1122 * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: 1123 * @code 1124 * boost::asio::ip::tcp::socket socket(my_context); 1125 * ... 1126 * boost::asio::ip::tcp::socket::keep_alive option; 1127 * boost::system::error_code ec; 1128 * socket.get_option(option, ec); 1129 * if (ec) 1130 * { 1131 * // An error occurred. 1132 * } 1133 * bool is_set = option.value(); 1134 * @endcode 1135 */ 1136 template <typename GettableSocketOption> get_option(GettableSocketOption & option,boost::system::error_code & ec) const1137 BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, 1138 boost::system::error_code& ec) const 1139 { 1140 impl_.get_service().get_option(impl_.get_implementation(), option, ec); 1141 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 1142 } 1143 1144 /// Perform an IO control command on the socket. 1145 /** 1146 * This function is used to execute an IO control command on the socket. 1147 * 1148 * @param command The IO control command to be performed on the socket. 1149 * 1150 * @throws boost::system::system_error Thrown on failure. 1151 * 1152 * @sa IoControlCommand @n 1153 * boost::asio::socket_base::bytes_readable @n 1154 * boost::asio::socket_base::non_blocking_io 1155 * 1156 * @par Example 1157 * Getting the number of bytes ready to read: 1158 * @code 1159 * boost::asio::ip::tcp::socket socket(my_context); 1160 * ... 1161 * boost::asio::ip::tcp::socket::bytes_readable command; 1162 * socket.io_control(command); 1163 * std::size_t bytes_readable = command.get(); 1164 * @endcode 1165 */ 1166 template <typename IoControlCommand> io_control(IoControlCommand & command)1167 void io_control(IoControlCommand& command) 1168 { 1169 boost::system::error_code ec; 1170 impl_.get_service().io_control(impl_.get_implementation(), command, ec); 1171 boost::asio::detail::throw_error(ec, "io_control"); 1172 } 1173 1174 /// Perform an IO control command on the socket. 1175 /** 1176 * This function is used to execute an IO control command on the socket. 1177 * 1178 * @param command The IO control command to be performed on the socket. 1179 * 1180 * @param ec Set to indicate what error occurred, if any. 1181 * 1182 * @sa IoControlCommand @n 1183 * boost::asio::socket_base::bytes_readable @n 1184 * boost::asio::socket_base::non_blocking_io 1185 * 1186 * @par Example 1187 * Getting the number of bytes ready to read: 1188 * @code 1189 * boost::asio::ip::tcp::socket socket(my_context); 1190 * ... 1191 * boost::asio::ip::tcp::socket::bytes_readable command; 1192 * boost::system::error_code ec; 1193 * socket.io_control(command, ec); 1194 * if (ec) 1195 * { 1196 * // An error occurred. 1197 * } 1198 * std::size_t bytes_readable = command.get(); 1199 * @endcode 1200 */ 1201 template <typename IoControlCommand> io_control(IoControlCommand & command,boost::system::error_code & ec)1202 BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, 1203 boost::system::error_code& ec) 1204 { 1205 impl_.get_service().io_control(impl_.get_implementation(), command, ec); 1206 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 1207 } 1208 1209 /// Gets the non-blocking mode of the socket. 1210 /** 1211 * @returns @c true if the socket's synchronous operations will fail with 1212 * boost::asio::error::would_block if they are unable to perform the requested 1213 * operation immediately. If @c false, synchronous operations will block 1214 * until complete. 1215 * 1216 * @note The non-blocking mode has no effect on the behaviour of asynchronous 1217 * operations. Asynchronous operations will never fail with the error 1218 * boost::asio::error::would_block. 1219 */ non_blocking() const1220 bool non_blocking() const 1221 { 1222 return impl_.get_service().non_blocking(impl_.get_implementation()); 1223 } 1224 1225 /// Sets the non-blocking mode of the socket. 1226 /** 1227 * @param mode If @c true, the socket's synchronous operations will fail with 1228 * boost::asio::error::would_block if they are unable to perform the requested 1229 * operation immediately. If @c false, synchronous operations will block 1230 * until complete. 1231 * 1232 * @throws boost::system::system_error Thrown on failure. 1233 * 1234 * @note The non-blocking mode has no effect on the behaviour of asynchronous 1235 * operations. Asynchronous operations will never fail with the error 1236 * boost::asio::error::would_block. 1237 */ non_blocking(bool mode)1238 void non_blocking(bool mode) 1239 { 1240 boost::system::error_code ec; 1241 impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); 1242 boost::asio::detail::throw_error(ec, "non_blocking"); 1243 } 1244 1245 /// Sets the non-blocking mode of the socket. 1246 /** 1247 * @param mode If @c true, the socket's synchronous operations will fail with 1248 * boost::asio::error::would_block if they are unable to perform the requested 1249 * operation immediately. If @c false, synchronous operations will block 1250 * until complete. 1251 * 1252 * @param ec Set to indicate what error occurred, if any. 1253 * 1254 * @note The non-blocking mode has no effect on the behaviour of asynchronous 1255 * operations. Asynchronous operations will never fail with the error 1256 * boost::asio::error::would_block. 1257 */ non_blocking(bool mode,boost::system::error_code & ec)1258 BOOST_ASIO_SYNC_OP_VOID non_blocking( 1259 bool mode, boost::system::error_code& ec) 1260 { 1261 impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); 1262 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 1263 } 1264 1265 /// Gets the non-blocking mode of the native socket implementation. 1266 /** 1267 * This function is used to retrieve the non-blocking mode of the underlying 1268 * native socket. This mode has no effect on the behaviour of the socket 1269 * object's synchronous operations. 1270 * 1271 * @returns @c true if the underlying socket is in non-blocking mode and 1272 * direct system calls may fail with boost::asio::error::would_block (or the 1273 * equivalent system error). 1274 * 1275 * @note The current non-blocking mode is cached by the socket object. 1276 * Consequently, the return value may be incorrect if the non-blocking mode 1277 * was set directly on the native socket. 1278 * 1279 * @par Example 1280 * This function is intended to allow the encapsulation of arbitrary 1281 * non-blocking system calls as asynchronous operations, in a way that is 1282 * transparent to the user of the socket object. The following example 1283 * illustrates how Linux's @c sendfile system call might be encapsulated: 1284 * @code template <typename Handler> 1285 * struct sendfile_op 1286 * { 1287 * tcp::socket& sock_; 1288 * int fd_; 1289 * Handler handler_; 1290 * off_t offset_; 1291 * std::size_t total_bytes_transferred_; 1292 * 1293 * // Function call operator meeting WriteHandler requirements. 1294 * // Used as the handler for the async_write_some operation. 1295 * void operator()(boost::system::error_code ec, std::size_t) 1296 * { 1297 * // Put the underlying socket into non-blocking mode. 1298 * if (!ec) 1299 * if (!sock_.native_non_blocking()) 1300 * sock_.native_non_blocking(true, ec); 1301 * 1302 * if (!ec) 1303 * { 1304 * for (;;) 1305 * { 1306 * // Try the system call. 1307 * errno = 0; 1308 * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); 1309 * ec = boost::system::error_code(n < 0 ? errno : 0, 1310 * boost::asio::error::get_system_category()); 1311 * total_bytes_transferred_ += ec ? 0 : n; 1312 * 1313 * // Retry operation immediately if interrupted by signal. 1314 * if (ec == boost::asio::error::interrupted) 1315 * continue; 1316 * 1317 * // Check if we need to run the operation again. 1318 * if (ec == boost::asio::error::would_block 1319 * || ec == boost::asio::error::try_again) 1320 * { 1321 * // We have to wait for the socket to become ready again. 1322 * sock_.async_wait(tcp::socket::wait_write, *this); 1323 * return; 1324 * } 1325 * 1326 * if (ec || n == 0) 1327 * { 1328 * // An error occurred, or we have reached the end of the file. 1329 * // Either way we must exit the loop so we can call the handler. 1330 * break; 1331 * } 1332 * 1333 * // Loop around to try calling sendfile again. 1334 * } 1335 * } 1336 * 1337 * // Pass result back to user's handler. 1338 * handler_(ec, total_bytes_transferred_); 1339 * } 1340 * }; 1341 * 1342 * template <typename Handler> 1343 * void async_sendfile(tcp::socket& sock, int fd, Handler h) 1344 * { 1345 * sendfile_op<Handler> op = { sock, fd, h, 0, 0 }; 1346 * sock.async_wait(tcp::socket::wait_write, op); 1347 * } @endcode 1348 */ native_non_blocking() const1349 bool native_non_blocking() const 1350 { 1351 return impl_.get_service().native_non_blocking(impl_.get_implementation()); 1352 } 1353 1354 /// Sets the non-blocking mode of the native socket implementation. 1355 /** 1356 * This function is used to modify the non-blocking mode of the underlying 1357 * native socket. It has no effect on the behaviour of the socket object's 1358 * synchronous operations. 1359 * 1360 * @param mode If @c true, the underlying socket is put into non-blocking 1361 * mode and direct system calls may fail with boost::asio::error::would_block 1362 * (or the equivalent system error). 1363 * 1364 * @throws boost::system::system_error Thrown on failure. If the @c mode is 1365 * @c false, but the current value of @c non_blocking() is @c true, this 1366 * function fails with boost::asio::error::invalid_argument, as the 1367 * combination does not make sense. 1368 * 1369 * @par Example 1370 * This function is intended to allow the encapsulation of arbitrary 1371 * non-blocking system calls as asynchronous operations, in a way that is 1372 * transparent to the user of the socket object. The following example 1373 * illustrates how Linux's @c sendfile system call might be encapsulated: 1374 * @code template <typename Handler> 1375 * struct sendfile_op 1376 * { 1377 * tcp::socket& sock_; 1378 * int fd_; 1379 * Handler handler_; 1380 * off_t offset_; 1381 * std::size_t total_bytes_transferred_; 1382 * 1383 * // Function call operator meeting WriteHandler requirements. 1384 * // Used as the handler for the async_write_some operation. 1385 * void operator()(boost::system::error_code ec, std::size_t) 1386 * { 1387 * // Put the underlying socket into non-blocking mode. 1388 * if (!ec) 1389 * if (!sock_.native_non_blocking()) 1390 * sock_.native_non_blocking(true, ec); 1391 * 1392 * if (!ec) 1393 * { 1394 * for (;;) 1395 * { 1396 * // Try the system call. 1397 * errno = 0; 1398 * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); 1399 * ec = boost::system::error_code(n < 0 ? errno : 0, 1400 * boost::asio::error::get_system_category()); 1401 * total_bytes_transferred_ += ec ? 0 : n; 1402 * 1403 * // Retry operation immediately if interrupted by signal. 1404 * if (ec == boost::asio::error::interrupted) 1405 * continue; 1406 * 1407 * // Check if we need to run the operation again. 1408 * if (ec == boost::asio::error::would_block 1409 * || ec == boost::asio::error::try_again) 1410 * { 1411 * // We have to wait for the socket to become ready again. 1412 * sock_.async_wait(tcp::socket::wait_write, *this); 1413 * return; 1414 * } 1415 * 1416 * if (ec || n == 0) 1417 * { 1418 * // An error occurred, or we have reached the end of the file. 1419 * // Either way we must exit the loop so we can call the handler. 1420 * break; 1421 * } 1422 * 1423 * // Loop around to try calling sendfile again. 1424 * } 1425 * } 1426 * 1427 * // Pass result back to user's handler. 1428 * handler_(ec, total_bytes_transferred_); 1429 * } 1430 * }; 1431 * 1432 * template <typename Handler> 1433 * void async_sendfile(tcp::socket& sock, int fd, Handler h) 1434 * { 1435 * sendfile_op<Handler> op = { sock, fd, h, 0, 0 }; 1436 * sock.async_wait(tcp::socket::wait_write, op); 1437 * } @endcode 1438 */ native_non_blocking(bool mode)1439 void native_non_blocking(bool mode) 1440 { 1441 boost::system::error_code ec; 1442 impl_.get_service().native_non_blocking( 1443 impl_.get_implementation(), mode, ec); 1444 boost::asio::detail::throw_error(ec, "native_non_blocking"); 1445 } 1446 1447 /// Sets the non-blocking mode of the native socket implementation. 1448 /** 1449 * This function is used to modify the non-blocking mode of the underlying 1450 * native socket. It has no effect on the behaviour of the socket object's 1451 * synchronous operations. 1452 * 1453 * @param mode If @c true, the underlying socket is put into non-blocking 1454 * mode and direct system calls may fail with boost::asio::error::would_block 1455 * (or the equivalent system error). 1456 * 1457 * @param ec Set to indicate what error occurred, if any. If the @c mode is 1458 * @c false, but the current value of @c non_blocking() is @c true, this 1459 * function fails with boost::asio::error::invalid_argument, as the 1460 * combination does not make sense. 1461 * 1462 * @par Example 1463 * This function is intended to allow the encapsulation of arbitrary 1464 * non-blocking system calls as asynchronous operations, in a way that is 1465 * transparent to the user of the socket object. The following example 1466 * illustrates how Linux's @c sendfile system call might be encapsulated: 1467 * @code template <typename Handler> 1468 * struct sendfile_op 1469 * { 1470 * tcp::socket& sock_; 1471 * int fd_; 1472 * Handler handler_; 1473 * off_t offset_; 1474 * std::size_t total_bytes_transferred_; 1475 * 1476 * // Function call operator meeting WriteHandler requirements. 1477 * // Used as the handler for the async_write_some operation. 1478 * void operator()(boost::system::error_code ec, std::size_t) 1479 * { 1480 * // Put the underlying socket into non-blocking mode. 1481 * if (!ec) 1482 * if (!sock_.native_non_blocking()) 1483 * sock_.native_non_blocking(true, ec); 1484 * 1485 * if (!ec) 1486 * { 1487 * for (;;) 1488 * { 1489 * // Try the system call. 1490 * errno = 0; 1491 * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); 1492 * ec = boost::system::error_code(n < 0 ? errno : 0, 1493 * boost::asio::error::get_system_category()); 1494 * total_bytes_transferred_ += ec ? 0 : n; 1495 * 1496 * // Retry operation immediately if interrupted by signal. 1497 * if (ec == boost::asio::error::interrupted) 1498 * continue; 1499 * 1500 * // Check if we need to run the operation again. 1501 * if (ec == boost::asio::error::would_block 1502 * || ec == boost::asio::error::try_again) 1503 * { 1504 * // We have to wait for the socket to become ready again. 1505 * sock_.async_wait(tcp::socket::wait_write, *this); 1506 * return; 1507 * } 1508 * 1509 * if (ec || n == 0) 1510 * { 1511 * // An error occurred, or we have reached the end of the file. 1512 * // Either way we must exit the loop so we can call the handler. 1513 * break; 1514 * } 1515 * 1516 * // Loop around to try calling sendfile again. 1517 * } 1518 * } 1519 * 1520 * // Pass result back to user's handler. 1521 * handler_(ec, total_bytes_transferred_); 1522 * } 1523 * }; 1524 * 1525 * template <typename Handler> 1526 * void async_sendfile(tcp::socket& sock, int fd, Handler h) 1527 * { 1528 * sendfile_op<Handler> op = { sock, fd, h, 0, 0 }; 1529 * sock.async_wait(tcp::socket::wait_write, op); 1530 * } @endcode 1531 */ native_non_blocking(bool mode,boost::system::error_code & ec)1532 BOOST_ASIO_SYNC_OP_VOID native_non_blocking( 1533 bool mode, boost::system::error_code& ec) 1534 { 1535 impl_.get_service().native_non_blocking( 1536 impl_.get_implementation(), mode, ec); 1537 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 1538 } 1539 1540 /// Get the local endpoint of the socket. 1541 /** 1542 * This function is used to obtain the locally bound endpoint of the socket. 1543 * 1544 * @returns An object that represents the local endpoint of the socket. 1545 * 1546 * @throws boost::system::system_error Thrown on failure. 1547 * 1548 * @par Example 1549 * @code 1550 * boost::asio::ip::tcp::socket socket(my_context); 1551 * ... 1552 * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(); 1553 * @endcode 1554 */ local_endpoint() const1555 endpoint_type local_endpoint() const 1556 { 1557 boost::system::error_code ec; 1558 endpoint_type ep = impl_.get_service().local_endpoint( 1559 impl_.get_implementation(), ec); 1560 boost::asio::detail::throw_error(ec, "local_endpoint"); 1561 return ep; 1562 } 1563 1564 /// Get the local endpoint of the socket. 1565 /** 1566 * This function is used to obtain the locally bound endpoint of the socket. 1567 * 1568 * @param ec Set to indicate what error occurred, if any. 1569 * 1570 * @returns An object that represents the local endpoint of the socket. 1571 * Returns a default-constructed endpoint object if an error occurred. 1572 * 1573 * @par Example 1574 * @code 1575 * boost::asio::ip::tcp::socket socket(my_context); 1576 * ... 1577 * boost::system::error_code ec; 1578 * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec); 1579 * if (ec) 1580 * { 1581 * // An error occurred. 1582 * } 1583 * @endcode 1584 */ local_endpoint(boost::system::error_code & ec) const1585 endpoint_type local_endpoint(boost::system::error_code& ec) const 1586 { 1587 return impl_.get_service().local_endpoint(impl_.get_implementation(), ec); 1588 } 1589 1590 /// Get the remote endpoint of the socket. 1591 /** 1592 * This function is used to obtain the remote endpoint of the socket. 1593 * 1594 * @returns An object that represents the remote endpoint of the socket. 1595 * 1596 * @throws boost::system::system_error Thrown on failure. 1597 * 1598 * @par Example 1599 * @code 1600 * boost::asio::ip::tcp::socket socket(my_context); 1601 * ... 1602 * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(); 1603 * @endcode 1604 */ remote_endpoint() const1605 endpoint_type remote_endpoint() const 1606 { 1607 boost::system::error_code ec; 1608 endpoint_type ep = impl_.get_service().remote_endpoint( 1609 impl_.get_implementation(), ec); 1610 boost::asio::detail::throw_error(ec, "remote_endpoint"); 1611 return ep; 1612 } 1613 1614 /// Get the remote endpoint of the socket. 1615 /** 1616 * This function is used to obtain the remote endpoint of the socket. 1617 * 1618 * @param ec Set to indicate what error occurred, if any. 1619 * 1620 * @returns An object that represents the remote endpoint of the socket. 1621 * Returns a default-constructed endpoint object if an error occurred. 1622 * 1623 * @par Example 1624 * @code 1625 * boost::asio::ip::tcp::socket socket(my_context); 1626 * ... 1627 * boost::system::error_code ec; 1628 * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec); 1629 * if (ec) 1630 * { 1631 * // An error occurred. 1632 * } 1633 * @endcode 1634 */ remote_endpoint(boost::system::error_code & ec) const1635 endpoint_type remote_endpoint(boost::system::error_code& ec) const 1636 { 1637 return impl_.get_service().remote_endpoint(impl_.get_implementation(), ec); 1638 } 1639 1640 /// Disable sends or receives on the socket. 1641 /** 1642 * This function is used to disable send operations, receive operations, or 1643 * both. 1644 * 1645 * @param what Determines what types of operation will no longer be allowed. 1646 * 1647 * @throws boost::system::system_error Thrown on failure. 1648 * 1649 * @par Example 1650 * Shutting down the send side of the socket: 1651 * @code 1652 * boost::asio::ip::tcp::socket socket(my_context); 1653 * ... 1654 * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send); 1655 * @endcode 1656 */ shutdown(shutdown_type what)1657 void shutdown(shutdown_type what) 1658 { 1659 boost::system::error_code ec; 1660 impl_.get_service().shutdown(impl_.get_implementation(), what, ec); 1661 boost::asio::detail::throw_error(ec, "shutdown"); 1662 } 1663 1664 /// Disable sends or receives on the socket. 1665 /** 1666 * This function is used to disable send operations, receive operations, or 1667 * both. 1668 * 1669 * @param what Determines what types of operation will no longer be allowed. 1670 * 1671 * @param ec Set to indicate what error occurred, if any. 1672 * 1673 * @par Example 1674 * Shutting down the send side of the socket: 1675 * @code 1676 * boost::asio::ip::tcp::socket socket(my_context); 1677 * ... 1678 * boost::system::error_code ec; 1679 * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec); 1680 * if (ec) 1681 * { 1682 * // An error occurred. 1683 * } 1684 * @endcode 1685 */ shutdown(shutdown_type what,boost::system::error_code & ec)1686 BOOST_ASIO_SYNC_OP_VOID shutdown(shutdown_type what, 1687 boost::system::error_code& ec) 1688 { 1689 impl_.get_service().shutdown(impl_.get_implementation(), what, ec); 1690 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 1691 } 1692 1693 /// Wait for the socket to become ready to read, ready to write, or to have 1694 /// pending error conditions. 1695 /** 1696 * This function is used to perform a blocking wait for a socket to enter 1697 * a ready to read, write or error condition state. 1698 * 1699 * @param w Specifies the desired socket state. 1700 * 1701 * @par Example 1702 * Waiting for a socket to become readable. 1703 * @code 1704 * boost::asio::ip::tcp::socket socket(my_context); 1705 * ... 1706 * socket.wait(boost::asio::ip::tcp::socket::wait_read); 1707 * @endcode 1708 */ wait(wait_type w)1709 void wait(wait_type w) 1710 { 1711 boost::system::error_code ec; 1712 impl_.get_service().wait(impl_.get_implementation(), w, ec); 1713 boost::asio::detail::throw_error(ec, "wait"); 1714 } 1715 1716 /// Wait for the socket to become ready to read, ready to write, or to have 1717 /// pending error conditions. 1718 /** 1719 * This function is used to perform a blocking wait for a socket to enter 1720 * a ready to read, write or error condition state. 1721 * 1722 * @param w Specifies the desired socket state. 1723 * 1724 * @param ec Set to indicate what error occurred, if any. 1725 * 1726 * @par Example 1727 * Waiting for a socket to become readable. 1728 * @code 1729 * boost::asio::ip::tcp::socket socket(my_context); 1730 * ... 1731 * boost::system::error_code ec; 1732 * socket.wait(boost::asio::ip::tcp::socket::wait_read, ec); 1733 * @endcode 1734 */ wait(wait_type w,boost::system::error_code & ec)1735 BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec) 1736 { 1737 impl_.get_service().wait(impl_.get_implementation(), w, ec); 1738 BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); 1739 } 1740 1741 /// Asynchronously wait for the socket to become ready to read, ready to 1742 /// write, or to have pending error conditions. 1743 /** 1744 * This function is used to perform an asynchronous wait for a socket to enter 1745 * a ready to read, write or error condition state. 1746 * 1747 * @param w Specifies the desired socket state. 1748 * 1749 * @param handler The handler to be called when the wait operation completes. 1750 * Copies will be made of the handler as required. The function signature of 1751 * the handler must be: 1752 * @code void handler( 1753 * const boost::system::error_code& error // Result of operation 1754 * ); @endcode 1755 * Regardless of whether the asynchronous operation completes immediately or 1756 * not, the handler will not be invoked from within this function. On 1757 * immediate completion, invocation of the handler will be performed in a 1758 * manner equivalent to using boost::asio::post(). 1759 * 1760 * @par Example 1761 * @code 1762 * void wait_handler(const boost::system::error_code& error) 1763 * { 1764 * if (!error) 1765 * { 1766 * // Wait succeeded. 1767 * } 1768 * } 1769 * 1770 * ... 1771 * 1772 * boost::asio::ip::tcp::socket socket(my_context); 1773 * ... 1774 * socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler); 1775 * @endcode 1776 */ 1777 template < 1778 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code)) 1779 WaitHandler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WaitHandler,void (boost::system::error_code))1780 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WaitHandler, 1781 void (boost::system::error_code)) 1782 async_wait(wait_type w, 1783 BOOST_ASIO_MOVE_ARG(WaitHandler) handler 1784 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) 1785 { 1786 return async_initiate<WaitHandler, void (boost::system::error_code)>( 1787 initiate_async_wait(this), handler, w); 1788 } 1789 1790 protected: 1791 /// Protected destructor to prevent deletion through this type. 1792 /** 1793 * This function destroys the socket, cancelling any outstanding asynchronous 1794 * operations associated with the socket as if by calling @c cancel. 1795 */ ~basic_socket()1796 ~basic_socket() 1797 { 1798 } 1799 1800 #if defined(BOOST_ASIO_WINDOWS_RUNTIME) 1801 detail::io_object_impl< 1802 detail::null_socket_service<Protocol>, Executor> impl_; 1803 #elif defined(BOOST_ASIO_HAS_IOCP) 1804 detail::io_object_impl< 1805 detail::win_iocp_socket_service<Protocol>, Executor> impl_; 1806 #else 1807 detail::io_object_impl< 1808 detail::reactive_socket_service<Protocol>, Executor> impl_; 1809 #endif 1810 1811 private: 1812 // Disallow copying and assignment. 1813 basic_socket(const basic_socket&) BOOST_ASIO_DELETED; 1814 basic_socket& operator=(const basic_socket&) BOOST_ASIO_DELETED; 1815 1816 class initiate_async_connect 1817 { 1818 public: 1819 typedef Executor executor_type; 1820 initiate_async_connect(basic_socket * self)1821 explicit initiate_async_connect(basic_socket* self) 1822 : self_(self) 1823 { 1824 } 1825 get_executor() const1826 executor_type get_executor() const BOOST_ASIO_NOEXCEPT 1827 { 1828 return self_->get_executor(); 1829 } 1830 1831 template <typename ConnectHandler> operator ()(BOOST_ASIO_MOVE_ARG (ConnectHandler)handler,const endpoint_type & peer_endpoint,const boost::system::error_code & open_ec) const1832 void operator()(BOOST_ASIO_MOVE_ARG(ConnectHandler) handler, 1833 const endpoint_type& peer_endpoint, 1834 const boost::system::error_code& open_ec) const 1835 { 1836 // If you get an error on the following line it means that your handler 1837 // does not meet the documented type requirements for a ConnectHandler. 1838 BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check; 1839 1840 if (open_ec) 1841 { 1842 boost::asio::post(self_->impl_.get_executor(), 1843 boost::asio::detail::bind_handler( 1844 BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler), open_ec)); 1845 } 1846 else 1847 { 1848 detail::non_const_lvalue<ConnectHandler> handler2(handler); 1849 self_->impl_.get_service().async_connect( 1850 self_->impl_.get_implementation(), peer_endpoint, 1851 handler2.value, self_->impl_.get_executor()); 1852 } 1853 } 1854 1855 private: 1856 basic_socket* self_; 1857 }; 1858 1859 class initiate_async_wait 1860 { 1861 public: 1862 typedef Executor executor_type; 1863 initiate_async_wait(basic_socket * self)1864 explicit initiate_async_wait(basic_socket* self) 1865 : self_(self) 1866 { 1867 } 1868 get_executor() const1869 executor_type get_executor() const BOOST_ASIO_NOEXCEPT 1870 { 1871 return self_->get_executor(); 1872 } 1873 1874 template <typename WaitHandler> operator ()(BOOST_ASIO_MOVE_ARG (WaitHandler)handler,wait_type w) const1875 void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, wait_type w) const 1876 { 1877 // If you get an error on the following line it means that your handler 1878 // does not meet the documented type requirements for a WaitHandler. 1879 BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; 1880 1881 detail::non_const_lvalue<WaitHandler> handler2(handler); 1882 self_->impl_.get_service().async_wait( 1883 self_->impl_.get_implementation(), w, 1884 handler2.value, self_->impl_.get_executor()); 1885 } 1886 1887 private: 1888 basic_socket* self_; 1889 }; 1890 }; 1891 1892 } // namespace asio 1893 } // namespace boost 1894 1895 #include <boost/asio/detail/pop_options.hpp> 1896 1897 #endif // BOOST_ASIO_BASIC_SOCKET_HPP 1898