1 // 2 // basic_socket.hpp 3 // ~~~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2015 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 15 #include "asio/detail/config.hpp" 16 #include "asio/async_result.hpp" 17 #include "asio/basic_io_object.hpp" 18 #include "asio/detail/handler_type_requirements.hpp" 19 #include "asio/detail/throw_error.hpp" 20 #include "asio/detail/type_traits.hpp" 21 #include "asio/error.hpp" 22 #include "asio/socket_base.hpp" 23 24 #include "asio/detail/push_options.hpp" 25 26 namespace asio { 27 28 /// Provides socket functionality. 29 /** 30 * The basic_socket class template provides functionality that is common to both 31 * stream-oriented and datagram-oriented sockets. 32 * 33 * @par Thread Safety 34 * @e Distinct @e objects: Safe.@n 35 * @e Shared @e objects: Unsafe. 36 */ 37 template <typename Protocol, typename SocketService> 38 class basic_socket 39 : public basic_io_object<SocketService>, 40 public socket_base 41 { 42 public: 43 /// (Deprecated: Use native_handle_type.) The native representation of a 44 /// socket. 45 typedef typename SocketService::native_handle_type native_type; 46 47 /// The native representation of a socket. 48 typedef typename SocketService::native_handle_type native_handle_type; 49 50 /// The protocol type. 51 typedef Protocol protocol_type; 52 53 /// The endpoint type. 54 typedef typename Protocol::endpoint endpoint_type; 55 56 /// A basic_socket is always the lowest layer. 57 typedef basic_socket<Protocol, SocketService> lowest_layer_type; 58 59 /// Construct a basic_socket without opening it. 60 /** 61 * This constructor creates a socket without opening it. 62 * 63 * @param io_service The io_service object that the socket will use to 64 * dispatch handlers for any asynchronous operations performed on the socket. 65 */ basic_socket(asio::io_service & io_service)66 explicit basic_socket(asio::io_service& io_service) 67 : basic_io_object<SocketService>(io_service) 68 { 69 } 70 71 /// Construct and open a basic_socket. 72 /** 73 * This constructor creates and opens a socket. 74 * 75 * @param io_service The io_service object that the socket will use to 76 * dispatch handlers for any asynchronous operations performed on the socket. 77 * 78 * @param protocol An object specifying protocol parameters to be used. 79 * 80 * @throws asio::system_error Thrown on failure. 81 */ basic_socket(asio::io_service & io_service,const protocol_type & protocol)82 basic_socket(asio::io_service& io_service, 83 const protocol_type& protocol) 84 : basic_io_object<SocketService>(io_service) 85 { 86 asio::error_code ec; 87 this->get_service().open(this->get_implementation(), protocol, ec); 88 asio::detail::throw_error(ec, "open"); 89 } 90 91 /// Construct a basic_socket, opening it and binding it to the given local 92 /// endpoint. 93 /** 94 * This constructor creates a socket and automatically opens it bound to the 95 * specified endpoint on the local machine. The protocol used is the protocol 96 * associated with the given endpoint. 97 * 98 * @param io_service The io_service object that the socket will use to 99 * dispatch handlers for any asynchronous operations performed on the socket. 100 * 101 * @param endpoint An endpoint on the local machine to which the socket will 102 * be bound. 103 * 104 * @throws asio::system_error Thrown on failure. 105 */ basic_socket(asio::io_service & io_service,const endpoint_type & endpoint)106 basic_socket(asio::io_service& io_service, 107 const endpoint_type& endpoint) 108 : basic_io_object<SocketService>(io_service) 109 { 110 asio::error_code ec; 111 const protocol_type protocol = endpoint.protocol(); 112 this->get_service().open(this->get_implementation(), protocol, ec); 113 asio::detail::throw_error(ec, "open"); 114 this->get_service().bind(this->get_implementation(), endpoint, ec); 115 asio::detail::throw_error(ec, "bind"); 116 } 117 118 /// Construct a basic_socket on an existing native socket. 119 /** 120 * This constructor creates a socket object to hold an existing native socket. 121 * 122 * @param io_service The io_service object that the socket will use to 123 * dispatch handlers for any asynchronous operations performed on the socket. 124 * 125 * @param protocol An object specifying protocol parameters to be used. 126 * 127 * @param native_socket A native socket. 128 * 129 * @throws asio::system_error Thrown on failure. 130 */ basic_socket(asio::io_service & io_service,const protocol_type & protocol,const native_handle_type & native_socket)131 basic_socket(asio::io_service& io_service, 132 const protocol_type& protocol, const native_handle_type& native_socket) 133 : basic_io_object<SocketService>(io_service) 134 { 135 asio::error_code ec; 136 this->get_service().assign(this->get_implementation(), 137 protocol, native_socket, ec); 138 asio::detail::throw_error(ec, "assign"); 139 } 140 141 /// Move-construct a basic_socket from another. 142 /** 143 * This constructor moves a socket from one object to another. 144 * 145 * @param other The other basic_socket object from which the move will 146 * occur. 147 * 148 * @note Following the move, the moved-from object is in the same state as if 149 * constructed using the @c basic_socket(io_service&) constructor. 150 */ basic_socket(basic_socket && other)151 basic_socket(basic_socket&& other) 152 : basic_io_object<SocketService>( 153 ASIO_MOVE_CAST(basic_socket)(other)) 154 { 155 } 156 157 /// Move-assign a basic_socket from another. 158 /** 159 * This assignment operator moves a socket from one object to another. 160 * 161 * @param other The other basic_socket object from which the move will 162 * occur. 163 * 164 * @note Following the move, the moved-from object is in the same state as if 165 * constructed using the @c basic_socket(io_service&) constructor. 166 */ operator =(basic_socket && other)167 basic_socket& operator=(basic_socket&& other) 168 { 169 basic_io_object<SocketService>::operator=( 170 ASIO_MOVE_CAST(basic_socket)(other)); 171 return *this; 172 } 173 174 // All sockets have access to each other's implementations. 175 template <typename Protocol1, typename SocketService1> 176 friend class basic_socket; 177 178 /// Move-construct a basic_socket from a socket of another protocol type. 179 /** 180 * This constructor moves a socket from one object to another. 181 * 182 * @param other The other basic_socket object from which the move will 183 * occur. 184 * 185 * @note Following the move, the moved-from object is in the same state as if 186 * constructed using the @c basic_socket(io_service&) constructor. 187 */ 188 template <typename Protocol1, typename SocketService1> basic_socket(basic_socket<Protocol1,SocketService1> && other,typename enable_if<is_convertible<Protocol1,Protocol>::value>::type * =0)189 basic_socket(basic_socket<Protocol1, SocketService1>&& other, 190 typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0) 191 : basic_io_object<SocketService>(other.get_io_service()) 192 { 193 this->get_service().template converting_move_construct<Protocol1>( 194 this->get_implementation(), other.get_implementation()); 195 } 196 197 /// Move-assign a basic_socket from a socket of another protocol type. 198 /** 199 * This assignment operator moves a socket from one object to another. 200 * 201 * @param other The other basic_socket object from which the move will 202 * occur. 203 * 204 * @note Following the move, the moved-from object is in the same state as if 205 * constructed using the @c basic_socket(io_service&) constructor. 206 */ 207 template <typename Protocol1, typename SocketService1> 208 typename enable_if<is_convertible<Protocol1, Protocol>::value, operator =(basic_socket<Protocol1,SocketService1> && other)209 basic_socket>::type& operator=( 210 basic_socket<Protocol1, SocketService1>&& other) 211 { 212 basic_socket tmp(ASIO_MOVE_CAST2(basic_socket< 213 Protocol1, SocketService1>)(other)); 214 basic_io_object<SocketService>::operator=( 215 ASIO_MOVE_CAST(basic_socket)(tmp)); 216 return *this; 217 } 218 219 /// Get a reference to the lowest layer. 220 /** 221 * This function returns a reference to the lowest layer in a stack of 222 * layers. Since a basic_socket cannot contain any further layers, it simply 223 * returns a reference to itself. 224 * 225 * @return A reference to the lowest layer in the stack of layers. Ownership 226 * is not transferred to the caller. 227 */ lowest_layer()228 lowest_layer_type& lowest_layer() 229 { 230 return *this; 231 } 232 233 /// Get a const reference to the lowest layer. 234 /** 235 * This function returns a const reference to the lowest layer in a stack of 236 * layers. Since a basic_socket cannot contain any further layers, it simply 237 * returns a reference to itself. 238 * 239 * @return A const reference to the lowest layer in the stack of layers. 240 * Ownership is not transferred to the caller. 241 */ lowest_layer() const242 const lowest_layer_type& lowest_layer() const 243 { 244 return *this; 245 } 246 247 /// Open the socket using the specified protocol. 248 /** 249 * This function opens the socket so that it will use the specified protocol. 250 * 251 * @param protocol An object specifying protocol parameters to be used. 252 * 253 * @throws asio::system_error Thrown on failure. 254 * 255 * @par Example 256 * @code 257 * asio::ip::tcp::socket socket(io_service); 258 * socket.open(asio::ip::tcp::v4()); 259 * @endcode 260 */ open(const protocol_type & protocol=protocol_type ())261 void open(const protocol_type& protocol = protocol_type()) 262 { 263 asio::error_code ec; 264 this->get_service().open(this->get_implementation(), protocol, ec); 265 asio::detail::throw_error(ec, "open"); 266 } 267 268 /// Open the socket using the specified protocol. 269 /** 270 * This function opens the socket so that it will use the specified protocol. 271 * 272 * @param protocol An object specifying which protocol is to be used. 273 * 274 * @param ec Set to indicate what error occurred, if any. 275 * 276 * @par Example 277 * @code 278 * asio::ip::tcp::socket socket(io_service); 279 * asio::error_code ec; 280 * socket.open(asio::ip::tcp::v4(), ec); 281 * if (ec) 282 * { 283 * // An error occurred. 284 * } 285 * @endcode 286 */ open(const protocol_type & protocol,asio::error_code & ec)287 asio::error_code open(const protocol_type& protocol, 288 asio::error_code& ec) 289 { 290 return this->get_service().open(this->get_implementation(), protocol, ec); 291 } 292 293 /// Assign an existing native socket to the socket. 294 /* 295 * This function opens the socket to hold an existing native socket. 296 * 297 * @param protocol An object specifying which protocol is to be used. 298 * 299 * @param native_socket A native socket. 300 * 301 * @throws asio::system_error Thrown on failure. 302 */ assign(const protocol_type & protocol,const native_handle_type & native_socket)303 void assign(const protocol_type& protocol, 304 const native_handle_type& native_socket) 305 { 306 asio::error_code ec; 307 this->get_service().assign(this->get_implementation(), 308 protocol, native_socket, ec); 309 asio::detail::throw_error(ec, "assign"); 310 } 311 312 /// Assign an existing native socket to the socket. 313 /* 314 * This function opens the socket to hold an existing native socket. 315 * 316 * @param protocol An object specifying which protocol is to be used. 317 * 318 * @param native_socket A native socket. 319 * 320 * @param ec Set to indicate what error occurred, if any. 321 */ assign(const protocol_type & protocol,const native_handle_type & native_socket,asio::error_code & ec)322 asio::error_code assign(const protocol_type& protocol, 323 const native_handle_type& native_socket, asio::error_code& ec) 324 { 325 return this->get_service().assign(this->get_implementation(), 326 protocol, native_socket, ec); 327 } 328 329 /// Determine whether the socket is open. is_open() const330 bool is_open() const 331 { 332 return this->get_service().is_open(this->get_implementation()); 333 } 334 335 /// Close the socket. 336 /** 337 * This function is used to close the socket. Any asynchronous send, receive 338 * or connect operations will be cancelled immediately, and will complete 339 * with the asio::error::operation_aborted error. 340 * 341 * @throws asio::system_error Thrown on failure. Note that, even if 342 * the function indicates an error, the underlying descriptor is closed. 343 * 344 * @note For portable behaviour with respect to graceful closure of a 345 * connected socket, call shutdown() before closing the socket. 346 */ close()347 void close() 348 { 349 asio::error_code ec; 350 this->get_service().close(this->get_implementation(), ec); 351 asio::detail::throw_error(ec, "close"); 352 } 353 354 /// Close the socket. 355 /** 356 * This function is used to close the socket. Any asynchronous send, receive 357 * or connect operations will be cancelled immediately, and will complete 358 * with the asio::error::operation_aborted error. 359 * 360 * @param ec Set to indicate what error occurred, if any. Note that, even if 361 * the function indicates an error, the underlying descriptor is closed. 362 * 363 * @par Example 364 * @code 365 * asio::ip::tcp::socket socket(io_service); 366 * ... 367 * asio::error_code ec; 368 * socket.close(ec); 369 * if (ec) 370 * { 371 * // An error occurred. 372 * } 373 * @endcode 374 * 375 * @note For portable behaviour with respect to graceful closure of a 376 * connected socket, call shutdown() before closing the socket. 377 */ close(asio::error_code & ec)378 asio::error_code close(asio::error_code& ec) 379 { 380 return this->get_service().close(this->get_implementation(), ec); 381 } 382 383 /// (Deprecated: Use native_handle().) Get the native socket representation. 384 /** 385 * This function may be used to obtain the underlying representation of the 386 * socket. This is intended to allow access to native socket functionality 387 * that is not otherwise provided. 388 */ native()389 native_type native() 390 { 391 return this->get_service().native_handle(this->get_implementation()); 392 } 393 394 /// Get the native socket representation. 395 /** 396 * This function may be used to obtain the underlying representation of the 397 * socket. This is intended to allow access to native socket functionality 398 * that is not otherwise provided. 399 */ native_handle()400 native_handle_type native_handle() 401 { 402 return this->get_service().native_handle(this->get_implementation()); 403 } 404 405 /// Cancel all asynchronous operations associated with the socket. 406 /** 407 * This function causes all outstanding asynchronous connect, send and receive 408 * operations to finish immediately, and the handlers for cancelled operations 409 * will be passed the asio::error::operation_aborted error. 410 * 411 * @throws asio::system_error Thrown on failure. 412 * 413 * @note Calls to cancel() will always fail with 414 * asio::error::operation_not_supported when run on Windows XP, Windows 415 * Server 2003, and earlier versions of Windows, unless 416 * ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has 417 * two issues that should be considered before enabling its use: 418 * 419 * @li It will only cancel asynchronous operations that were initiated in the 420 * current thread. 421 * 422 * @li It can appear to complete without error, but the request to cancel the 423 * unfinished operations may be silently ignored by the operating system. 424 * Whether it works or not seems to depend on the drivers that are installed. 425 * 426 * For portable cancellation, consider using one of the following 427 * alternatives: 428 * 429 * @li Disable asio's I/O completion port backend by defining 430 * ASIO_DISABLE_IOCP. 431 * 432 * @li Use the close() function to simultaneously cancel the outstanding 433 * operations and close the socket. 434 * 435 * When running on Windows Vista, Windows Server 2008, and later, the 436 * CancelIoEx function is always used. This function does not have the 437 * problems described above. 438 */ cancel()439 void cancel() 440 { 441 asio::error_code ec; 442 this->get_service().cancel(this->get_implementation(), ec); 443 asio::detail::throw_error(ec, "cancel"); 444 } 445 446 /// Cancel all asynchronous operations associated with the socket. 447 /** 448 * This function causes all outstanding asynchronous connect, send and receive 449 * operations to finish immediately, and the handlers for cancelled operations 450 * will be passed the asio::error::operation_aborted error. 451 * 452 * @param ec Set to indicate what error occurred, if any. 453 * 454 * @note Calls to cancel() will always fail with 455 * asio::error::operation_not_supported when run on Windows XP, Windows 456 * Server 2003, and earlier versions of Windows, unless 457 * ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has 458 * two issues that should be considered before enabling its use: 459 * 460 * @li It will only cancel asynchronous operations that were initiated in the 461 * current thread. 462 * 463 * @li It can appear to complete without error, but the request to cancel the 464 * unfinished operations may be silently ignored by the operating system. 465 * Whether it works or not seems to depend on the drivers that are installed. 466 * 467 * For portable cancellation, consider using one of the following 468 * alternatives: 469 * 470 * @li Disable asio's I/O completion port backend by defining 471 * ASIO_DISABLE_IOCP. 472 * 473 * @li Use the close() function to simultaneously cancel the outstanding 474 * operations and close the socket. 475 * 476 * When running on Windows Vista, Windows Server 2008, and later, the 477 * CancelIoEx function is always used. This function does not have the 478 * problems described above. 479 */ cancel(asio::error_code & ec)480 asio::error_code cancel(asio::error_code& ec) 481 { 482 return this->get_service().cancel(this->get_implementation(), ec); 483 } 484 485 /// Determine whether the socket is at the out-of-band data mark. 486 /** 487 * This function is used to check whether the socket input is currently 488 * positioned at the out-of-band data mark. 489 * 490 * @return A bool indicating whether the socket is at the out-of-band data 491 * mark. 492 * 493 * @throws asio::system_error Thrown on failure. 494 */ at_mark() const495 bool at_mark() const 496 { 497 asio::error_code ec; 498 bool b = this->get_service().at_mark(this->get_implementation(), ec); 499 asio::detail::throw_error(ec, "at_mark"); 500 return b; 501 } 502 503 /// Determine whether the socket is at the out-of-band data mark. 504 /** 505 * This function is used to check whether the socket input is currently 506 * positioned at the out-of-band data mark. 507 * 508 * @param ec Set to indicate what error occurred, if any. 509 * 510 * @return A bool indicating whether the socket is at the out-of-band data 511 * mark. 512 */ at_mark(asio::error_code & ec) const513 bool at_mark(asio::error_code& ec) const 514 { 515 return this->get_service().at_mark(this->get_implementation(), ec); 516 } 517 518 /// Determine the number of bytes available for reading. 519 /** 520 * This function is used to determine the number of bytes that may be read 521 * without blocking. 522 * 523 * @return The number of bytes that may be read without blocking, or 0 if an 524 * error occurs. 525 * 526 * @throws asio::system_error Thrown on failure. 527 */ available() const528 std::size_t available() const 529 { 530 asio::error_code ec; 531 std::size_t s = this->get_service().available( 532 this->get_implementation(), ec); 533 asio::detail::throw_error(ec, "available"); 534 return s; 535 } 536 537 /// Determine the number of bytes available for reading. 538 /** 539 * This function is used to determine the number of bytes that may be read 540 * without blocking. 541 * 542 * @param ec Set to indicate what error occurred, if any. 543 * 544 * @return The number of bytes that may be read without blocking, or 0 if an 545 * error occurs. 546 */ available(asio::error_code & ec) const547 std::size_t available(asio::error_code& ec) const 548 { 549 return this->get_service().available(this->get_implementation(), ec); 550 } 551 552 /// Bind the socket to the given local endpoint. 553 /** 554 * This function binds the socket to the specified endpoint on the local 555 * machine. 556 * 557 * @param endpoint An endpoint on the local machine to which the socket will 558 * be bound. 559 * 560 * @throws asio::system_error Thrown on failure. 561 * 562 * @par Example 563 * @code 564 * asio::ip::tcp::socket socket(io_service); 565 * socket.open(asio::ip::tcp::v4()); 566 * socket.bind(asio::ip::tcp::endpoint( 567 * asio::ip::tcp::v4(), 12345)); 568 * @endcode 569 */ bind(const endpoint_type & endpoint)570 void bind(const endpoint_type& endpoint) 571 { 572 asio::error_code ec; 573 this->get_service().bind(this->get_implementation(), endpoint, ec); 574 asio::detail::throw_error(ec, "bind"); 575 } 576 577 /// Bind the socket to the given local endpoint. 578 /** 579 * This function binds the socket to the specified endpoint on the local 580 * machine. 581 * 582 * @param endpoint An endpoint on the local machine to which the socket will 583 * be bound. 584 * 585 * @param ec Set to indicate what error occurred, if any. 586 * 587 * @par Example 588 * @code 589 * asio::ip::tcp::socket socket(io_service); 590 * socket.open(asio::ip::tcp::v4()); 591 * asio::error_code ec; 592 * socket.bind(asio::ip::tcp::endpoint( 593 * asio::ip::tcp::v4(), 12345), ec); 594 * if (ec) 595 * { 596 * // An error occurred. 597 * } 598 * @endcode 599 */ bind(const endpoint_type & endpoint,asio::error_code & ec)600 asio::error_code bind(const endpoint_type& endpoint, 601 asio::error_code& ec) 602 { 603 return this->get_service().bind(this->get_implementation(), endpoint, ec); 604 } 605 606 /// Connect the socket to the specified endpoint. 607 /** 608 * This function is used to connect a socket to the specified remote endpoint. 609 * The function call will block until the connection is successfully made or 610 * an error occurs. 611 * 612 * The socket is automatically opened if it is not already open. If the 613 * connect fails, and the socket was automatically opened, the socket is 614 * not returned to the closed state. 615 * 616 * @param peer_endpoint The remote endpoint to which the socket will be 617 * connected. 618 * 619 * @throws asio::system_error Thrown on failure. 620 * 621 * @par Example 622 * @code 623 * asio::ip::tcp::socket socket(io_service); 624 * asio::ip::tcp::endpoint endpoint( 625 * asio::ip::address::from_string("1.2.3.4"), 12345); 626 * socket.connect(endpoint); 627 * @endcode 628 */ connect(const endpoint_type & peer_endpoint)629 void connect(const endpoint_type& peer_endpoint) 630 { 631 asio::error_code ec; 632 if (!is_open()) 633 { 634 this->get_service().open(this->get_implementation(), 635 peer_endpoint.protocol(), ec); 636 asio::detail::throw_error(ec, "connect"); 637 } 638 this->get_service().connect(this->get_implementation(), peer_endpoint, ec); 639 asio::detail::throw_error(ec, "connect"); 640 } 641 642 /// Connect the socket to the specified endpoint. 643 /** 644 * This function is used to connect a socket to the specified remote endpoint. 645 * The function call will block until the connection is successfully made or 646 * an error occurs. 647 * 648 * The socket is automatically opened if it is not already open. If the 649 * connect fails, and the socket was automatically opened, the socket is 650 * not returned to the closed state. 651 * 652 * @param peer_endpoint The remote endpoint to which the socket will be 653 * connected. 654 * 655 * @param ec Set to indicate what error occurred, if any. 656 * 657 * @par Example 658 * @code 659 * asio::ip::tcp::socket socket(io_service); 660 * asio::ip::tcp::endpoint endpoint( 661 * asio::ip::address::from_string("1.2.3.4"), 12345); 662 * asio::error_code ec; 663 * socket.connect(endpoint, ec); 664 * if (ec) 665 * { 666 * // An error occurred. 667 * } 668 * @endcode 669 */ connect(const endpoint_type & peer_endpoint,asio::error_code & ec)670 asio::error_code connect(const endpoint_type& peer_endpoint, 671 asio::error_code& ec) 672 { 673 if (!is_open()) 674 { 675 if (this->get_service().open(this->get_implementation(), 676 peer_endpoint.protocol(), ec)) 677 { 678 return ec; 679 } 680 } 681 682 return this->get_service().connect( 683 this->get_implementation(), peer_endpoint, ec); 684 } 685 686 /// Start an asynchronous connect. 687 /** 688 * This function is used to asynchronously connect a socket to the specified 689 * remote endpoint. The function call always returns immediately. 690 * 691 * The socket is automatically opened if it is not already open. If the 692 * connect fails, and the socket was automatically opened, the socket is 693 * not returned to the closed state. 694 * 695 * @param peer_endpoint The remote endpoint to which the socket will be 696 * connected. Copies will be made of the endpoint object as required. 697 * 698 * @param handler The handler to be called when the connection operation 699 * completes. Copies will be made of the handler as required. The function 700 * signature of the handler must be: 701 * @code void handler( 702 * const asio::error_code& error // Result of operation 703 * ); @endcode 704 * Regardless of whether the asynchronous operation completes immediately or 705 * not, the handler will not be invoked from within this function. Invocation 706 * of the handler will be performed in a manner equivalent to using 707 * asio::io_service::post(). 708 * 709 * @par Example 710 * @code 711 * void connect_handler(const asio::error_code& error) 712 * { 713 * if (!error) 714 * { 715 * // Connect succeeded. 716 * } 717 * } 718 * 719 * ... 720 * 721 * asio::ip::tcp::socket socket(io_service); 722 * asio::ip::tcp::endpoint endpoint( 723 * asio::ip::address::from_string("1.2.3.4"), 12345); 724 * socket.async_connect(endpoint, connect_handler); 725 * @endcode 726 */ 727 template <typename ConnectHandler> ASIO_INITFN_RESULT_TYPE(ConnectHandler,void (asio::error_code))728 ASIO_INITFN_RESULT_TYPE(ConnectHandler, 729 void (asio::error_code)) 730 async_connect(const endpoint_type& peer_endpoint, 731 ASIO_MOVE_ARG(ConnectHandler) handler) 732 { 733 // If you get an error on the following line it means that your handler does 734 // not meet the documented type requirements for a ConnectHandler. 735 ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check; 736 737 if (!is_open()) 738 { 739 asio::error_code ec; 740 const protocol_type protocol = peer_endpoint.protocol(); 741 if (this->get_service().open(this->get_implementation(), protocol, ec)) 742 { 743 detail::async_result_init< 744 ConnectHandler, void (asio::error_code)> init( 745 ASIO_MOVE_CAST(ConnectHandler)(handler)); 746 747 this->get_io_service().post( 748 asio::detail::bind_handler( 749 ASIO_MOVE_CAST(ASIO_HANDLER_TYPE( 750 ConnectHandler, void (asio::error_code)))( 751 init.handler), ec)); 752 753 return init.result.get(); 754 } 755 } 756 757 return this->get_service().async_connect(this->get_implementation(), 758 peer_endpoint, ASIO_MOVE_CAST(ConnectHandler)(handler)); 759 } 760 761 /// Set an option on the socket. 762 /** 763 * This function is used to set an option on the socket. 764 * 765 * @param option The new option value to be set on the socket. 766 * 767 * @throws asio::system_error Thrown on failure. 768 * 769 * @sa SettableSocketOption @n 770 * asio::socket_base::broadcast @n 771 * asio::socket_base::do_not_route @n 772 * asio::socket_base::keep_alive @n 773 * asio::socket_base::linger @n 774 * asio::socket_base::receive_buffer_size @n 775 * asio::socket_base::receive_low_watermark @n 776 * asio::socket_base::reuse_address @n 777 * asio::socket_base::send_buffer_size @n 778 * asio::socket_base::send_low_watermark @n 779 * asio::ip::multicast::join_group @n 780 * asio::ip::multicast::leave_group @n 781 * asio::ip::multicast::enable_loopback @n 782 * asio::ip::multicast::outbound_interface @n 783 * asio::ip::multicast::hops @n 784 * asio::ip::tcp::no_delay 785 * 786 * @par Example 787 * Setting the IPPROTO_TCP/TCP_NODELAY option: 788 * @code 789 * asio::ip::tcp::socket socket(io_service); 790 * ... 791 * asio::ip::tcp::no_delay option(true); 792 * socket.set_option(option); 793 * @endcode 794 */ 795 template <typename SettableSocketOption> set_option(const SettableSocketOption & option)796 void set_option(const SettableSocketOption& option) 797 { 798 asio::error_code ec; 799 this->get_service().set_option(this->get_implementation(), option, ec); 800 asio::detail::throw_error(ec, "set_option"); 801 } 802 803 /// Set an option on the socket. 804 /** 805 * This function is used to set an option on the socket. 806 * 807 * @param option The new option value to be set on the socket. 808 * 809 * @param ec Set to indicate what error occurred, if any. 810 * 811 * @sa SettableSocketOption @n 812 * asio::socket_base::broadcast @n 813 * asio::socket_base::do_not_route @n 814 * asio::socket_base::keep_alive @n 815 * asio::socket_base::linger @n 816 * asio::socket_base::receive_buffer_size @n 817 * asio::socket_base::receive_low_watermark @n 818 * asio::socket_base::reuse_address @n 819 * asio::socket_base::send_buffer_size @n 820 * asio::socket_base::send_low_watermark @n 821 * asio::ip::multicast::join_group @n 822 * asio::ip::multicast::leave_group @n 823 * asio::ip::multicast::enable_loopback @n 824 * asio::ip::multicast::outbound_interface @n 825 * asio::ip::multicast::hops @n 826 * asio::ip::tcp::no_delay 827 * 828 * @par Example 829 * Setting the IPPROTO_TCP/TCP_NODELAY option: 830 * @code 831 * asio::ip::tcp::socket socket(io_service); 832 * ... 833 * asio::ip::tcp::no_delay option(true); 834 * asio::error_code ec; 835 * socket.set_option(option, ec); 836 * if (ec) 837 * { 838 * // An error occurred. 839 * } 840 * @endcode 841 */ 842 template <typename SettableSocketOption> set_option(const SettableSocketOption & option,asio::error_code & ec)843 asio::error_code set_option(const SettableSocketOption& option, 844 asio::error_code& ec) 845 { 846 return this->get_service().set_option( 847 this->get_implementation(), option, ec); 848 } 849 850 /// Get an option from the socket. 851 /** 852 * This function is used to get the current value of an option on the socket. 853 * 854 * @param option The option value to be obtained from the socket. 855 * 856 * @throws asio::system_error Thrown on failure. 857 * 858 * @sa GettableSocketOption @n 859 * asio::socket_base::broadcast @n 860 * asio::socket_base::do_not_route @n 861 * asio::socket_base::keep_alive @n 862 * asio::socket_base::linger @n 863 * asio::socket_base::receive_buffer_size @n 864 * asio::socket_base::receive_low_watermark @n 865 * asio::socket_base::reuse_address @n 866 * asio::socket_base::send_buffer_size @n 867 * asio::socket_base::send_low_watermark @n 868 * asio::ip::multicast::join_group @n 869 * asio::ip::multicast::leave_group @n 870 * asio::ip::multicast::enable_loopback @n 871 * asio::ip::multicast::outbound_interface @n 872 * asio::ip::multicast::hops @n 873 * asio::ip::tcp::no_delay 874 * 875 * @par Example 876 * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: 877 * @code 878 * asio::ip::tcp::socket socket(io_service); 879 * ... 880 * asio::ip::tcp::socket::keep_alive option; 881 * socket.get_option(option); 882 * bool is_set = option.value(); 883 * @endcode 884 */ 885 template <typename GettableSocketOption> get_option(GettableSocketOption & option) const886 void get_option(GettableSocketOption& option) const 887 { 888 asio::error_code ec; 889 this->get_service().get_option(this->get_implementation(), option, ec); 890 asio::detail::throw_error(ec, "get_option"); 891 } 892 893 /// Get an option from the socket. 894 /** 895 * This function is used to get the current value of an option on the socket. 896 * 897 * @param option The option value to be obtained from the socket. 898 * 899 * @param ec Set to indicate what error occurred, if any. 900 * 901 * @sa GettableSocketOption @n 902 * asio::socket_base::broadcast @n 903 * asio::socket_base::do_not_route @n 904 * asio::socket_base::keep_alive @n 905 * asio::socket_base::linger @n 906 * asio::socket_base::receive_buffer_size @n 907 * asio::socket_base::receive_low_watermark @n 908 * asio::socket_base::reuse_address @n 909 * asio::socket_base::send_buffer_size @n 910 * asio::socket_base::send_low_watermark @n 911 * asio::ip::multicast::join_group @n 912 * asio::ip::multicast::leave_group @n 913 * asio::ip::multicast::enable_loopback @n 914 * asio::ip::multicast::outbound_interface @n 915 * asio::ip::multicast::hops @n 916 * asio::ip::tcp::no_delay 917 * 918 * @par Example 919 * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: 920 * @code 921 * asio::ip::tcp::socket socket(io_service); 922 * ... 923 * asio::ip::tcp::socket::keep_alive option; 924 * asio::error_code ec; 925 * socket.get_option(option, ec); 926 * if (ec) 927 * { 928 * // An error occurred. 929 * } 930 * bool is_set = option.value(); 931 * @endcode 932 */ 933 template <typename GettableSocketOption> get_option(GettableSocketOption & option,asio::error_code & ec) const934 asio::error_code get_option(GettableSocketOption& option, 935 asio::error_code& ec) const 936 { 937 return this->get_service().get_option( 938 this->get_implementation(), option, ec); 939 } 940 941 /// Perform an IO control command on the socket. 942 /** 943 * This function is used to execute an IO control command on the socket. 944 * 945 * @param command The IO control command to be performed on the socket. 946 * 947 * @throws asio::system_error Thrown on failure. 948 * 949 * @sa IoControlCommand @n 950 * asio::socket_base::bytes_readable @n 951 * asio::socket_base::non_blocking_io 952 * 953 * @par Example 954 * Getting the number of bytes ready to read: 955 * @code 956 * asio::ip::tcp::socket socket(io_service); 957 * ... 958 * asio::ip::tcp::socket::bytes_readable command; 959 * socket.io_control(command); 960 * std::size_t bytes_readable = command.get(); 961 * @endcode 962 */ 963 template <typename IoControlCommand> io_control(IoControlCommand & command)964 void io_control(IoControlCommand& command) 965 { 966 asio::error_code ec; 967 this->get_service().io_control(this->get_implementation(), command, ec); 968 asio::detail::throw_error(ec, "io_control"); 969 } 970 971 /// Perform an IO control command on the socket. 972 /** 973 * This function is used to execute an IO control command on the socket. 974 * 975 * @param command The IO control command to be performed on the socket. 976 * 977 * @param ec Set to indicate what error occurred, if any. 978 * 979 * @sa IoControlCommand @n 980 * asio::socket_base::bytes_readable @n 981 * asio::socket_base::non_blocking_io 982 * 983 * @par Example 984 * Getting the number of bytes ready to read: 985 * @code 986 * asio::ip::tcp::socket socket(io_service); 987 * ... 988 * asio::ip::tcp::socket::bytes_readable command; 989 * asio::error_code ec; 990 * socket.io_control(command, ec); 991 * if (ec) 992 * { 993 * // An error occurred. 994 * } 995 * std::size_t bytes_readable = command.get(); 996 * @endcode 997 */ 998 template <typename IoControlCommand> io_control(IoControlCommand & command,asio::error_code & ec)999 asio::error_code io_control(IoControlCommand& command, 1000 asio::error_code& ec) 1001 { 1002 return this->get_service().io_control( 1003 this->get_implementation(), command, ec); 1004 } 1005 1006 /// Gets the non-blocking mode of the socket. 1007 /** 1008 * @returns @c true if the socket's synchronous operations will fail with 1009 * asio::error::would_block if they are unable to perform the requested 1010 * operation immediately. If @c false, synchronous operations will block 1011 * until complete. 1012 * 1013 * @note The non-blocking mode has no effect on the behaviour of asynchronous 1014 * operations. Asynchronous operations will never fail with the error 1015 * asio::error::would_block. 1016 */ non_blocking() const1017 bool non_blocking() const 1018 { 1019 return this->get_service().non_blocking(this->get_implementation()); 1020 } 1021 1022 /// Sets the non-blocking mode of the socket. 1023 /** 1024 * @param mode If @c true, the socket's synchronous operations will fail with 1025 * asio::error::would_block if they are unable to perform the requested 1026 * operation immediately. If @c false, synchronous operations will block 1027 * until complete. 1028 * 1029 * @throws asio::system_error Thrown on failure. 1030 * 1031 * @note The non-blocking mode has no effect on the behaviour of asynchronous 1032 * operations. Asynchronous operations will never fail with the error 1033 * asio::error::would_block. 1034 */ non_blocking(bool mode)1035 void non_blocking(bool mode) 1036 { 1037 asio::error_code ec; 1038 this->get_service().non_blocking(this->get_implementation(), mode, ec); 1039 asio::detail::throw_error(ec, "non_blocking"); 1040 } 1041 1042 /// Sets the non-blocking mode of the socket. 1043 /** 1044 * @param mode If @c true, the socket's synchronous operations will fail with 1045 * asio::error::would_block if they are unable to perform the requested 1046 * operation immediately. If @c false, synchronous operations will block 1047 * until complete. 1048 * 1049 * @param ec Set to indicate what error occurred, if any. 1050 * 1051 * @note The non-blocking mode has no effect on the behaviour of asynchronous 1052 * operations. Asynchronous operations will never fail with the error 1053 * asio::error::would_block. 1054 */ non_blocking(bool mode,asio::error_code & ec)1055 asio::error_code non_blocking( 1056 bool mode, asio::error_code& ec) 1057 { 1058 return this->get_service().non_blocking( 1059 this->get_implementation(), mode, ec); 1060 } 1061 1062 /// Gets the non-blocking mode of the native socket implementation. 1063 /** 1064 * This function is used to retrieve the non-blocking mode of the underlying 1065 * native socket. This mode has no effect on the behaviour of the socket 1066 * object's synchronous operations. 1067 * 1068 * @returns @c true if the underlying socket is in non-blocking mode and 1069 * direct system calls may fail with asio::error::would_block (or the 1070 * equivalent system error). 1071 * 1072 * @note The current non-blocking mode is cached by the socket object. 1073 * Consequently, the return value may be incorrect if the non-blocking mode 1074 * was set directly on the native socket. 1075 * 1076 * @par Example 1077 * This function is intended to allow the encapsulation of arbitrary 1078 * non-blocking system calls as asynchronous operations, in a way that is 1079 * transparent to the user of the socket object. The following example 1080 * illustrates how Linux's @c sendfile system call might be encapsulated: 1081 * @code template <typename Handler> 1082 * struct sendfile_op 1083 * { 1084 * tcp::socket& sock_; 1085 * int fd_; 1086 * Handler handler_; 1087 * off_t offset_; 1088 * std::size_t total_bytes_transferred_; 1089 * 1090 * // Function call operator meeting WriteHandler requirements. 1091 * // Used as the handler for the async_write_some operation. 1092 * void operator()(asio::error_code ec, std::size_t) 1093 * { 1094 * // Put the underlying socket into non-blocking mode. 1095 * if (!ec) 1096 * if (!sock_.native_non_blocking()) 1097 * sock_.native_non_blocking(true, ec); 1098 * 1099 * if (!ec) 1100 * { 1101 * for (;;) 1102 * { 1103 * // Try the system call. 1104 * errno = 0; 1105 * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); 1106 * ec = asio::error_code(n < 0 ? errno : 0, 1107 * asio::error::get_system_category()); 1108 * total_bytes_transferred_ += ec ? 0 : n; 1109 * 1110 * // Retry operation immediately if interrupted by signal. 1111 * if (ec == asio::error::interrupted) 1112 * continue; 1113 * 1114 * // Check if we need to run the operation again. 1115 * if (ec == asio::error::would_block 1116 * || ec == asio::error::try_again) 1117 * { 1118 * // We have to wait for the socket to become ready again. 1119 * sock_.async_write_some(asio::null_buffers(), *this); 1120 * return; 1121 * } 1122 * 1123 * if (ec || n == 0) 1124 * { 1125 * // An error occurred, or we have reached the end of the file. 1126 * // Either way we must exit the loop so we can call the handler. 1127 * break; 1128 * } 1129 * 1130 * // Loop around to try calling sendfile again. 1131 * } 1132 * } 1133 * 1134 * // Pass result back to user's handler. 1135 * handler_(ec, total_bytes_transferred_); 1136 * } 1137 * }; 1138 * 1139 * template <typename Handler> 1140 * void async_sendfile(tcp::socket& sock, int fd, Handler h) 1141 * { 1142 * sendfile_op<Handler> op = { sock, fd, h, 0, 0 }; 1143 * sock.async_write_some(asio::null_buffers(), op); 1144 * } @endcode 1145 */ native_non_blocking() const1146 bool native_non_blocking() const 1147 { 1148 return this->get_service().native_non_blocking(this->get_implementation()); 1149 } 1150 1151 /// Sets the non-blocking mode of the native socket implementation. 1152 /** 1153 * This function is used to modify the non-blocking mode of the underlying 1154 * native socket. It has no effect on the behaviour of the socket object's 1155 * synchronous operations. 1156 * 1157 * @param mode If @c true, the underlying socket is put into non-blocking 1158 * mode and direct system calls may fail with asio::error::would_block 1159 * (or the equivalent system error). 1160 * 1161 * @throws asio::system_error Thrown on failure. If the @c mode is 1162 * @c false, but the current value of @c non_blocking() is @c true, this 1163 * function fails with asio::error::invalid_argument, as the 1164 * combination does not make sense. 1165 * 1166 * @par Example 1167 * This function is intended to allow the encapsulation of arbitrary 1168 * non-blocking system calls as asynchronous operations, in a way that is 1169 * transparent to the user of the socket object. The following example 1170 * illustrates how Linux's @c sendfile system call might be encapsulated: 1171 * @code template <typename Handler> 1172 * struct sendfile_op 1173 * { 1174 * tcp::socket& sock_; 1175 * int fd_; 1176 * Handler handler_; 1177 * off_t offset_; 1178 * std::size_t total_bytes_transferred_; 1179 * 1180 * // Function call operator meeting WriteHandler requirements. 1181 * // Used as the handler for the async_write_some operation. 1182 * void operator()(asio::error_code ec, std::size_t) 1183 * { 1184 * // Put the underlying socket into non-blocking mode. 1185 * if (!ec) 1186 * if (!sock_.native_non_blocking()) 1187 * sock_.native_non_blocking(true, ec); 1188 * 1189 * if (!ec) 1190 * { 1191 * for (;;) 1192 * { 1193 * // Try the system call. 1194 * errno = 0; 1195 * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); 1196 * ec = asio::error_code(n < 0 ? errno : 0, 1197 * asio::error::get_system_category()); 1198 * total_bytes_transferred_ += ec ? 0 : n; 1199 * 1200 * // Retry operation immediately if interrupted by signal. 1201 * if (ec == asio::error::interrupted) 1202 * continue; 1203 * 1204 * // Check if we need to run the operation again. 1205 * if (ec == asio::error::would_block 1206 * || ec == asio::error::try_again) 1207 * { 1208 * // We have to wait for the socket to become ready again. 1209 * sock_.async_write_some(asio::null_buffers(), *this); 1210 * return; 1211 * } 1212 * 1213 * if (ec || n == 0) 1214 * { 1215 * // An error occurred, or we have reached the end of the file. 1216 * // Either way we must exit the loop so we can call the handler. 1217 * break; 1218 * } 1219 * 1220 * // Loop around to try calling sendfile again. 1221 * } 1222 * } 1223 * 1224 * // Pass result back to user's handler. 1225 * handler_(ec, total_bytes_transferred_); 1226 * } 1227 * }; 1228 * 1229 * template <typename Handler> 1230 * void async_sendfile(tcp::socket& sock, int fd, Handler h) 1231 * { 1232 * sendfile_op<Handler> op = { sock, fd, h, 0, 0 }; 1233 * sock.async_write_some(asio::null_buffers(), op); 1234 * } @endcode 1235 */ native_non_blocking(bool mode)1236 void native_non_blocking(bool mode) 1237 { 1238 asio::error_code ec; 1239 this->get_service().native_non_blocking( 1240 this->get_implementation(), mode, ec); 1241 asio::detail::throw_error(ec, "native_non_blocking"); 1242 } 1243 1244 /// Sets the non-blocking mode of the native socket implementation. 1245 /** 1246 * This function is used to modify the non-blocking mode of the underlying 1247 * native socket. It has no effect on the behaviour of the socket object's 1248 * synchronous operations. 1249 * 1250 * @param mode If @c true, the underlying socket is put into non-blocking 1251 * mode and direct system calls may fail with asio::error::would_block 1252 * (or the equivalent system error). 1253 * 1254 * @param ec Set to indicate what error occurred, if any. If the @c mode is 1255 * @c false, but the current value of @c non_blocking() is @c true, this 1256 * function fails with asio::error::invalid_argument, as the 1257 * combination does not make sense. 1258 * 1259 * @par Example 1260 * This function is intended to allow the encapsulation of arbitrary 1261 * non-blocking system calls as asynchronous operations, in a way that is 1262 * transparent to the user of the socket object. The following example 1263 * illustrates how Linux's @c sendfile system call might be encapsulated: 1264 * @code template <typename Handler> 1265 * struct sendfile_op 1266 * { 1267 * tcp::socket& sock_; 1268 * int fd_; 1269 * Handler handler_; 1270 * off_t offset_; 1271 * std::size_t total_bytes_transferred_; 1272 * 1273 * // Function call operator meeting WriteHandler requirements. 1274 * // Used as the handler for the async_write_some operation. 1275 * void operator()(asio::error_code ec, std::size_t) 1276 * { 1277 * // Put the underlying socket into non-blocking mode. 1278 * if (!ec) 1279 * if (!sock_.native_non_blocking()) 1280 * sock_.native_non_blocking(true, ec); 1281 * 1282 * if (!ec) 1283 * { 1284 * for (;;) 1285 * { 1286 * // Try the system call. 1287 * errno = 0; 1288 * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); 1289 * ec = asio::error_code(n < 0 ? errno : 0, 1290 * asio::error::get_system_category()); 1291 * total_bytes_transferred_ += ec ? 0 : n; 1292 * 1293 * // Retry operation immediately if interrupted by signal. 1294 * if (ec == asio::error::interrupted) 1295 * continue; 1296 * 1297 * // Check if we need to run the operation again. 1298 * if (ec == asio::error::would_block 1299 * || ec == asio::error::try_again) 1300 * { 1301 * // We have to wait for the socket to become ready again. 1302 * sock_.async_write_some(asio::null_buffers(), *this); 1303 * return; 1304 * } 1305 * 1306 * if (ec || n == 0) 1307 * { 1308 * // An error occurred, or we have reached the end of the file. 1309 * // Either way we must exit the loop so we can call the handler. 1310 * break; 1311 * } 1312 * 1313 * // Loop around to try calling sendfile again. 1314 * } 1315 * } 1316 * 1317 * // Pass result back to user's handler. 1318 * handler_(ec, total_bytes_transferred_); 1319 * } 1320 * }; 1321 * 1322 * template <typename Handler> 1323 * void async_sendfile(tcp::socket& sock, int fd, Handler h) 1324 * { 1325 * sendfile_op<Handler> op = { sock, fd, h, 0, 0 }; 1326 * sock.async_write_some(asio::null_buffers(), op); 1327 * } @endcode 1328 */ native_non_blocking(bool mode,asio::error_code & ec)1329 asio::error_code native_non_blocking( 1330 bool mode, asio::error_code& ec) 1331 { 1332 return this->get_service().native_non_blocking( 1333 this->get_implementation(), mode, ec); 1334 } 1335 1336 /// Get the local endpoint of the socket. 1337 /** 1338 * This function is used to obtain the locally bound endpoint of the socket. 1339 * 1340 * @returns An object that represents the local endpoint of the socket. 1341 * 1342 * @throws asio::system_error Thrown on failure. 1343 * 1344 * @par Example 1345 * @code 1346 * asio::ip::tcp::socket socket(io_service); 1347 * ... 1348 * asio::ip::tcp::endpoint endpoint = socket.local_endpoint(); 1349 * @endcode 1350 */ local_endpoint() const1351 endpoint_type local_endpoint() const 1352 { 1353 asio::error_code ec; 1354 endpoint_type ep = this->get_service().local_endpoint( 1355 this->get_implementation(), ec); 1356 asio::detail::throw_error(ec, "local_endpoint"); 1357 return ep; 1358 } 1359 1360 /// Get the local endpoint of the socket. 1361 /** 1362 * This function is used to obtain the locally bound endpoint of the socket. 1363 * 1364 * @param ec Set to indicate what error occurred, if any. 1365 * 1366 * @returns An object that represents the local endpoint of the socket. 1367 * Returns a default-constructed endpoint object if an error occurred. 1368 * 1369 * @par Example 1370 * @code 1371 * asio::ip::tcp::socket socket(io_service); 1372 * ... 1373 * asio::error_code ec; 1374 * asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec); 1375 * if (ec) 1376 * { 1377 * // An error occurred. 1378 * } 1379 * @endcode 1380 */ local_endpoint(asio::error_code & ec) const1381 endpoint_type local_endpoint(asio::error_code& ec) const 1382 { 1383 return this->get_service().local_endpoint(this->get_implementation(), ec); 1384 } 1385 1386 /// Get the remote endpoint of the socket. 1387 /** 1388 * This function is used to obtain the remote endpoint of the socket. 1389 * 1390 * @returns An object that represents the remote endpoint of the socket. 1391 * 1392 * @throws asio::system_error Thrown on failure. 1393 * 1394 * @par Example 1395 * @code 1396 * asio::ip::tcp::socket socket(io_service); 1397 * ... 1398 * asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(); 1399 * @endcode 1400 */ remote_endpoint() const1401 endpoint_type remote_endpoint() const 1402 { 1403 asio::error_code ec; 1404 endpoint_type ep = this->get_service().remote_endpoint( 1405 this->get_implementation(), ec); 1406 asio::detail::throw_error(ec, "remote_endpoint"); 1407 return ep; 1408 } 1409 1410 /// Get the remote endpoint of the socket. 1411 /** 1412 * This function is used to obtain the remote endpoint of the socket. 1413 * 1414 * @param ec Set to indicate what error occurred, if any. 1415 * 1416 * @returns An object that represents the remote endpoint of the socket. 1417 * Returns a default-constructed endpoint object if an error occurred. 1418 * 1419 * @par Example 1420 * @code 1421 * asio::ip::tcp::socket socket(io_service); 1422 * ... 1423 * asio::error_code ec; 1424 * asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec); 1425 * if (ec) 1426 * { 1427 * // An error occurred. 1428 * } 1429 * @endcode 1430 */ remote_endpoint(asio::error_code & ec) const1431 endpoint_type remote_endpoint(asio::error_code& ec) const 1432 { 1433 return this->get_service().remote_endpoint(this->get_implementation(), ec); 1434 } 1435 1436 /// Disable sends or receives on the socket. 1437 /** 1438 * This function is used to disable send operations, receive operations, or 1439 * both. 1440 * 1441 * @param what Determines what types of operation will no longer be allowed. 1442 * 1443 * @throws asio::system_error Thrown on failure. 1444 * 1445 * @par Example 1446 * Shutting down the send side of the socket: 1447 * @code 1448 * asio::ip::tcp::socket socket(io_service); 1449 * ... 1450 * socket.shutdown(asio::ip::tcp::socket::shutdown_send); 1451 * @endcode 1452 */ shutdown(shutdown_type what)1453 void shutdown(shutdown_type what) 1454 { 1455 asio::error_code ec; 1456 this->get_service().shutdown(this->get_implementation(), what, ec); 1457 asio::detail::throw_error(ec, "shutdown"); 1458 } 1459 1460 /// Disable sends or receives on the socket. 1461 /** 1462 * This function is used to disable send operations, receive operations, or 1463 * both. 1464 * 1465 * @param what Determines what types of operation will no longer be allowed. 1466 * 1467 * @param ec Set to indicate what error occurred, if any. 1468 * 1469 * @par Example 1470 * Shutting down the send side of the socket: 1471 * @code 1472 * asio::ip::tcp::socket socket(io_service); 1473 * ... 1474 * asio::error_code ec; 1475 * socket.shutdown(asio::ip::tcp::socket::shutdown_send, ec); 1476 * if (ec) 1477 * { 1478 * // An error occurred. 1479 * } 1480 * @endcode 1481 */ shutdown(shutdown_type what,asio::error_code & ec)1482 asio::error_code shutdown(shutdown_type what, 1483 asio::error_code& ec) 1484 { 1485 return this->get_service().shutdown(this->get_implementation(), what, ec); 1486 } 1487 1488 protected: 1489 /// Protected destructor to prevent deletion through this type. ~basic_socket()1490 ~basic_socket() 1491 { 1492 } 1493 }; 1494 1495 } // namespace asio 1496 1497 #include "asio/detail/pop_options.hpp" 1498 1499 #endif // ASIO_BASIC_SOCKET_HPP 1500