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