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