1 // 2 // basic_socket_acceptor.hpp 3 // ~~~~~~~~~~~~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) 6 // 7 // Distributed under the Boost Software License, Version 1.0. (See accompanying 8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 // 10 11 #ifndef ASIO_BASIC_SOCKET_ACCEPTOR_HPP 12 #define ASIO_BASIC_SOCKET_ACCEPTOR_HPP 13 14 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 15 # pragma once 16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 17 18 #include "asio/detail/config.hpp" 19 #include "asio/basic_socket.hpp" 20 #include "asio/detail/handler_type_requirements.hpp" 21 #include "asio/detail/io_object_impl.hpp" 22 #include "asio/detail/non_const_lvalue.hpp" 23 #include "asio/detail/throw_error.hpp" 24 #include "asio/detail/type_traits.hpp" 25 #include "asio/error.hpp" 26 #include "asio/execution_context.hpp" 27 #include "asio/executor.hpp" 28 #include "asio/socket_base.hpp" 29 30 #if defined(ASIO_WINDOWS_RUNTIME) 31 # include "asio/detail/null_socket_service.hpp" 32 #elif defined(ASIO_HAS_IOCP) 33 # include "asio/detail/win_iocp_socket_service.hpp" 34 #else 35 # include "asio/detail/reactive_socket_service.hpp" 36 #endif 37 38 #if defined(ASIO_HAS_MOVE) 39 # include <utility> 40 #endif // defined(ASIO_HAS_MOVE) 41 42 #include "asio/detail/push_options.hpp" 43 44 namespace asio { 45 46 #if !defined(ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL) 47 #define ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL 48 49 // Forward declaration with defaulted arguments. 50 template <typename Protocol, typename Executor = executor> 51 class basic_socket_acceptor; 52 53 #endif // !defined(ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL) 54 55 /// Provides the ability to accept new connections. 56 /** 57 * The basic_socket_acceptor class template is used for accepting new socket 58 * connections. 59 * 60 * @par Thread Safety 61 * @e Distinct @e objects: Safe.@n 62 * @e Shared @e objects: Unsafe. 63 * 64 * @par Example 65 * Opening a socket acceptor with the SO_REUSEADDR option enabled: 66 * @code 67 * asio::ip::tcp::acceptor acceptor(my_context); 68 * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), port); 69 * acceptor.open(endpoint.protocol()); 70 * acceptor.set_option(asio::ip::tcp::acceptor::reuse_address(true)); 71 * acceptor.bind(endpoint); 72 * acceptor.listen(); 73 * @endcode 74 */ 75 template <typename Protocol, typename Executor> 76 class basic_socket_acceptor 77 : public socket_base 78 { 79 public: 80 /// The type of the executor associated with the object. 81 typedef Executor executor_type; 82 83 /// The native representation of an acceptor. 84 #if defined(GENERATING_DOCUMENTATION) 85 typedef implementation_defined native_handle_type; 86 #elif defined(ASIO_WINDOWS_RUNTIME) 87 typedef typename detail::null_socket_service< 88 Protocol>::native_handle_type native_handle_type; 89 #elif defined(ASIO_HAS_IOCP) 90 typedef typename detail::win_iocp_socket_service< 91 Protocol>::native_handle_type native_handle_type; 92 #else 93 typedef typename detail::reactive_socket_service< 94 Protocol>::native_handle_type native_handle_type; 95 #endif 96 97 /// The protocol type. 98 typedef Protocol protocol_type; 99 100 /// The endpoint type. 101 typedef typename Protocol::endpoint endpoint_type; 102 103 /// Construct an acceptor without opening it. 104 /** 105 * This constructor creates an acceptor without opening it to listen for new 106 * connections. The open() function must be called before the acceptor can 107 * accept new socket connections. 108 * 109 * @param ex The I/O executor that the acceptor will use, by default, to 110 * dispatch handlers for any asynchronous operations performed on the 111 * acceptor. 112 */ basic_socket_acceptor(const executor_type & ex)113 explicit basic_socket_acceptor(const executor_type& ex) 114 : impl_(ex) 115 { 116 } 117 118 /// Construct an acceptor without opening it. 119 /** 120 * This constructor creates an acceptor without opening it to listen for new 121 * connections. The open() function must be called before the acceptor can 122 * accept new socket connections. 123 * 124 * @param context An execution context which provides the I/O executor that 125 * the acceptor will use, by default, to dispatch handlers for any 126 * asynchronous operations performed on the acceptor. 127 */ 128 template <typename ExecutionContext> basic_socket_acceptor(ExecutionContext & context,typename enable_if<is_convertible<ExecutionContext &,execution_context &>::value>::type * =0)129 explicit basic_socket_acceptor(ExecutionContext& context, 130 typename enable_if< 131 is_convertible<ExecutionContext&, execution_context&>::value 132 >::type* = 0) 133 : impl_(context) 134 { 135 } 136 137 /// Construct an open acceptor. 138 /** 139 * This constructor creates an acceptor and automatically opens it. 140 * 141 * @param ex The I/O executor that the acceptor will use, by default, to 142 * dispatch handlers for any asynchronous operations performed on the 143 * acceptor. 144 * 145 * @param protocol An object specifying protocol parameters to be used. 146 * 147 * @throws asio::system_error Thrown on failure. 148 */ basic_socket_acceptor(const executor_type & ex,const protocol_type & protocol)149 basic_socket_acceptor(const executor_type& ex, const protocol_type& protocol) 150 : impl_(ex) 151 { 152 asio::error_code ec; 153 impl_.get_service().open(impl_.get_implementation(), protocol, ec); 154 asio::detail::throw_error(ec, "open"); 155 } 156 157 /// Construct an open acceptor. 158 /** 159 * This constructor creates an acceptor and automatically opens it. 160 * 161 * @param context An execution context which provides the I/O executor that 162 * the acceptor will use, by default, to dispatch handlers for any 163 * asynchronous operations performed on the acceptor. 164 * 165 * @param protocol An object specifying protocol parameters to be used. 166 * 167 * @throws asio::system_error Thrown on failure. 168 */ 169 template <typename ExecutionContext> basic_socket_acceptor(ExecutionContext & context,const protocol_type & protocol,typename enable_if<is_convertible<ExecutionContext &,execution_context &>::value>::type * =0)170 basic_socket_acceptor(ExecutionContext& context, 171 const protocol_type& protocol, 172 typename enable_if< 173 is_convertible<ExecutionContext&, execution_context&>::value 174 >::type* = 0) 175 : impl_(context) 176 { 177 asio::error_code ec; 178 impl_.get_service().open(impl_.get_implementation(), protocol, ec); 179 asio::detail::throw_error(ec, "open"); 180 } 181 182 /// Construct an acceptor opened on the given endpoint. 183 /** 184 * This constructor creates an acceptor and automatically opens it to listen 185 * for new connections on the specified endpoint. 186 * 187 * @param ex The I/O executor that the acceptor will use, by default, to 188 * dispatch handlers for any asynchronous operations performed on the 189 * acceptor. 190 * 191 * @param endpoint An endpoint on the local machine on which the acceptor 192 * will listen for new connections. 193 * 194 * @param reuse_addr Whether the constructor should set the socket option 195 * socket_base::reuse_address. 196 * 197 * @throws asio::system_error Thrown on failure. 198 * 199 * @note This constructor is equivalent to the following code: 200 * @code 201 * basic_socket_acceptor<Protocol> acceptor(my_context); 202 * acceptor.open(endpoint.protocol()); 203 * if (reuse_addr) 204 * acceptor.set_option(socket_base::reuse_address(true)); 205 * acceptor.bind(endpoint); 206 * acceptor.listen(); 207 * @endcode 208 */ basic_socket_acceptor(const executor_type & ex,const endpoint_type & endpoint,bool reuse_addr=true)209 basic_socket_acceptor(const executor_type& ex, 210 const endpoint_type& endpoint, bool reuse_addr = true) 211 : impl_(ex) 212 { 213 asio::error_code ec; 214 const protocol_type protocol = endpoint.protocol(); 215 impl_.get_service().open(impl_.get_implementation(), protocol, ec); 216 asio::detail::throw_error(ec, "open"); 217 if (reuse_addr) 218 { 219 impl_.get_service().set_option(impl_.get_implementation(), 220 socket_base::reuse_address(true), ec); 221 asio::detail::throw_error(ec, "set_option"); 222 } 223 impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); 224 asio::detail::throw_error(ec, "bind"); 225 impl_.get_service().listen(impl_.get_implementation(), 226 socket_base::max_listen_connections, ec); 227 asio::detail::throw_error(ec, "listen"); 228 } 229 230 /// Construct an acceptor opened on the given endpoint. 231 /** 232 * This constructor creates an acceptor and automatically opens it to listen 233 * for new connections on the specified endpoint. 234 * 235 * @param context An execution context which provides the I/O executor that 236 * the acceptor will use, by default, to dispatch handlers for any 237 * asynchronous operations performed on the acceptor. 238 * 239 * @param endpoint An endpoint on the local machine on which the acceptor 240 * will listen for new connections. 241 * 242 * @param reuse_addr Whether the constructor should set the socket option 243 * socket_base::reuse_address. 244 * 245 * @throws asio::system_error Thrown on failure. 246 * 247 * @note This constructor is equivalent to the following code: 248 * @code 249 * basic_socket_acceptor<Protocol> acceptor(my_context); 250 * acceptor.open(endpoint.protocol()); 251 * if (reuse_addr) 252 * acceptor.set_option(socket_base::reuse_address(true)); 253 * acceptor.bind(endpoint); 254 * acceptor.listen(); 255 * @endcode 256 */ 257 template <typename ExecutionContext> basic_socket_acceptor(ExecutionContext & context,const endpoint_type & endpoint,bool reuse_addr=true,typename enable_if<is_convertible<ExecutionContext &,execution_context &>::value>::type * =0)258 basic_socket_acceptor(ExecutionContext& context, 259 const endpoint_type& endpoint, bool reuse_addr = true, 260 typename enable_if< 261 is_convertible<ExecutionContext&, execution_context&>::value 262 >::type* = 0) 263 : impl_(context) 264 { 265 asio::error_code ec; 266 const protocol_type protocol = endpoint.protocol(); 267 impl_.get_service().open(impl_.get_implementation(), protocol, ec); 268 asio::detail::throw_error(ec, "open"); 269 if (reuse_addr) 270 { 271 impl_.get_service().set_option(impl_.get_implementation(), 272 socket_base::reuse_address(true), ec); 273 asio::detail::throw_error(ec, "set_option"); 274 } 275 impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); 276 asio::detail::throw_error(ec, "bind"); 277 impl_.get_service().listen(impl_.get_implementation(), 278 socket_base::max_listen_connections, ec); 279 asio::detail::throw_error(ec, "listen"); 280 } 281 282 /// Construct a basic_socket_acceptor on an existing native acceptor. 283 /** 284 * This constructor creates an acceptor object to hold an existing native 285 * acceptor. 286 * 287 * @param ex The I/O executor that the acceptor will use, by default, to 288 * dispatch handlers for any asynchronous operations performed on the 289 * acceptor. 290 * 291 * @param protocol An object specifying protocol parameters to be used. 292 * 293 * @param native_acceptor A native acceptor. 294 * 295 * @throws asio::system_error Thrown on failure. 296 */ basic_socket_acceptor(const executor_type & ex,const protocol_type & protocol,const native_handle_type & native_acceptor)297 basic_socket_acceptor(const executor_type& ex, 298 const protocol_type& protocol, const native_handle_type& native_acceptor) 299 : impl_(ex) 300 { 301 asio::error_code ec; 302 impl_.get_service().assign(impl_.get_implementation(), 303 protocol, native_acceptor, ec); 304 asio::detail::throw_error(ec, "assign"); 305 } 306 307 /// Construct a basic_socket_acceptor on an existing native acceptor. 308 /** 309 * This constructor creates an acceptor object to hold an existing native 310 * acceptor. 311 * 312 * @param context An execution context which provides the I/O executor that 313 * the acceptor will use, by default, to dispatch handlers for any 314 * asynchronous operations performed on the acceptor. 315 * 316 * @param protocol An object specifying protocol parameters to be used. 317 * 318 * @param native_acceptor A native acceptor. 319 * 320 * @throws asio::system_error Thrown on failure. 321 */ 322 template <typename ExecutionContext> basic_socket_acceptor(ExecutionContext & context,const protocol_type & protocol,const native_handle_type & native_acceptor,typename enable_if<is_convertible<ExecutionContext &,execution_context &>::value>::type * =0)323 basic_socket_acceptor(ExecutionContext& context, 324 const protocol_type& protocol, const native_handle_type& native_acceptor, 325 typename enable_if< 326 is_convertible<ExecutionContext&, execution_context&>::value 327 >::type* = 0) 328 : impl_(context) 329 { 330 asio::error_code ec; 331 impl_.get_service().assign(impl_.get_implementation(), 332 protocol, native_acceptor, ec); 333 asio::detail::throw_error(ec, "assign"); 334 } 335 336 #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) 337 /// Move-construct a basic_socket_acceptor from another. 338 /** 339 * This constructor moves an acceptor from one object to another. 340 * 341 * @param other The other basic_socket_acceptor object from which the move 342 * will occur. 343 * 344 * @note Following the move, the moved-from object is in the same state as if 345 * constructed using the @c basic_socket_acceptor(const executor_type&) 346 * constructor. 347 */ basic_socket_acceptor(basic_socket_acceptor && other)348 basic_socket_acceptor(basic_socket_acceptor&& other) 349 : impl_(std::move(other.impl_)) 350 { 351 } 352 353 /// Move-assign a basic_socket_acceptor from another. 354 /** 355 * This assignment operator moves an acceptor from one object to another. 356 * 357 * @param other The other basic_socket_acceptor object from which the move 358 * will occur. 359 * 360 * @note Following the move, the moved-from object is in the same state as if 361 * constructed using the @c basic_socket_acceptor(const executor_type&) 362 * constructor. 363 */ operator =(basic_socket_acceptor && other)364 basic_socket_acceptor& operator=(basic_socket_acceptor&& other) 365 { 366 impl_ = std::move(other.impl_); 367 return *this; 368 } 369 370 // All socket acceptors have access to each other's implementations. 371 template <typename Protocol1, typename Executor1> 372 friend class basic_socket_acceptor; 373 374 /// Move-construct a basic_socket_acceptor from an acceptor of another 375 /// protocol type. 376 /** 377 * This constructor moves an acceptor from one object to another. 378 * 379 * @param other The other basic_socket_acceptor object from which the move 380 * will occur. 381 * 382 * @note Following the move, the moved-from object is in the same state as if 383 * constructed using the @c basic_socket_acceptor(const executor_type&) 384 * constructor. 385 */ 386 template <typename Protocol1, typename Executor1> basic_socket_acceptor(basic_socket_acceptor<Protocol1,Executor1> && other,typename enable_if<is_convertible<Protocol1,Protocol>::value && is_convertible<Executor1,Executor>::value>::type * =0)387 basic_socket_acceptor(basic_socket_acceptor<Protocol1, Executor1>&& other, 388 typename enable_if< 389 is_convertible<Protocol1, Protocol>::value 390 && is_convertible<Executor1, Executor>::value 391 >::type* = 0) 392 : impl_(std::move(other.impl_)) 393 { 394 } 395 396 /// Move-assign a basic_socket_acceptor from an acceptor of another protocol 397 /// type. 398 /** 399 * This assignment operator moves an acceptor from one object to another. 400 * 401 * @param other The other basic_socket_acceptor object from which the move 402 * will occur. 403 * 404 * @note Following the move, the moved-from object is in the same state as if 405 * constructed using the @c basic_socket_acceptor(const executor_type&) 406 * constructor. 407 */ 408 template <typename Protocol1, typename Executor1> 409 typename enable_if< 410 is_convertible<Protocol1, Protocol>::value 411 && is_convertible<Executor1, Executor>::value, 412 basic_socket_acceptor& operator =(basic_socket_acceptor<Protocol1,Executor1> && other)413 >::type operator=(basic_socket_acceptor<Protocol1, Executor1>&& other) 414 { 415 basic_socket_acceptor tmp(std::move(other)); 416 impl_ = std::move(tmp.impl_); 417 return *this; 418 } 419 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) 420 421 /// Destroys the acceptor. 422 /** 423 * This function destroys the acceptor, cancelling any outstanding 424 * asynchronous operations associated with the acceptor as if by calling 425 * @c cancel. 426 */ ~basic_socket_acceptor()427 ~basic_socket_acceptor() 428 { 429 } 430 431 /// Get the executor associated with the object. get_executor()432 executor_type get_executor() ASIO_NOEXCEPT 433 { 434 return impl_.get_executor(); 435 } 436 437 /// Open the acceptor using the specified protocol. 438 /** 439 * This function opens the socket acceptor so that it will use the specified 440 * protocol. 441 * 442 * @param protocol An object specifying which protocol is to be used. 443 * 444 * @throws asio::system_error Thrown on failure. 445 * 446 * @par Example 447 * @code 448 * asio::ip::tcp::acceptor acceptor(my_context); 449 * acceptor.open(asio::ip::tcp::v4()); 450 * @endcode 451 */ open(const protocol_type & protocol=protocol_type ())452 void open(const protocol_type& protocol = protocol_type()) 453 { 454 asio::error_code ec; 455 impl_.get_service().open(impl_.get_implementation(), protocol, ec); 456 asio::detail::throw_error(ec, "open"); 457 } 458 459 /// Open the acceptor using the specified protocol. 460 /** 461 * This function opens the socket acceptor so that it will use the specified 462 * protocol. 463 * 464 * @param protocol An object specifying which protocol is to be used. 465 * 466 * @param ec Set to indicate what error occurred, if any. 467 * 468 * @par Example 469 * @code 470 * asio::ip::tcp::acceptor acceptor(my_context); 471 * asio::error_code ec; 472 * acceptor.open(asio::ip::tcp::v4(), ec); 473 * if (ec) 474 * { 475 * // An error occurred. 476 * } 477 * @endcode 478 */ open(const protocol_type & protocol,asio::error_code & ec)479 ASIO_SYNC_OP_VOID open(const protocol_type& protocol, 480 asio::error_code& ec) 481 { 482 impl_.get_service().open(impl_.get_implementation(), protocol, ec); 483 ASIO_SYNC_OP_VOID_RETURN(ec); 484 } 485 486 /// Assigns an existing native acceptor to the acceptor. 487 /* 488 * This function opens the acceptor to hold an existing native acceptor. 489 * 490 * @param protocol An object specifying which protocol is to be used. 491 * 492 * @param native_acceptor A native acceptor. 493 * 494 * @throws asio::system_error Thrown on failure. 495 */ assign(const protocol_type & protocol,const native_handle_type & native_acceptor)496 void assign(const protocol_type& protocol, 497 const native_handle_type& native_acceptor) 498 { 499 asio::error_code ec; 500 impl_.get_service().assign(impl_.get_implementation(), 501 protocol, native_acceptor, ec); 502 asio::detail::throw_error(ec, "assign"); 503 } 504 505 /// Assigns an existing native acceptor to the acceptor. 506 /* 507 * This function opens the acceptor to hold an existing native acceptor. 508 * 509 * @param protocol An object specifying which protocol is to be used. 510 * 511 * @param native_acceptor A native acceptor. 512 * 513 * @param ec Set to indicate what error occurred, if any. 514 */ assign(const protocol_type & protocol,const native_handle_type & native_acceptor,asio::error_code & ec)515 ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, 516 const native_handle_type& native_acceptor, asio::error_code& ec) 517 { 518 impl_.get_service().assign(impl_.get_implementation(), 519 protocol, native_acceptor, ec); 520 ASIO_SYNC_OP_VOID_RETURN(ec); 521 } 522 523 /// Determine whether the acceptor is open. is_open() const524 bool is_open() const 525 { 526 return impl_.get_service().is_open(impl_.get_implementation()); 527 } 528 529 /// Bind the acceptor to the given local endpoint. 530 /** 531 * This function binds the socket acceptor to the specified endpoint on the 532 * local machine. 533 * 534 * @param endpoint An endpoint on the local machine to which the socket 535 * acceptor will be bound. 536 * 537 * @throws asio::system_error Thrown on failure. 538 * 539 * @par Example 540 * @code 541 * asio::ip::tcp::acceptor acceptor(my_context); 542 * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), 12345); 543 * acceptor.open(endpoint.protocol()); 544 * acceptor.bind(endpoint); 545 * @endcode 546 */ bind(const endpoint_type & endpoint)547 void bind(const endpoint_type& endpoint) 548 { 549 asio::error_code ec; 550 impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); 551 asio::detail::throw_error(ec, "bind"); 552 } 553 554 /// Bind the acceptor to the given local endpoint. 555 /** 556 * This function binds the socket acceptor to the specified endpoint on the 557 * local machine. 558 * 559 * @param endpoint An endpoint on the local machine to which the socket 560 * acceptor will be bound. 561 * 562 * @param ec Set to indicate what error occurred, if any. 563 * 564 * @par Example 565 * @code 566 * asio::ip::tcp::acceptor acceptor(my_context); 567 * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), 12345); 568 * acceptor.open(endpoint.protocol()); 569 * asio::error_code ec; 570 * acceptor.bind(endpoint, ec); 571 * if (ec) 572 * { 573 * // An error occurred. 574 * } 575 * @endcode 576 */ bind(const endpoint_type & endpoint,asio::error_code & ec)577 ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, 578 asio::error_code& ec) 579 { 580 impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); 581 ASIO_SYNC_OP_VOID_RETURN(ec); 582 } 583 584 /// Place the acceptor into the state where it will listen for new 585 /// connections. 586 /** 587 * This function puts the socket acceptor into the state where it may accept 588 * new connections. 589 * 590 * @param backlog The maximum length of the queue of pending connections. 591 * 592 * @throws asio::system_error Thrown on failure. 593 */ listen(int backlog=socket_base::max_listen_connections)594 void listen(int backlog = socket_base::max_listen_connections) 595 { 596 asio::error_code ec; 597 impl_.get_service().listen(impl_.get_implementation(), backlog, ec); 598 asio::detail::throw_error(ec, "listen"); 599 } 600 601 /// Place the acceptor into the state where it will listen for new 602 /// connections. 603 /** 604 * This function puts the socket acceptor into the state where it may accept 605 * new connections. 606 * 607 * @param backlog The maximum length of the queue of pending connections. 608 * 609 * @param ec Set to indicate what error occurred, if any. 610 * 611 * @par Example 612 * @code 613 * asio::ip::tcp::acceptor acceptor(my_context); 614 * ... 615 * asio::error_code ec; 616 * acceptor.listen(asio::socket_base::max_listen_connections, ec); 617 * if (ec) 618 * { 619 * // An error occurred. 620 * } 621 * @endcode 622 */ listen(int backlog,asio::error_code & ec)623 ASIO_SYNC_OP_VOID listen(int backlog, asio::error_code& ec) 624 { 625 impl_.get_service().listen(impl_.get_implementation(), backlog, ec); 626 ASIO_SYNC_OP_VOID_RETURN(ec); 627 } 628 629 /// Close the acceptor. 630 /** 631 * This function is used to close the acceptor. Any asynchronous accept 632 * operations will be cancelled immediately. 633 * 634 * A subsequent call to open() is required before the acceptor can again be 635 * used to again perform socket accept operations. 636 * 637 * @throws asio::system_error Thrown on failure. 638 */ close()639 void close() 640 { 641 asio::error_code ec; 642 impl_.get_service().close(impl_.get_implementation(), ec); 643 asio::detail::throw_error(ec, "close"); 644 } 645 646 /// Close the acceptor. 647 /** 648 * This function is used to close the acceptor. Any asynchronous accept 649 * operations will be cancelled immediately. 650 * 651 * A subsequent call to open() is required before the acceptor can again be 652 * used to again perform socket accept operations. 653 * 654 * @param ec Set to indicate what error occurred, if any. 655 * 656 * @par Example 657 * @code 658 * asio::ip::tcp::acceptor acceptor(my_context); 659 * ... 660 * asio::error_code ec; 661 * acceptor.close(ec); 662 * if (ec) 663 * { 664 * // An error occurred. 665 * } 666 * @endcode 667 */ close(asio::error_code & ec)668 ASIO_SYNC_OP_VOID close(asio::error_code& ec) 669 { 670 impl_.get_service().close(impl_.get_implementation(), ec); 671 ASIO_SYNC_OP_VOID_RETURN(ec); 672 } 673 674 /// Release ownership of the underlying native acceptor. 675 /** 676 * This function causes all outstanding asynchronous accept operations to 677 * finish immediately, and the handlers for cancelled operations will be 678 * passed the asio::error::operation_aborted error. Ownership of the 679 * native acceptor is then transferred to the caller. 680 * 681 * @throws asio::system_error Thrown on failure. 682 * 683 * @note This function is unsupported on Windows versions prior to Windows 684 * 8.1, and will fail with asio::error::operation_not_supported on 685 * these platforms. 686 */ 687 #if defined(ASIO_MSVC) && (ASIO_MSVC >= 1400) \ 688 && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) 689 __declspec(deprecated("This function always fails with " 690 "operation_not_supported when used on Windows versions " 691 "prior to Windows 8.1.")) 692 #endif release()693 native_handle_type release() 694 { 695 asio::error_code ec; 696 native_handle_type s = impl_.get_service().release( 697 impl_.get_implementation(), ec); 698 asio::detail::throw_error(ec, "release"); 699 return s; 700 } 701 702 /// Release ownership of the underlying native acceptor. 703 /** 704 * This function causes all outstanding asynchronous accept operations to 705 * finish immediately, and the handlers for cancelled operations will be 706 * passed the asio::error::operation_aborted error. Ownership of the 707 * native acceptor is then transferred to the caller. 708 * 709 * @param ec Set to indicate what error occurred, if any. 710 * 711 * @note This function is unsupported on Windows versions prior to Windows 712 * 8.1, and will fail with asio::error::operation_not_supported on 713 * these platforms. 714 */ 715 #if defined(ASIO_MSVC) && (ASIO_MSVC >= 1400) \ 716 && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) 717 __declspec(deprecated("This function always fails with " 718 "operation_not_supported when used on Windows versions " 719 "prior to Windows 8.1.")) 720 #endif release(asio::error_code & ec)721 native_handle_type release(asio::error_code& ec) 722 { 723 return impl_.get_service().release(impl_.get_implementation(), ec); 724 } 725 726 /// Get the native acceptor representation. 727 /** 728 * This function may be used to obtain the underlying representation of the 729 * acceptor. This is intended to allow access to native acceptor functionality 730 * that is not otherwise provided. 731 */ native_handle()732 native_handle_type native_handle() 733 { 734 return impl_.get_service().native_handle(impl_.get_implementation()); 735 } 736 737 /// Cancel all asynchronous operations associated with the acceptor. 738 /** 739 * This function causes all outstanding asynchronous connect, send and receive 740 * operations to finish immediately, and the handlers for cancelled operations 741 * will be passed the asio::error::operation_aborted error. 742 * 743 * @throws asio::system_error Thrown on failure. 744 */ cancel()745 void cancel() 746 { 747 asio::error_code ec; 748 impl_.get_service().cancel(impl_.get_implementation(), ec); 749 asio::detail::throw_error(ec, "cancel"); 750 } 751 752 /// Cancel all asynchronous operations associated with the acceptor. 753 /** 754 * This function causes all outstanding asynchronous connect, send and receive 755 * operations to finish immediately, and the handlers for cancelled operations 756 * will be passed the asio::error::operation_aborted error. 757 * 758 * @param ec Set to indicate what error occurred, if any. 759 */ cancel(asio::error_code & ec)760 ASIO_SYNC_OP_VOID cancel(asio::error_code& ec) 761 { 762 impl_.get_service().cancel(impl_.get_implementation(), ec); 763 ASIO_SYNC_OP_VOID_RETURN(ec); 764 } 765 766 /// Set an option on the acceptor. 767 /** 768 * This function is used to set an option on the acceptor. 769 * 770 * @param option The new option value to be set on the acceptor. 771 * 772 * @throws asio::system_error Thrown on failure. 773 * 774 * @sa SettableSocketOption @n 775 * asio::socket_base::reuse_address 776 * asio::socket_base::enable_connection_aborted 777 * 778 * @par Example 779 * Setting the SOL_SOCKET/SO_REUSEADDR option: 780 * @code 781 * asio::ip::tcp::acceptor acceptor(my_context); 782 * ... 783 * asio::ip::tcp::acceptor::reuse_address option(true); 784 * acceptor.set_option(option); 785 * @endcode 786 */ 787 template <typename SettableSocketOption> set_option(const SettableSocketOption & option)788 void set_option(const SettableSocketOption& option) 789 { 790 asio::error_code ec; 791 impl_.get_service().set_option(impl_.get_implementation(), option, ec); 792 asio::detail::throw_error(ec, "set_option"); 793 } 794 795 /// Set an option on the acceptor. 796 /** 797 * This function is used to set an option on the acceptor. 798 * 799 * @param option The new option value to be set on the acceptor. 800 * 801 * @param ec Set to indicate what error occurred, if any. 802 * 803 * @sa SettableSocketOption @n 804 * asio::socket_base::reuse_address 805 * asio::socket_base::enable_connection_aborted 806 * 807 * @par Example 808 * Setting the SOL_SOCKET/SO_REUSEADDR option: 809 * @code 810 * asio::ip::tcp::acceptor acceptor(my_context); 811 * ... 812 * asio::ip::tcp::acceptor::reuse_address option(true); 813 * asio::error_code ec; 814 * acceptor.set_option(option, ec); 815 * if (ec) 816 * { 817 * // An error occurred. 818 * } 819 * @endcode 820 */ 821 template <typename SettableSocketOption> set_option(const SettableSocketOption & option,asio::error_code & ec)822 ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, 823 asio::error_code& ec) 824 { 825 impl_.get_service().set_option(impl_.get_implementation(), option, ec); 826 ASIO_SYNC_OP_VOID_RETURN(ec); 827 } 828 829 /// Get an option from the acceptor. 830 /** 831 * This function is used to get the current value of an option on the 832 * acceptor. 833 * 834 * @param option The option value to be obtained from the acceptor. 835 * 836 * @throws asio::system_error Thrown on failure. 837 * 838 * @sa GettableSocketOption @n 839 * asio::socket_base::reuse_address 840 * 841 * @par Example 842 * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: 843 * @code 844 * asio::ip::tcp::acceptor acceptor(my_context); 845 * ... 846 * asio::ip::tcp::acceptor::reuse_address option; 847 * acceptor.get_option(option); 848 * bool is_set = option.get(); 849 * @endcode 850 */ 851 template <typename GettableSocketOption> get_option(GettableSocketOption & option) const852 void get_option(GettableSocketOption& option) const 853 { 854 asio::error_code ec; 855 impl_.get_service().get_option(impl_.get_implementation(), option, ec); 856 asio::detail::throw_error(ec, "get_option"); 857 } 858 859 /// Get an option from the acceptor. 860 /** 861 * This function is used to get the current value of an option on the 862 * acceptor. 863 * 864 * @param option The option value to be obtained from the acceptor. 865 * 866 * @param ec Set to indicate what error occurred, if any. 867 * 868 * @sa GettableSocketOption @n 869 * asio::socket_base::reuse_address 870 * 871 * @par Example 872 * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: 873 * @code 874 * asio::ip::tcp::acceptor acceptor(my_context); 875 * ... 876 * asio::ip::tcp::acceptor::reuse_address option; 877 * asio::error_code ec; 878 * acceptor.get_option(option, ec); 879 * if (ec) 880 * { 881 * // An error occurred. 882 * } 883 * bool is_set = option.get(); 884 * @endcode 885 */ 886 template <typename GettableSocketOption> get_option(GettableSocketOption & option,asio::error_code & ec) const887 ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, 888 asio::error_code& ec) const 889 { 890 impl_.get_service().get_option(impl_.get_implementation(), option, ec); 891 ASIO_SYNC_OP_VOID_RETURN(ec); 892 } 893 894 /// Perform an IO control command on the acceptor. 895 /** 896 * This function is used to execute an IO control command on the acceptor. 897 * 898 * @param command The IO control command to be performed on the acceptor. 899 * 900 * @throws asio::system_error Thrown on failure. 901 * 902 * @sa IoControlCommand @n 903 * asio::socket_base::non_blocking_io 904 * 905 * @par Example 906 * Getting the number of bytes ready to read: 907 * @code 908 * asio::ip::tcp::acceptor acceptor(my_context); 909 * ... 910 * asio::ip::tcp::acceptor::non_blocking_io command(true); 911 * socket.io_control(command); 912 * @endcode 913 */ 914 template <typename IoControlCommand> io_control(IoControlCommand & command)915 void io_control(IoControlCommand& command) 916 { 917 asio::error_code ec; 918 impl_.get_service().io_control(impl_.get_implementation(), command, ec); 919 asio::detail::throw_error(ec, "io_control"); 920 } 921 922 /// Perform an IO control command on the acceptor. 923 /** 924 * This function is used to execute an IO control command on the acceptor. 925 * 926 * @param command The IO control command to be performed on the acceptor. 927 * 928 * @param ec Set to indicate what error occurred, if any. 929 * 930 * @sa IoControlCommand @n 931 * asio::socket_base::non_blocking_io 932 * 933 * @par Example 934 * Getting the number of bytes ready to read: 935 * @code 936 * asio::ip::tcp::acceptor acceptor(my_context); 937 * ... 938 * asio::ip::tcp::acceptor::non_blocking_io command(true); 939 * asio::error_code ec; 940 * socket.io_control(command, ec); 941 * if (ec) 942 * { 943 * // An error occurred. 944 * } 945 * @endcode 946 */ 947 template <typename IoControlCommand> io_control(IoControlCommand & command,asio::error_code & ec)948 ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, 949 asio::error_code& ec) 950 { 951 impl_.get_service().io_control(impl_.get_implementation(), command, ec); 952 ASIO_SYNC_OP_VOID_RETURN(ec); 953 } 954 955 /// Gets the non-blocking mode of the acceptor. 956 /** 957 * @returns @c true if the acceptor's synchronous operations will fail with 958 * asio::error::would_block if they are unable to perform the requested 959 * operation immediately. If @c false, synchronous operations will block 960 * until complete. 961 * 962 * @note The non-blocking mode has no effect on the behaviour of asynchronous 963 * operations. Asynchronous operations will never fail with the error 964 * asio::error::would_block. 965 */ non_blocking() const966 bool non_blocking() const 967 { 968 return impl_.get_service().non_blocking(impl_.get_implementation()); 969 } 970 971 /// Sets the non-blocking mode of the acceptor. 972 /** 973 * @param mode If @c true, the acceptor's synchronous operations will fail 974 * with asio::error::would_block if they are unable to perform the 975 * requested operation immediately. If @c false, synchronous operations will 976 * block until complete. 977 * 978 * @throws asio::system_error Thrown on failure. 979 * 980 * @note The non-blocking mode has no effect on the behaviour of asynchronous 981 * operations. Asynchronous operations will never fail with the error 982 * asio::error::would_block. 983 */ non_blocking(bool mode)984 void non_blocking(bool mode) 985 { 986 asio::error_code ec; 987 impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); 988 asio::detail::throw_error(ec, "non_blocking"); 989 } 990 991 /// Sets the non-blocking mode of the acceptor. 992 /** 993 * @param mode If @c true, the acceptor's synchronous operations will fail 994 * with asio::error::would_block if they are unable to perform the 995 * requested operation immediately. If @c false, synchronous operations will 996 * block until complete. 997 * 998 * @param ec Set to indicate what error occurred, if any. 999 * 1000 * @note The non-blocking mode has no effect on the behaviour of asynchronous 1001 * operations. Asynchronous operations will never fail with the error 1002 * asio::error::would_block. 1003 */ non_blocking(bool mode,asio::error_code & ec)1004 ASIO_SYNC_OP_VOID non_blocking( 1005 bool mode, asio::error_code& ec) 1006 { 1007 impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); 1008 ASIO_SYNC_OP_VOID_RETURN(ec); 1009 } 1010 1011 /// Gets the non-blocking mode of the native acceptor implementation. 1012 /** 1013 * This function is used to retrieve the non-blocking mode of the underlying 1014 * native acceptor. This mode has no effect on the behaviour of the acceptor 1015 * object's synchronous operations. 1016 * 1017 * @returns @c true if the underlying acceptor is in non-blocking mode and 1018 * direct system calls may fail with asio::error::would_block (or the 1019 * equivalent system error). 1020 * 1021 * @note The current non-blocking mode is cached by the acceptor object. 1022 * Consequently, the return value may be incorrect if the non-blocking mode 1023 * was set directly on the native acceptor. 1024 */ native_non_blocking() const1025 bool native_non_blocking() const 1026 { 1027 return impl_.get_service().native_non_blocking(impl_.get_implementation()); 1028 } 1029 1030 /// Sets the non-blocking mode of the native acceptor implementation. 1031 /** 1032 * This function is used to modify the non-blocking mode of the underlying 1033 * native acceptor. It has no effect on the behaviour of the acceptor object's 1034 * synchronous operations. 1035 * 1036 * @param mode If @c true, the underlying acceptor is put into non-blocking 1037 * mode and direct system calls may fail with asio::error::would_block 1038 * (or the equivalent system error). 1039 * 1040 * @throws asio::system_error Thrown on failure. If the @c mode is 1041 * @c false, but the current value of @c non_blocking() is @c true, this 1042 * function fails with asio::error::invalid_argument, as the 1043 * combination does not make sense. 1044 */ native_non_blocking(bool mode)1045 void native_non_blocking(bool mode) 1046 { 1047 asio::error_code ec; 1048 impl_.get_service().native_non_blocking( 1049 impl_.get_implementation(), mode, ec); 1050 asio::detail::throw_error(ec, "native_non_blocking"); 1051 } 1052 1053 /// Sets the non-blocking mode of the native acceptor implementation. 1054 /** 1055 * This function is used to modify the non-blocking mode of the underlying 1056 * native acceptor. It has no effect on the behaviour of the acceptor object's 1057 * synchronous operations. 1058 * 1059 * @param mode If @c true, the underlying acceptor is put into non-blocking 1060 * mode and direct system calls may fail with asio::error::would_block 1061 * (or the equivalent system error). 1062 * 1063 * @param ec Set to indicate what error occurred, if any. If the @c mode is 1064 * @c false, but the current value of @c non_blocking() is @c true, this 1065 * function fails with asio::error::invalid_argument, as the 1066 * combination does not make sense. 1067 */ native_non_blocking(bool mode,asio::error_code & ec)1068 ASIO_SYNC_OP_VOID native_non_blocking( 1069 bool mode, asio::error_code& ec) 1070 { 1071 impl_.get_service().native_non_blocking( 1072 impl_.get_implementation(), mode, ec); 1073 ASIO_SYNC_OP_VOID_RETURN(ec); 1074 } 1075 1076 /// Get the local endpoint of the acceptor. 1077 /** 1078 * This function is used to obtain the locally bound endpoint of the acceptor. 1079 * 1080 * @returns An object that represents the local endpoint of the acceptor. 1081 * 1082 * @throws asio::system_error Thrown on failure. 1083 * 1084 * @par Example 1085 * @code 1086 * asio::ip::tcp::acceptor acceptor(my_context); 1087 * ... 1088 * asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(); 1089 * @endcode 1090 */ local_endpoint() const1091 endpoint_type local_endpoint() const 1092 { 1093 asio::error_code ec; 1094 endpoint_type ep = impl_.get_service().local_endpoint( 1095 impl_.get_implementation(), ec); 1096 asio::detail::throw_error(ec, "local_endpoint"); 1097 return ep; 1098 } 1099 1100 /// Get the local endpoint of the acceptor. 1101 /** 1102 * This function is used to obtain the locally bound endpoint of the acceptor. 1103 * 1104 * @param ec Set to indicate what error occurred, if any. 1105 * 1106 * @returns An object that represents the local endpoint of the acceptor. 1107 * Returns a default-constructed endpoint object if an error occurred and the 1108 * error handler did not throw an exception. 1109 * 1110 * @par Example 1111 * @code 1112 * asio::ip::tcp::acceptor acceptor(my_context); 1113 * ... 1114 * asio::error_code ec; 1115 * asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec); 1116 * if (ec) 1117 * { 1118 * // An error occurred. 1119 * } 1120 * @endcode 1121 */ local_endpoint(asio::error_code & ec) const1122 endpoint_type local_endpoint(asio::error_code& ec) const 1123 { 1124 return impl_.get_service().local_endpoint(impl_.get_implementation(), ec); 1125 } 1126 1127 /// Wait for the acceptor to become ready to read, ready to write, or to have 1128 /// pending error conditions. 1129 /** 1130 * This function is used to perform a blocking wait for an acceptor to enter 1131 * a ready to read, write or error condition state. 1132 * 1133 * @param w Specifies the desired acceptor state. 1134 * 1135 * @par Example 1136 * Waiting for an acceptor to become readable. 1137 * @code 1138 * asio::ip::tcp::acceptor acceptor(my_context); 1139 * ... 1140 * acceptor.wait(asio::ip::tcp::acceptor::wait_read); 1141 * @endcode 1142 */ wait(wait_type w)1143 void wait(wait_type w) 1144 { 1145 asio::error_code ec; 1146 impl_.get_service().wait(impl_.get_implementation(), w, ec); 1147 asio::detail::throw_error(ec, "wait"); 1148 } 1149 1150 /// Wait for the acceptor to become ready to read, ready to write, or to have 1151 /// pending error conditions. 1152 /** 1153 * This function is used to perform a blocking wait for an acceptor to enter 1154 * a ready to read, write or error condition state. 1155 * 1156 * @param w Specifies the desired acceptor state. 1157 * 1158 * @param ec Set to indicate what error occurred, if any. 1159 * 1160 * @par Example 1161 * Waiting for an acceptor to become readable. 1162 * @code 1163 * asio::ip::tcp::acceptor acceptor(my_context); 1164 * ... 1165 * asio::error_code ec; 1166 * acceptor.wait(asio::ip::tcp::acceptor::wait_read, ec); 1167 * @endcode 1168 */ wait(wait_type w,asio::error_code & ec)1169 ASIO_SYNC_OP_VOID wait(wait_type w, asio::error_code& ec) 1170 { 1171 impl_.get_service().wait(impl_.get_implementation(), w, ec); 1172 ASIO_SYNC_OP_VOID_RETURN(ec); 1173 } 1174 1175 /// Asynchronously wait for the acceptor to become ready to read, ready to 1176 /// write, or to have pending error conditions. 1177 /** 1178 * This function is used to perform an asynchronous wait for an acceptor to 1179 * enter a ready to read, write or error condition state. 1180 * 1181 * @param w Specifies the desired acceptor state. 1182 * 1183 * @param handler The handler to be called when the wait operation completes. 1184 * Copies will be made of the handler as required. The function signature of 1185 * the handler must be: 1186 * @code void handler( 1187 * const asio::error_code& error // Result of operation 1188 * ); @endcode 1189 * Regardless of whether the asynchronous operation completes immediately or 1190 * not, the handler will not be invoked from within this function. On 1191 * immediate completion, invocation of the handler will be performed in a 1192 * manner equivalent to using asio::post(). 1193 * 1194 * @par Example 1195 * @code 1196 * void wait_handler(const asio::error_code& error) 1197 * { 1198 * if (!error) 1199 * { 1200 * // Wait succeeded. 1201 * } 1202 * } 1203 * 1204 * ... 1205 * 1206 * asio::ip::tcp::acceptor acceptor(my_context); 1207 * ... 1208 * acceptor.async_wait( 1209 * asio::ip::tcp::acceptor::wait_read, 1210 * wait_handler); 1211 * @endcode 1212 */ 1213 template <typename WaitHandler> ASIO_INITFN_RESULT_TYPE(WaitHandler,void (asio::error_code))1214 ASIO_INITFN_RESULT_TYPE(WaitHandler, 1215 void (asio::error_code)) 1216 async_wait(wait_type w, ASIO_MOVE_ARG(WaitHandler) handler) 1217 { 1218 return async_initiate<WaitHandler, void (asio::error_code)>( 1219 initiate_async_wait(), handler, this, w); 1220 } 1221 1222 #if !defined(ASIO_NO_EXTENSIONS) 1223 /// Accept a new connection. 1224 /** 1225 * This function is used to accept a new connection from a peer into the 1226 * given socket. The function call will block until a new connection has been 1227 * accepted successfully or an error occurs. 1228 * 1229 * @param peer The socket into which the new connection will be accepted. 1230 * 1231 * @throws asio::system_error Thrown on failure. 1232 * 1233 * @par Example 1234 * @code 1235 * asio::ip::tcp::acceptor acceptor(my_context); 1236 * ... 1237 * asio::ip::tcp::socket socket(my_context); 1238 * acceptor.accept(socket); 1239 * @endcode 1240 */ 1241 template <typename Protocol1, typename Executor1> accept(basic_socket<Protocol1,Executor1> & peer,typename enable_if<is_convertible<Protocol,Protocol1>::value>::type * =0)1242 void accept(basic_socket<Protocol1, Executor1>& peer, 1243 typename enable_if< 1244 is_convertible<Protocol, Protocol1>::value 1245 >::type* = 0) 1246 { 1247 asio::error_code ec; 1248 impl_.get_service().accept(impl_.get_implementation(), 1249 peer, static_cast<endpoint_type*>(0), ec); 1250 asio::detail::throw_error(ec, "accept"); 1251 } 1252 1253 /// Accept a new connection. 1254 /** 1255 * This function is used to accept a new connection from a peer into the 1256 * given socket. The function call will block until a new connection has been 1257 * accepted successfully or an error occurs. 1258 * 1259 * @param peer The socket into which the new connection will be accepted. 1260 * 1261 * @param ec Set to indicate what error occurred, if any. 1262 * 1263 * @par Example 1264 * @code 1265 * asio::ip::tcp::acceptor acceptor(my_context); 1266 * ... 1267 * asio::ip::tcp::socket socket(my_context); 1268 * asio::error_code ec; 1269 * acceptor.accept(socket, ec); 1270 * if (ec) 1271 * { 1272 * // An error occurred. 1273 * } 1274 * @endcode 1275 */ 1276 template <typename Protocol1, typename Executor1> accept(basic_socket<Protocol1,Executor1> & peer,asio::error_code & ec,typename enable_if<is_convertible<Protocol,Protocol1>::value>::type * =0)1277 ASIO_SYNC_OP_VOID accept( 1278 basic_socket<Protocol1, Executor1>& peer, asio::error_code& ec, 1279 typename enable_if< 1280 is_convertible<Protocol, Protocol1>::value 1281 >::type* = 0) 1282 { 1283 impl_.get_service().accept(impl_.get_implementation(), 1284 peer, static_cast<endpoint_type*>(0), ec); 1285 ASIO_SYNC_OP_VOID_RETURN(ec); 1286 } 1287 1288 /// Start an asynchronous accept. 1289 /** 1290 * This function is used to asynchronously accept a new connection into a 1291 * socket. The function call always returns immediately. 1292 * 1293 * @param peer The socket into which the new connection will be accepted. 1294 * Ownership of the peer object is retained by the caller, which must 1295 * guarantee that it is valid until the handler is called. 1296 * 1297 * @param handler The handler to be called when the accept operation 1298 * completes. Copies will be made of the handler as required. The function 1299 * signature of the handler must be: 1300 * @code void handler( 1301 * const asio::error_code& error // Result of operation. 1302 * ); @endcode 1303 * Regardless of whether the asynchronous operation completes immediately or 1304 * not, the handler will not be invoked from within this function. On 1305 * immediate completion, invocation of the handler will be performed in a 1306 * manner equivalent to using asio::post(). 1307 * 1308 * @par Example 1309 * @code 1310 * void accept_handler(const asio::error_code& error) 1311 * { 1312 * if (!error) 1313 * { 1314 * // Accept succeeded. 1315 * } 1316 * } 1317 * 1318 * ... 1319 * 1320 * asio::ip::tcp::acceptor acceptor(my_context); 1321 * ... 1322 * asio::ip::tcp::socket socket(my_context); 1323 * acceptor.async_accept(socket, accept_handler); 1324 * @endcode 1325 */ 1326 template <typename Protocol1, typename Executor1, typename AcceptHandler> ASIO_INITFN_RESULT_TYPE(AcceptHandler,void (asio::error_code))1327 ASIO_INITFN_RESULT_TYPE(AcceptHandler, 1328 void (asio::error_code)) 1329 async_accept(basic_socket<Protocol1, Executor1>& peer, 1330 ASIO_MOVE_ARG(AcceptHandler) handler, 1331 typename enable_if< 1332 is_convertible<Protocol, Protocol1>::value 1333 >::type* = 0) 1334 { 1335 return async_initiate<AcceptHandler, void (asio::error_code)>( 1336 initiate_async_accept(), handler, this, 1337 &peer, static_cast<endpoint_type*>(0)); 1338 } 1339 1340 /// Accept a new connection and obtain the endpoint of the peer 1341 /** 1342 * This function is used to accept a new connection from a peer into the 1343 * given socket, and additionally provide the endpoint of the remote peer. 1344 * The function call will block until a new connection has been accepted 1345 * successfully or an error occurs. 1346 * 1347 * @param peer The socket into which the new connection will be accepted. 1348 * 1349 * @param peer_endpoint An endpoint object which will receive the endpoint of 1350 * the remote peer. 1351 * 1352 * @throws asio::system_error Thrown on failure. 1353 * 1354 * @par Example 1355 * @code 1356 * asio::ip::tcp::acceptor acceptor(my_context); 1357 * ... 1358 * asio::ip::tcp::socket socket(my_context); 1359 * asio::ip::tcp::endpoint endpoint; 1360 * acceptor.accept(socket, endpoint); 1361 * @endcode 1362 */ 1363 template <typename Executor1> accept(basic_socket<protocol_type,Executor1> & peer,endpoint_type & peer_endpoint)1364 void accept(basic_socket<protocol_type, Executor1>& peer, 1365 endpoint_type& peer_endpoint) 1366 { 1367 asio::error_code ec; 1368 impl_.get_service().accept(impl_.get_implementation(), 1369 peer, &peer_endpoint, ec); 1370 asio::detail::throw_error(ec, "accept"); 1371 } 1372 1373 /// Accept a new connection and obtain the endpoint of the peer 1374 /** 1375 * This function is used to accept a new connection from a peer into the 1376 * given socket, and additionally provide the endpoint of the remote peer. 1377 * The function call will block until a new connection has been accepted 1378 * successfully or an error occurs. 1379 * 1380 * @param peer The socket into which the new connection will be accepted. 1381 * 1382 * @param peer_endpoint An endpoint object which will receive the endpoint of 1383 * the remote peer. 1384 * 1385 * @param ec Set to indicate what error occurred, if any. 1386 * 1387 * @par Example 1388 * @code 1389 * asio::ip::tcp::acceptor acceptor(my_context); 1390 * ... 1391 * asio::ip::tcp::socket socket(my_context); 1392 * asio::ip::tcp::endpoint endpoint; 1393 * asio::error_code ec; 1394 * acceptor.accept(socket, endpoint, ec); 1395 * if (ec) 1396 * { 1397 * // An error occurred. 1398 * } 1399 * @endcode 1400 */ 1401 template <typename Executor1> accept(basic_socket<protocol_type,Executor1> & peer,endpoint_type & peer_endpoint,asio::error_code & ec)1402 ASIO_SYNC_OP_VOID accept(basic_socket<protocol_type, Executor1>& peer, 1403 endpoint_type& peer_endpoint, asio::error_code& ec) 1404 { 1405 impl_.get_service().accept( 1406 impl_.get_implementation(), peer, &peer_endpoint, ec); 1407 ASIO_SYNC_OP_VOID_RETURN(ec); 1408 } 1409 1410 /// Start an asynchronous accept. 1411 /** 1412 * This function is used to asynchronously accept a new connection into a 1413 * socket, and additionally obtain the endpoint of the remote peer. The 1414 * function call always returns immediately. 1415 * 1416 * @param peer The socket into which the new connection will be accepted. 1417 * Ownership of the peer object is retained by the caller, which must 1418 * guarantee that it is valid until the handler is called. 1419 * 1420 * @param peer_endpoint An endpoint object into which the endpoint of the 1421 * remote peer will be written. Ownership of the peer_endpoint object is 1422 * retained by the caller, which must guarantee that it is valid until the 1423 * handler is called. 1424 * 1425 * @param handler The handler to be called when the accept operation 1426 * completes. Copies will be made of the handler as required. The function 1427 * signature of the handler must be: 1428 * @code void handler( 1429 * const asio::error_code& error // Result of operation. 1430 * ); @endcode 1431 * Regardless of whether the asynchronous operation completes immediately or 1432 * not, the handler will not be invoked from within this function. On 1433 * immediate completion, invocation of the handler will be performed in a 1434 * manner equivalent to using asio::post(). 1435 */ 1436 template <typename Executor1, typename AcceptHandler> ASIO_INITFN_RESULT_TYPE(AcceptHandler,void (asio::error_code))1437 ASIO_INITFN_RESULT_TYPE(AcceptHandler, 1438 void (asio::error_code)) 1439 async_accept(basic_socket<protocol_type, Executor1>& peer, 1440 endpoint_type& peer_endpoint, ASIO_MOVE_ARG(AcceptHandler) handler) 1441 { 1442 return async_initiate<AcceptHandler, void (asio::error_code)>( 1443 initiate_async_accept(), handler, this, &peer, &peer_endpoint); 1444 } 1445 #endif // !defined(ASIO_NO_EXTENSIONS) 1446 1447 #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) 1448 /// Accept a new connection. 1449 /** 1450 * This function is used to accept a new connection from a peer. The function 1451 * call will block until a new connection has been accepted successfully or 1452 * an error occurs. 1453 * 1454 * This overload requires that the Protocol template parameter satisfy the 1455 * AcceptableProtocol type requirements. 1456 * 1457 * @returns A socket object representing the newly accepted connection. 1458 * 1459 * @throws asio::system_error Thrown on failure. 1460 * 1461 * @par Example 1462 * @code 1463 * asio::ip::tcp::acceptor acceptor(my_context); 1464 * ... 1465 * asio::ip::tcp::socket socket(acceptor.accept()); 1466 * @endcode 1467 */ accept()1468 typename Protocol::socket accept() 1469 { 1470 asio::error_code ec; 1471 typename Protocol::socket peer(impl_.get_executor()); 1472 impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); 1473 asio::detail::throw_error(ec, "accept"); 1474 return peer; 1475 } 1476 1477 /// Accept a new connection. 1478 /** 1479 * This function is used to accept a new connection from a peer. The function 1480 * call will block until a new connection has been accepted successfully or 1481 * an error occurs. 1482 * 1483 * This overload requires that the Protocol template parameter satisfy the 1484 * AcceptableProtocol type requirements. 1485 * 1486 * @param ec Set to indicate what error occurred, if any. 1487 * 1488 * @returns On success, a socket object representing the newly accepted 1489 * connection. On error, a socket object where is_open() is false. 1490 * 1491 * @par Example 1492 * @code 1493 * asio::ip::tcp::acceptor acceptor(my_context); 1494 * ... 1495 * asio::ip::tcp::socket socket(acceptor.accept(ec)); 1496 * if (ec) 1497 * { 1498 * // An error occurred. 1499 * } 1500 * @endcode 1501 */ accept(asio::error_code & ec)1502 typename Protocol::socket accept(asio::error_code& ec) 1503 { 1504 typename Protocol::socket peer(impl_.get_executor()); 1505 impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); 1506 return peer; 1507 } 1508 1509 /// Start an asynchronous accept. 1510 /** 1511 * This function is used to asynchronously accept a new connection. The 1512 * function call always returns immediately. 1513 * 1514 * This overload requires that the Protocol template parameter satisfy the 1515 * AcceptableProtocol type requirements. 1516 * 1517 * @param handler The handler to be called when the accept operation 1518 * completes. Copies will be made of the handler as required. The function 1519 * signature of the handler must be: 1520 * @code void handler( 1521 * const asio::error_code& error, // Result of operation. 1522 * typename Protocol::socket peer // On success, the newly accepted socket. 1523 * ); @endcode 1524 * Regardless of whether the asynchronous operation completes immediately or 1525 * not, the handler will not be invoked from within this function. On 1526 * immediate completion, invocation of the handler will be performed in a 1527 * manner equivalent to using asio::post(). 1528 * 1529 * @par Example 1530 * @code 1531 * void accept_handler(const asio::error_code& error, 1532 * asio::ip::tcp::socket peer) 1533 * { 1534 * if (!error) 1535 * { 1536 * // Accept succeeded. 1537 * } 1538 * } 1539 * 1540 * ... 1541 * 1542 * asio::ip::tcp::acceptor acceptor(my_context); 1543 * ... 1544 * acceptor.async_accept(accept_handler); 1545 * @endcode 1546 */ 1547 template <typename MoveAcceptHandler> ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,void (asio::error_code,typename Protocol::socket))1548 ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, 1549 void (asio::error_code, typename Protocol::socket)) 1550 async_accept(ASIO_MOVE_ARG(MoveAcceptHandler) handler) 1551 { 1552 return async_initiate<MoveAcceptHandler, 1553 void (asio::error_code, typename Protocol::socket)>( 1554 initiate_async_move_accept(), handler, this, 1555 impl_.get_executor(), static_cast<endpoint_type*>(0), 1556 static_cast<typename Protocol::socket*>(0)); 1557 } 1558 1559 /// Accept a new connection. 1560 /** 1561 * This function is used to accept a new connection from a peer. The function 1562 * call will block until a new connection has been accepted successfully or 1563 * an error occurs. 1564 * 1565 * This overload requires that the Protocol template parameter satisfy the 1566 * AcceptableProtocol type requirements. 1567 * 1568 * @param ex The I/O executor object to be used for the newly 1569 * accepted socket. 1570 * 1571 * @returns A socket object representing the newly accepted connection. 1572 * 1573 * @throws asio::system_error Thrown on failure. 1574 * 1575 * @par Example 1576 * @code 1577 * asio::ip::tcp::acceptor acceptor(my_context); 1578 * ... 1579 * asio::ip::tcp::socket socket(acceptor.accept()); 1580 * @endcode 1581 */ 1582 template <typename Executor1> 1583 typename Protocol::socket::template rebind_executor<Executor1>::other accept(const Executor1 & ex,typename enable_if<is_executor<Executor1>::value>::type * =0)1584 accept(const Executor1& ex, 1585 typename enable_if< 1586 is_executor<Executor1>::value 1587 >::type* = 0) 1588 { 1589 asio::error_code ec; 1590 typename Protocol::socket::template 1591 rebind_executor<Executor1>::other peer(ex); 1592 impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); 1593 asio::detail::throw_error(ec, "accept"); 1594 return peer; 1595 } 1596 1597 /// Accept a new connection. 1598 /** 1599 * This function is used to accept a new connection from a peer. The function 1600 * call will block until a new connection has been accepted successfully or 1601 * an error occurs. 1602 * 1603 * This overload requires that the Protocol template parameter satisfy the 1604 * AcceptableProtocol type requirements. 1605 * 1606 * @param context The I/O execution context object to be used for the newly 1607 * accepted socket. 1608 * 1609 * @returns A socket object representing the newly accepted connection. 1610 * 1611 * @throws asio::system_error Thrown on failure. 1612 * 1613 * @par Example 1614 * @code 1615 * asio::ip::tcp::acceptor acceptor(my_context); 1616 * ... 1617 * asio::ip::tcp::socket socket(acceptor.accept()); 1618 * @endcode 1619 */ 1620 template <typename ExecutionContext> 1621 typename Protocol::socket::template rebind_executor< 1622 typename ExecutionContext::executor_type>::other accept(ExecutionContext & context,typename enable_if<is_convertible<ExecutionContext &,execution_context &>::value>::type * =0)1623 accept(ExecutionContext& context, 1624 typename enable_if< 1625 is_convertible<ExecutionContext&, execution_context&>::value 1626 >::type* = 0) 1627 { 1628 asio::error_code ec; 1629 typename Protocol::socket::template rebind_executor< 1630 typename ExecutionContext::executor_type>::other peer(context); 1631 impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); 1632 asio::detail::throw_error(ec, "accept"); 1633 return peer; 1634 } 1635 1636 /// Accept a new connection. 1637 /** 1638 * This function is used to accept a new connection from a peer. The function 1639 * call will block until a new connection has been accepted successfully or 1640 * an error occurs. 1641 * 1642 * This overload requires that the Protocol template parameter satisfy the 1643 * AcceptableProtocol type requirements. 1644 * 1645 * @param ex The I/O executor object to be used for the newly accepted 1646 * socket. 1647 * 1648 * @param ec Set to indicate what error occurred, if any. 1649 * 1650 * @returns On success, a socket object representing the newly accepted 1651 * connection. On error, a socket object where is_open() is false. 1652 * 1653 * @par Example 1654 * @code 1655 * asio::ip::tcp::acceptor acceptor(my_context); 1656 * ... 1657 * asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec)); 1658 * if (ec) 1659 * { 1660 * // An error occurred. 1661 * } 1662 * @endcode 1663 */ 1664 template <typename Executor1> 1665 typename Protocol::socket::template rebind_executor<Executor1>::other accept(const Executor1 & ex,asio::error_code & ec,typename enable_if<is_executor<Executor1>::value>::type * =0)1666 accept(const Executor1& ex, asio::error_code& ec, 1667 typename enable_if< 1668 is_executor<Executor1>::value 1669 >::type* = 0) 1670 { 1671 typename Protocol::socket::template 1672 rebind_executor<Executor1>::other peer(ex); 1673 impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); 1674 return peer; 1675 } 1676 1677 /// Accept a new connection. 1678 /** 1679 * This function is used to accept a new connection from a peer. The function 1680 * call will block until a new connection has been accepted successfully or 1681 * an error occurs. 1682 * 1683 * This overload requires that the Protocol template parameter satisfy the 1684 * AcceptableProtocol type requirements. 1685 * 1686 * @param context The I/O execution context object to be used for the newly 1687 * accepted socket. 1688 * 1689 * @param ec Set to indicate what error occurred, if any. 1690 * 1691 * @returns On success, a socket object representing the newly accepted 1692 * connection. On error, a socket object where is_open() is false. 1693 * 1694 * @par Example 1695 * @code 1696 * asio::ip::tcp::acceptor acceptor(my_context); 1697 * ... 1698 * asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec)); 1699 * if (ec) 1700 * { 1701 * // An error occurred. 1702 * } 1703 * @endcode 1704 */ 1705 template <typename ExecutionContext> 1706 typename Protocol::socket::template rebind_executor< 1707 typename ExecutionContext::executor_type>::other accept(ExecutionContext & context,asio::error_code & ec,typename enable_if<is_convertible<ExecutionContext &,execution_context &>::value>::type * =0)1708 accept(ExecutionContext& context, asio::error_code& ec, 1709 typename enable_if< 1710 is_convertible<ExecutionContext&, execution_context&>::value 1711 >::type* = 0) 1712 { 1713 typename Protocol::socket::template rebind_executor< 1714 typename ExecutionContext::executor_type>::other peer(context); 1715 impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); 1716 return peer; 1717 } 1718 1719 /// Start an asynchronous accept. 1720 /** 1721 * This function is used to asynchronously accept a new connection. The 1722 * function call always returns immediately. 1723 * 1724 * This overload requires that the Protocol template parameter satisfy the 1725 * AcceptableProtocol type requirements. 1726 * 1727 * @param ex The I/O executor object to be used for the newly accepted 1728 * socket. 1729 * 1730 * @param handler The handler to be called when the accept operation 1731 * completes. Copies will be made of the handler as required. The function 1732 * signature of the handler must be: 1733 * @code void handler( 1734 * const asio::error_code& error, // Result of operation. 1735 * typename Protocol::socket::template rebind_executor< 1736 * Executor1>::other peer // On success, the newly accepted socket. 1737 * ); @endcode 1738 * Regardless of whether the asynchronous operation completes immediately or 1739 * not, the handler will not be invoked from within this function. On 1740 * immediate completion, invocation of the handler will be performed in a 1741 * manner equivalent to using asio::post(). 1742 * 1743 * @par Example 1744 * @code 1745 * void accept_handler(const asio::error_code& error, 1746 * asio::ip::tcp::socket peer) 1747 * { 1748 * if (!error) 1749 * { 1750 * // Accept succeeded. 1751 * } 1752 * } 1753 * 1754 * ... 1755 * 1756 * asio::ip::tcp::acceptor acceptor(my_context); 1757 * ... 1758 * acceptor.async_accept(my_context2, accept_handler); 1759 * @endcode 1760 */ 1761 template <typename Executor1, typename MoveAcceptHandler> ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,void (asio::error_code,typename Protocol::socket::template rebind_executor<Executor1>::other))1762 ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, 1763 void (asio::error_code, 1764 typename Protocol::socket::template rebind_executor< 1765 Executor1>::other)) 1766 async_accept(const Executor1& ex, 1767 ASIO_MOVE_ARG(MoveAcceptHandler) handler, 1768 typename enable_if< 1769 is_executor<Executor1>::value 1770 >::type* = 0) 1771 { 1772 typedef typename Protocol::socket::template rebind_executor< 1773 Executor1>::other other_socket_type; 1774 1775 return async_initiate<MoveAcceptHandler, 1776 void (asio::error_code, other_socket_type)>( 1777 initiate_async_move_accept(), handler, this, 1778 ex, static_cast<endpoint_type*>(0), 1779 static_cast<other_socket_type*>(0)); 1780 } 1781 1782 /// Start an asynchronous accept. 1783 /** 1784 * This function is used to asynchronously accept a new connection. The 1785 * function call always returns immediately. 1786 * 1787 * This overload requires that the Protocol template parameter satisfy the 1788 * AcceptableProtocol type requirements. 1789 * 1790 * @param context The I/O execution context object to be used for the newly 1791 * accepted socket. 1792 * 1793 * @param handler The handler to be called when the accept operation 1794 * completes. Copies will be made of the handler as required. The function 1795 * signature of the handler must be: 1796 * @code void handler( 1797 * const asio::error_code& error, // Result of operation. 1798 * typename Protocol::socket::template rebind_executor< 1799 * typename ExecutionContext::executor_type>::other peer 1800 * // On success, the newly accepted socket. 1801 * ); @endcode 1802 * Regardless of whether the asynchronous operation completes immediately or 1803 * not, the handler will not be invoked from within this function. On 1804 * immediate completion, invocation of the handler will be performed in a 1805 * manner equivalent to using asio::post(). 1806 * 1807 * @par Example 1808 * @code 1809 * void accept_handler(const asio::error_code& error, 1810 * asio::ip::tcp::socket peer) 1811 * { 1812 * if (!error) 1813 * { 1814 * // Accept succeeded. 1815 * } 1816 * } 1817 * 1818 * ... 1819 * 1820 * asio::ip::tcp::acceptor acceptor(my_context); 1821 * ... 1822 * acceptor.async_accept(my_context2, accept_handler); 1823 * @endcode 1824 */ 1825 template <typename ExecutionContext, typename MoveAcceptHandler> ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,void (asio::error_code,typename Protocol::socket::template rebind_executor<typename ExecutionContext::executor_type>::other))1826 ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, 1827 void (asio::error_code, 1828 typename Protocol::socket::template rebind_executor< 1829 typename ExecutionContext::executor_type>::other)) 1830 async_accept(ExecutionContext& context, 1831 ASIO_MOVE_ARG(MoveAcceptHandler) handler, 1832 typename enable_if< 1833 is_convertible<ExecutionContext&, execution_context&>::value 1834 >::type* = 0) 1835 { 1836 typedef typename Protocol::socket::template rebind_executor< 1837 typename ExecutionContext::executor_type>::other other_socket_type; 1838 1839 return async_initiate<MoveAcceptHandler, 1840 void (asio::error_code, other_socket_type)>( 1841 initiate_async_move_accept(), handler, this, 1842 context.get_executor(), static_cast<endpoint_type*>(0), 1843 static_cast<other_socket_type*>(0)); 1844 } 1845 1846 /// Accept a new connection. 1847 /** 1848 * This function is used to accept a new connection from a peer. The function 1849 * call will block until a new connection has been accepted successfully or 1850 * an error occurs. 1851 * 1852 * This overload requires that the Protocol template parameter satisfy the 1853 * AcceptableProtocol type requirements. 1854 * 1855 * @param peer_endpoint An endpoint object into which the endpoint of the 1856 * remote peer will be written. 1857 * 1858 * @returns A socket object representing the newly accepted connection. 1859 * 1860 * @throws asio::system_error Thrown on failure. 1861 * 1862 * @par Example 1863 * @code 1864 * asio::ip::tcp::acceptor acceptor(my_context); 1865 * ... 1866 * asio::ip::tcp::endpoint endpoint; 1867 * asio::ip::tcp::socket socket(acceptor.accept(endpoint)); 1868 * @endcode 1869 */ accept(endpoint_type & peer_endpoint)1870 typename Protocol::socket accept(endpoint_type& peer_endpoint) 1871 { 1872 asio::error_code ec; 1873 typename Protocol::socket peer(impl_.get_executor()); 1874 impl_.get_service().accept(impl_.get_implementation(), 1875 peer, &peer_endpoint, ec); 1876 asio::detail::throw_error(ec, "accept"); 1877 return peer; 1878 } 1879 1880 /// Accept a new connection. 1881 /** 1882 * This function is used to accept a new connection from a peer. The function 1883 * call will block until a new connection has been accepted successfully or 1884 * an error occurs. 1885 * 1886 * This overload requires that the Protocol template parameter satisfy the 1887 * AcceptableProtocol type requirements. 1888 * 1889 * @param peer_endpoint An endpoint object into which the endpoint of the 1890 * remote peer will be written. 1891 * 1892 * @param ec Set to indicate what error occurred, if any. 1893 * 1894 * @returns On success, a socket object representing the newly accepted 1895 * connection. On error, a socket object where is_open() is false. 1896 * 1897 * @par Example 1898 * @code 1899 * asio::ip::tcp::acceptor acceptor(my_context); 1900 * ... 1901 * asio::ip::tcp::endpoint endpoint; 1902 * asio::ip::tcp::socket socket(acceptor.accept(endpoint, ec)); 1903 * if (ec) 1904 * { 1905 * // An error occurred. 1906 * } 1907 * @endcode 1908 */ accept(endpoint_type & peer_endpoint,asio::error_code & ec)1909 typename Protocol::socket accept( 1910 endpoint_type& peer_endpoint, asio::error_code& ec) 1911 { 1912 typename Protocol::socket peer(impl_.get_executor()); 1913 impl_.get_service().accept(impl_.get_implementation(), 1914 peer, &peer_endpoint, ec); 1915 return peer; 1916 } 1917 1918 /// Start an asynchronous accept. 1919 /** 1920 * This function is used to asynchronously accept a new connection. The 1921 * function call always returns immediately. 1922 * 1923 * This overload requires that the Protocol template parameter satisfy the 1924 * AcceptableProtocol type requirements. 1925 * 1926 * @param peer_endpoint An endpoint object into which the endpoint of the 1927 * remote peer will be written. Ownership of the peer_endpoint object is 1928 * retained by the caller, which must guarantee that it is valid until the 1929 * handler is called. 1930 * 1931 * @param handler The handler to be called when the accept operation 1932 * completes. Copies will be made of the handler as required. The function 1933 * signature of the handler must be: 1934 * @code void handler( 1935 * const asio::error_code& error, // Result of operation. 1936 * typename Protocol::socket peer // On success, the newly accepted socket. 1937 * ); @endcode 1938 * Regardless of whether the asynchronous operation completes immediately or 1939 * not, the handler will not be invoked from within this function. On 1940 * immediate completion, invocation of the handler will be performed in a 1941 * manner equivalent to using asio::post(). 1942 * 1943 * @par Example 1944 * @code 1945 * void accept_handler(const asio::error_code& error, 1946 * asio::ip::tcp::socket peer) 1947 * { 1948 * if (!error) 1949 * { 1950 * // Accept succeeded. 1951 * } 1952 * } 1953 * 1954 * ... 1955 * 1956 * asio::ip::tcp::acceptor acceptor(my_context); 1957 * ... 1958 * asio::ip::tcp::endpoint endpoint; 1959 * acceptor.async_accept(endpoint, accept_handler); 1960 * @endcode 1961 */ 1962 template <typename MoveAcceptHandler> ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,void (asio::error_code,typename Protocol::socket))1963 ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, 1964 void (asio::error_code, typename Protocol::socket)) 1965 async_accept(endpoint_type& peer_endpoint, 1966 ASIO_MOVE_ARG(MoveAcceptHandler) handler) 1967 { 1968 return async_initiate<MoveAcceptHandler, 1969 void (asio::error_code, typename Protocol::socket)>( 1970 initiate_async_move_accept(), handler, this, 1971 impl_.get_executor(), &peer_endpoint, 1972 static_cast<typename Protocol::socket*>(0)); 1973 } 1974 1975 /// Accept a new connection. 1976 /** 1977 * This function is used to accept a new connection from a peer. The function 1978 * call will block until a new connection has been accepted successfully or 1979 * an error occurs. 1980 * 1981 * This overload requires that the Protocol template parameter satisfy the 1982 * AcceptableProtocol type requirements. 1983 * 1984 * @param ex The I/O executor object to be used for the newly accepted 1985 * socket. 1986 * 1987 * @param peer_endpoint An endpoint object into which the endpoint of the 1988 * remote peer will be written. 1989 * 1990 * @returns A socket object representing the newly accepted connection. 1991 * 1992 * @throws asio::system_error Thrown on failure. 1993 * 1994 * @par Example 1995 * @code 1996 * asio::ip::tcp::acceptor acceptor(my_context); 1997 * ... 1998 * asio::ip::tcp::endpoint endpoint; 1999 * asio::ip::tcp::socket socket( 2000 * acceptor.accept(my_context2, endpoint)); 2001 * @endcode 2002 */ 2003 template <typename Executor1> 2004 typename Protocol::socket::template rebind_executor<Executor1>::other accept(const Executor1 & ex,endpoint_type & peer_endpoint,typename enable_if<is_executor<Executor1>::value>::type * =0)2005 accept(const Executor1& ex, endpoint_type& peer_endpoint, 2006 typename enable_if< 2007 is_executor<Executor1>::value 2008 >::type* = 0) 2009 { 2010 asio::error_code ec; 2011 typename Protocol::socket::template 2012 rebind_executor<Executor1>::other peer(ex); 2013 impl_.get_service().accept(impl_.get_implementation(), 2014 peer, &peer_endpoint, ec); 2015 asio::detail::throw_error(ec, "accept"); 2016 return peer; 2017 } 2018 2019 /// Accept a new connection. 2020 /** 2021 * This function is used to accept a new connection from a peer. The function 2022 * call will block until a new connection has been accepted successfully or 2023 * an error occurs. 2024 * 2025 * This overload requires that the Protocol template parameter satisfy the 2026 * AcceptableProtocol type requirements. 2027 * 2028 * @param context The I/O execution context object to be used for the newly 2029 * accepted socket. 2030 * 2031 * @param peer_endpoint An endpoint object into which the endpoint of the 2032 * remote peer will be written. 2033 * 2034 * @returns A socket object representing the newly accepted connection. 2035 * 2036 * @throws asio::system_error Thrown on failure. 2037 * 2038 * @par Example 2039 * @code 2040 * asio::ip::tcp::acceptor acceptor(my_context); 2041 * ... 2042 * asio::ip::tcp::endpoint endpoint; 2043 * asio::ip::tcp::socket socket( 2044 * acceptor.accept(my_context2, endpoint)); 2045 * @endcode 2046 */ 2047 template <typename ExecutionContext> 2048 typename Protocol::socket::template rebind_executor< 2049 typename ExecutionContext::executor_type>::other accept(ExecutionContext & context,endpoint_type & peer_endpoint,typename enable_if<is_convertible<ExecutionContext &,execution_context &>::value>::type * =0)2050 accept(ExecutionContext& context, endpoint_type& peer_endpoint, 2051 typename enable_if< 2052 is_convertible<ExecutionContext&, execution_context&>::value 2053 >::type* = 0) 2054 { 2055 asio::error_code ec; 2056 typename Protocol::socket::template rebind_executor< 2057 typename ExecutionContext::executor_type>::other peer(context); 2058 impl_.get_service().accept(impl_.get_implementation(), 2059 peer, &peer_endpoint, ec); 2060 asio::detail::throw_error(ec, "accept"); 2061 return peer; 2062 } 2063 2064 /// Accept a new connection. 2065 /** 2066 * This function is used to accept a new connection from a peer. The function 2067 * call will block until a new connection has been accepted successfully or 2068 * an error occurs. 2069 * 2070 * This overload requires that the Protocol template parameter satisfy the 2071 * AcceptableProtocol type requirements. 2072 * 2073 * @param ex The I/O executor object to be used for the newly accepted 2074 * socket. 2075 * 2076 * @param peer_endpoint An endpoint object into which the endpoint of the 2077 * remote peer will be written. 2078 * 2079 * @param ec Set to indicate what error occurred, if any. 2080 * 2081 * @returns On success, a socket object representing the newly accepted 2082 * connection. On error, a socket object where is_open() is false. 2083 * 2084 * @par Example 2085 * @code 2086 * asio::ip::tcp::acceptor acceptor(my_context); 2087 * ... 2088 * asio::ip::tcp::endpoint endpoint; 2089 * asio::ip::tcp::socket socket( 2090 * acceptor.accept(my_context2, endpoint, ec)); 2091 * if (ec) 2092 * { 2093 * // An error occurred. 2094 * } 2095 * @endcode 2096 */ 2097 template <typename Executor1> 2098 typename Protocol::socket::template rebind_executor<Executor1>::other accept(const executor_type & ex,endpoint_type & peer_endpoint,asio::error_code & ec,typename enable_if<is_executor<Executor1>::value>::type * =0)2099 accept(const executor_type& ex, 2100 endpoint_type& peer_endpoint, asio::error_code& ec, 2101 typename enable_if< 2102 is_executor<Executor1>::value 2103 >::type* = 0) 2104 { 2105 typename Protocol::socket::template 2106 rebind_executor<Executor1>::other peer(ex); 2107 impl_.get_service().accept(impl_.get_implementation(), 2108 peer, &peer_endpoint, ec); 2109 return peer; 2110 } 2111 2112 /// Accept a new connection. 2113 /** 2114 * This function is used to accept a new connection from a peer. The function 2115 * call will block until a new connection has been accepted successfully or 2116 * an error occurs. 2117 * 2118 * This overload requires that the Protocol template parameter satisfy the 2119 * AcceptableProtocol type requirements. 2120 * 2121 * @param context The I/O execution context object to be used for the newly 2122 * accepted socket. 2123 * 2124 * @param peer_endpoint An endpoint object into which the endpoint of the 2125 * remote peer will be written. 2126 * 2127 * @param ec Set to indicate what error occurred, if any. 2128 * 2129 * @returns On success, a socket object representing the newly accepted 2130 * connection. On error, a socket object where is_open() is false. 2131 * 2132 * @par Example 2133 * @code 2134 * asio::ip::tcp::acceptor acceptor(my_context); 2135 * ... 2136 * asio::ip::tcp::endpoint endpoint; 2137 * asio::ip::tcp::socket socket( 2138 * acceptor.accept(my_context2, endpoint, ec)); 2139 * if (ec) 2140 * { 2141 * // An error occurred. 2142 * } 2143 * @endcode 2144 */ 2145 template <typename ExecutionContext> 2146 typename Protocol::socket::template rebind_executor< 2147 typename ExecutionContext::executor_type>::other accept(ExecutionContext & context,endpoint_type & peer_endpoint,asio::error_code & ec,typename enable_if<is_convertible<ExecutionContext &,execution_context &>::value>::type * =0)2148 accept(ExecutionContext& context, 2149 endpoint_type& peer_endpoint, asio::error_code& ec, 2150 typename enable_if< 2151 is_convertible<ExecutionContext&, execution_context&>::value 2152 >::type* = 0) 2153 { 2154 typename Protocol::socket::template rebind_executor< 2155 typename ExecutionContext::executor_type>::other peer(context); 2156 impl_.get_service().accept(impl_.get_implementation(), 2157 peer, &peer_endpoint, ec); 2158 return peer; 2159 } 2160 2161 /// Start an asynchronous accept. 2162 /** 2163 * This function is used to asynchronously accept a new connection. The 2164 * function call always returns immediately. 2165 * 2166 * This overload requires that the Protocol template parameter satisfy the 2167 * AcceptableProtocol type requirements. 2168 * 2169 * @param ex The I/O executor object to be used for the newly accepted 2170 * socket. 2171 * 2172 * @param peer_endpoint An endpoint object into which the endpoint of the 2173 * remote peer will be written. Ownership of the peer_endpoint object is 2174 * retained by the caller, which must guarantee that it is valid until the 2175 * handler is called. 2176 * 2177 * @param handler The handler to be called when the accept operation 2178 * completes. Copies will be made of the handler as required. The function 2179 * signature of the handler must be: 2180 * @code void handler( 2181 * const asio::error_code& error, // Result of operation. 2182 * typename Protocol::socket::template rebind_executor< 2183 * Executor1>::other peer // On success, the newly accepted socket. 2184 * ); @endcode 2185 * Regardless of whether the asynchronous operation completes immediately or 2186 * not, the handler will not be invoked from within this function. On 2187 * immediate completion, invocation of the handler will be performed in a 2188 * manner equivalent to using asio::post(). 2189 * 2190 * @par Example 2191 * @code 2192 * void accept_handler(const asio::error_code& error, 2193 * asio::ip::tcp::socket peer) 2194 * { 2195 * if (!error) 2196 * { 2197 * // Accept succeeded. 2198 * } 2199 * } 2200 * 2201 * ... 2202 * 2203 * asio::ip::tcp::acceptor acceptor(my_context); 2204 * ... 2205 * asio::ip::tcp::endpoint endpoint; 2206 * acceptor.async_accept(my_context2, endpoint, accept_handler); 2207 * @endcode 2208 */ 2209 template <typename Executor1, typename MoveAcceptHandler> ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,void (asio::error_code,typename Protocol::socket::template rebind_executor<Executor1>::other))2210 ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, 2211 void (asio::error_code, 2212 typename Protocol::socket::template rebind_executor< 2213 Executor1>::other)) 2214 async_accept(const Executor1& ex, endpoint_type& peer_endpoint, 2215 ASIO_MOVE_ARG(MoveAcceptHandler) handler, 2216 typename enable_if< 2217 is_executor<Executor1>::value 2218 >::type* = 0) 2219 { 2220 typedef typename Protocol::socket::template rebind_executor< 2221 Executor1>::other other_socket_type; 2222 2223 return async_initiate<MoveAcceptHandler, 2224 void (asio::error_code, other_socket_type)>( 2225 initiate_async_move_accept(), handler, this, 2226 ex, &peer_endpoint, 2227 static_cast<other_socket_type*>(0)); 2228 } 2229 2230 /// Start an asynchronous accept. 2231 /** 2232 * This function is used to asynchronously accept a new connection. The 2233 * function call always returns immediately. 2234 * 2235 * This overload requires that the Protocol template parameter satisfy the 2236 * AcceptableProtocol type requirements. 2237 * 2238 * @param context The I/O execution context object to be used for the newly 2239 * accepted socket. 2240 * 2241 * @param peer_endpoint An endpoint object into which the endpoint of the 2242 * remote peer will be written. Ownership of the peer_endpoint object is 2243 * retained by the caller, which must guarantee that it is valid until the 2244 * handler is called. 2245 * 2246 * @param handler The handler to be called when the accept operation 2247 * completes. Copies will be made of the handler as required. The function 2248 * signature of the handler must be: 2249 * @code void handler( 2250 * const asio::error_code& error, // Result of operation. 2251 * typename Protocol::socket::template rebind_executor< 2252 * typename ExecutionContext::executor_type>::other peer 2253 * // On success, the newly accepted socket. 2254 * ); @endcode 2255 * Regardless of whether the asynchronous operation completes immediately or 2256 * not, the handler will not be invoked from within this function. On 2257 * immediate completion, invocation of the handler will be performed in a 2258 * manner equivalent to using asio::post(). 2259 * 2260 * @par Example 2261 * @code 2262 * void accept_handler(const asio::error_code& error, 2263 * asio::ip::tcp::socket peer) 2264 * { 2265 * if (!error) 2266 * { 2267 * // Accept succeeded. 2268 * } 2269 * } 2270 * 2271 * ... 2272 * 2273 * asio::ip::tcp::acceptor acceptor(my_context); 2274 * ... 2275 * asio::ip::tcp::endpoint endpoint; 2276 * acceptor.async_accept(my_context2, endpoint, accept_handler); 2277 * @endcode 2278 */ 2279 template <typename ExecutionContext, typename MoveAcceptHandler> ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,void (asio::error_code,typename Protocol::socket::template rebind_executor<typename ExecutionContext::executor_type>::other))2280 ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, 2281 void (asio::error_code, 2282 typename Protocol::socket::template rebind_executor< 2283 typename ExecutionContext::executor_type>::other)) 2284 async_accept(ExecutionContext& context, 2285 endpoint_type& peer_endpoint, 2286 ASIO_MOVE_ARG(MoveAcceptHandler) handler, 2287 typename enable_if< 2288 is_convertible<ExecutionContext&, execution_context&>::value 2289 >::type* = 0) 2290 { 2291 typedef typename Protocol::socket::template rebind_executor< 2292 typename ExecutionContext::executor_type>::other other_socket_type; 2293 2294 return async_initiate<MoveAcceptHandler, 2295 void (asio::error_code, other_socket_type)>( 2296 initiate_async_move_accept(), handler, this, 2297 context.get_executor(), &peer_endpoint, 2298 static_cast<other_socket_type*>(0)); 2299 } 2300 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) 2301 2302 private: 2303 // Disallow copying and assignment. 2304 basic_socket_acceptor(const basic_socket_acceptor&) ASIO_DELETED; 2305 basic_socket_acceptor& operator=( 2306 const basic_socket_acceptor&) ASIO_DELETED; 2307 2308 struct initiate_async_wait 2309 { 2310 template <typename WaitHandler> operator ()asio::basic_socket_acceptor::initiate_async_wait2311 void operator()(ASIO_MOVE_ARG(WaitHandler) handler, 2312 basic_socket_acceptor* self, wait_type w) const 2313 { 2314 // If you get an error on the following line it means that your handler 2315 // does not meet the documented type requirements for a WaitHandler. 2316 ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; 2317 2318 detail::non_const_lvalue<WaitHandler> handler2(handler); 2319 self->impl_.get_service().async_wait( 2320 self->impl_.get_implementation(), w, handler2.value, 2321 self->impl_.get_implementation_executor()); 2322 } 2323 }; 2324 2325 struct initiate_async_accept 2326 { 2327 template <typename AcceptHandler, typename Protocol1, typename Executor1> operator ()asio::basic_socket_acceptor::initiate_async_accept2328 void operator()(ASIO_MOVE_ARG(AcceptHandler) handler, 2329 basic_socket_acceptor* self, basic_socket<Protocol1, Executor1>* peer, 2330 endpoint_type* peer_endpoint) const 2331 { 2332 // If you get an error on the following line it means that your handler 2333 // does not meet the documented type requirements for a AcceptHandler. 2334 ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; 2335 2336 detail::non_const_lvalue<AcceptHandler> handler2(handler); 2337 self->impl_.get_service().async_accept( 2338 self->impl_.get_implementation(), *peer, peer_endpoint, 2339 handler2.value, self->impl_.get_implementation_executor()); 2340 } 2341 }; 2342 2343 struct initiate_async_move_accept 2344 { 2345 template <typename MoveAcceptHandler, typename Executor1, typename Socket> operator ()asio::basic_socket_acceptor::initiate_async_move_accept2346 void operator()(ASIO_MOVE_ARG(MoveAcceptHandler) handler, 2347 basic_socket_acceptor* self, const Executor1& peer_ex, 2348 endpoint_type* peer_endpoint, Socket*) const 2349 { 2350 // If you get an error on the following line it means that your handler 2351 // does not meet the documented type requirements for a MoveAcceptHandler. 2352 ASIO_MOVE_ACCEPT_HANDLER_CHECK( 2353 MoveAcceptHandler, handler, Socket) type_check; 2354 2355 detail::non_const_lvalue<MoveAcceptHandler> handler2(handler); 2356 self->impl_.get_service().async_move_accept( 2357 self->impl_.get_implementation(), peer_ex, peer_endpoint, 2358 handler2.value, self->impl_.get_implementation_executor()); 2359 } 2360 }; 2361 2362 #if defined(ASIO_WINDOWS_RUNTIME) 2363 detail::io_object_impl< 2364 detail::null_socket_service<Protocol>, Executor> impl_; 2365 #elif defined(ASIO_HAS_IOCP) 2366 detail::io_object_impl< 2367 detail::win_iocp_socket_service<Protocol>, Executor> impl_; 2368 #else 2369 detail::io_object_impl< 2370 detail::reactive_socket_service<Protocol>, Executor> impl_; 2371 #endif 2372 }; 2373 2374 } // namespace asio 2375 2376 #include "asio/detail/pop_options.hpp" 2377 2378 #endif // ASIO_BASIC_SOCKET_ACCEPTOR_HPP 2379