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