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