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