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