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 15 #include "asio/detail/config.hpp" 16 #include "asio/basic_io_object.hpp" 17 #include "asio/basic_socket.hpp" 18 #include "asio/detail/handler_type_requirements.hpp" 19 #include "asio/detail/throw_error.hpp" 20 #include "asio/detail/type_traits.hpp" 21 #include "asio/error.hpp" 22 #include "asio/socket_acceptor_service.hpp" 23 #include "asio/socket_base.hpp" 24 25 #include "asio/detail/push_options.hpp" 26 27 namespace asio { 28 29 /// Provides the ability to accept new connections. 30 /** 31 * The basic_socket_acceptor class template is used for accepting new socket 32 * connections. 33 * 34 * @par Thread Safety 35 * @e Distinct @e objects: Safe.@n 36 * @e Shared @e objects: Unsafe. 37 * 38 * @par Example 39 * Opening a socket acceptor with the SO_REUSEADDR option enabled: 40 * @code 41 * asio::ip::tcp::acceptor acceptor(io_service); 42 * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), port); 43 * acceptor.open(endpoint.protocol()); 44 * acceptor.set_option(asio::ip::tcp::acceptor::reuse_address(true)); 45 * acceptor.bind(endpoint); 46 * acceptor.listen(); 47 * @endcode 48 */ 49 template <typename Protocol, 50 typename SocketAcceptorService = socket_acceptor_service<Protocol> > 51 class basic_socket_acceptor 52 : public basic_io_object<SocketAcceptorService>, 53 public socket_base 54 { 55 public: 56 /// (Deprecated: Use native_handle_type.) The native representation of an 57 /// acceptor. 58 typedef typename SocketAcceptorService::native_handle_type native_type; 59 60 /// The native representation of an acceptor. 61 typedef typename SocketAcceptorService::native_handle_type native_handle_type; 62 63 /// The protocol type. 64 typedef Protocol protocol_type; 65 66 /// The endpoint type. 67 typedef typename Protocol::endpoint endpoint_type; 68 69 /// Construct an acceptor without opening it. 70 /** 71 * This constructor creates an acceptor without opening it to listen for new 72 * connections. The open() function must be called before the acceptor can 73 * accept new socket connections. 74 * 75 * @param io_service The io_service object that the acceptor will use to 76 * dispatch handlers for any asynchronous operations performed on the 77 * acceptor. 78 */ basic_socket_acceptor(asio::io_service & io_service)79 explicit basic_socket_acceptor(asio::io_service& io_service) 80 : basic_io_object<SocketAcceptorService>(io_service) 81 { 82 } 83 84 /// Construct an open acceptor. 85 /** 86 * This constructor creates an acceptor and automatically opens it. 87 * 88 * @param io_service The io_service object that the acceptor will use to 89 * dispatch handlers for any asynchronous operations performed on the 90 * acceptor. 91 * 92 * @param protocol An object specifying protocol parameters to be used. 93 * 94 * @throws asio::system_error Thrown on failure. 95 */ basic_socket_acceptor(asio::io_service & io_service,const protocol_type & protocol)96 basic_socket_acceptor(asio::io_service& io_service, 97 const protocol_type& protocol) 98 : basic_io_object<SocketAcceptorService>(io_service) 99 { 100 asio::error_code ec; 101 this->get_service().open(this->get_implementation(), protocol, ec); 102 asio::detail::throw_error(ec, "open"); 103 } 104 105 /// Construct an acceptor opened on the given endpoint. 106 /** 107 * This constructor creates an acceptor and automatically opens it to listen 108 * for new connections on the specified endpoint. 109 * 110 * @param io_service The io_service object that the acceptor will use to 111 * dispatch handlers for any asynchronous operations performed on the 112 * acceptor. 113 * 114 * @param endpoint An endpoint on the local machine on which the acceptor 115 * will listen for new connections. 116 * 117 * @param reuse_addr Whether the constructor should set the socket option 118 * socket_base::reuse_address. 119 * 120 * @throws asio::system_error Thrown on failure. 121 * 122 * @note This constructor is equivalent to the following code: 123 * @code 124 * basic_socket_acceptor<Protocol> acceptor(io_service); 125 * acceptor.open(endpoint.protocol()); 126 * if (reuse_addr) 127 * acceptor.set_option(socket_base::reuse_address(true)); 128 * acceptor.bind(endpoint); 129 * acceptor.listen(listen_backlog); 130 * @endcode 131 */ basic_socket_acceptor(asio::io_service & io_service,const endpoint_type & endpoint,bool reuse_addr=true)132 basic_socket_acceptor(asio::io_service& io_service, 133 const endpoint_type& endpoint, bool reuse_addr = true) 134 : basic_io_object<SocketAcceptorService>(io_service) 135 { 136 asio::error_code ec; 137 const protocol_type protocol = endpoint.protocol(); 138 this->get_service().open(this->get_implementation(), protocol, ec); 139 asio::detail::throw_error(ec, "open"); 140 if (reuse_addr) 141 { 142 this->get_service().set_option(this->get_implementation(), 143 socket_base::reuse_address(true), ec); 144 asio::detail::throw_error(ec, "set_option"); 145 } 146 this->get_service().bind(this->get_implementation(), endpoint, ec); 147 asio::detail::throw_error(ec, "bind"); 148 this->get_service().listen(this->get_implementation(), 149 socket_base::max_connections, ec); 150 asio::detail::throw_error(ec, "listen"); 151 } 152 153 /// Construct a basic_socket_acceptor on an existing native acceptor. 154 /** 155 * This constructor creates an acceptor object to hold an existing native 156 * acceptor. 157 * 158 * @param io_service The io_service object that the acceptor will use to 159 * dispatch handlers for any asynchronous operations performed on the 160 * acceptor. 161 * 162 * @param protocol An object specifying protocol parameters to be used. 163 * 164 * @param native_acceptor A native acceptor. 165 * 166 * @throws asio::system_error Thrown on failure. 167 */ basic_socket_acceptor(asio::io_service & io_service,const protocol_type & protocol,const native_handle_type & native_acceptor)168 basic_socket_acceptor(asio::io_service& io_service, 169 const protocol_type& protocol, const native_handle_type& native_acceptor) 170 : basic_io_object<SocketAcceptorService>(io_service) 171 { 172 asio::error_code ec; 173 this->get_service().assign(this->get_implementation(), 174 protocol, native_acceptor, ec); 175 asio::detail::throw_error(ec, "assign"); 176 } 177 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_service&) 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_service&) 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_service&) 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>(other.get_io_service()) 231 { 232 this->get_service().template converting_move_construct<Protocol1>( 233 this->get_implementation(), other.get_implementation()); 234 } 235 236 /// Move-assign a basic_socket_acceptor from an acceptor of another protocol 237 /// type. 238 /** 239 * This assignment operator moves an acceptor from one object to another. 240 * 241 * @param other The other basic_socket_acceptor object from which the move 242 * will occur. 243 * 244 * @note Following the move, the moved-from object is in the same state as if 245 * constructed using the @c basic_socket(io_service&) constructor. 246 */ 247 template <typename Protocol1, typename SocketAcceptorService1> 248 typename enable_if<is_convertible<Protocol1, Protocol>::value, operator =(basic_socket_acceptor<Protocol1,SocketAcceptorService1> && other)249 basic_socket_acceptor>::type& operator=( 250 basic_socket_acceptor<Protocol1, SocketAcceptorService1>&& other) 251 { 252 basic_socket_acceptor tmp(ASIO_MOVE_CAST2(basic_socket_acceptor< 253 Protocol1, SocketAcceptorService1>)(other)); 254 basic_io_object<SocketAcceptorService>::operator=( 255 ASIO_MOVE_CAST(basic_socket_acceptor)(tmp)); 256 return *this; 257 } 258 259 /// Open the acceptor using the specified protocol. 260 /** 261 * This function opens the socket acceptor so that it will use the specified 262 * protocol. 263 * 264 * @param protocol An object specifying which protocol is to be used. 265 * 266 * @throws asio::system_error Thrown on failure. 267 * 268 * @par Example 269 * @code 270 * asio::ip::tcp::acceptor acceptor(io_service); 271 * acceptor.open(asio::ip::tcp::v4()); 272 * @endcode 273 */ open(const protocol_type & protocol=protocol_type ())274 void open(const protocol_type& protocol = protocol_type()) 275 { 276 asio::error_code ec; 277 this->get_service().open(this->get_implementation(), protocol, ec); 278 asio::detail::throw_error(ec, "open"); 279 } 280 281 /// Open the acceptor using the specified protocol. 282 /** 283 * This function opens the socket acceptor so that it will use the specified 284 * protocol. 285 * 286 * @param protocol An object specifying which protocol is to be used. 287 * 288 * @param ec Set to indicate what error occurred, if any. 289 * 290 * @par Example 291 * @code 292 * asio::ip::tcp::acceptor acceptor(io_service); 293 * asio::error_code ec; 294 * acceptor.open(asio::ip::tcp::v4(), ec); 295 * if (ec) 296 * { 297 * // An error occurred. 298 * } 299 * @endcode 300 */ open(const protocol_type & protocol,asio::error_code & ec)301 asio::error_code open(const protocol_type& protocol, 302 asio::error_code& ec) 303 { 304 return this->get_service().open(this->get_implementation(), protocol, ec); 305 } 306 307 /// Assigns an existing native acceptor to the acceptor. 308 /* 309 * This function opens the acceptor to hold an existing native acceptor. 310 * 311 * @param protocol An object specifying which protocol is to be used. 312 * 313 * @param native_acceptor A native acceptor. 314 * 315 * @throws asio::system_error Thrown on failure. 316 */ assign(const protocol_type & protocol,const native_handle_type & native_acceptor)317 void assign(const protocol_type& protocol, 318 const native_handle_type& native_acceptor) 319 { 320 asio::error_code ec; 321 this->get_service().assign(this->get_implementation(), 322 protocol, native_acceptor, ec); 323 asio::detail::throw_error(ec, "assign"); 324 } 325 326 /// Assigns an existing native acceptor to the acceptor. 327 /* 328 * This function opens the acceptor to hold an existing native acceptor. 329 * 330 * @param protocol An object specifying which protocol is to be used. 331 * 332 * @param native_acceptor A native acceptor. 333 * 334 * @param ec Set to indicate what error occurred, if any. 335 */ assign(const protocol_type & protocol,const native_handle_type & native_acceptor,asio::error_code & ec)336 asio::error_code assign(const protocol_type& protocol, 337 const native_handle_type& native_acceptor, asio::error_code& ec) 338 { 339 return this->get_service().assign(this->get_implementation(), 340 protocol, native_acceptor, ec); 341 } 342 343 /// Determine whether the acceptor is open. is_open() const344 bool is_open() const 345 { 346 return this->get_service().is_open(this->get_implementation()); 347 } 348 349 /// Bind the acceptor to the given local endpoint. 350 /** 351 * This function binds the socket acceptor to the specified endpoint on the 352 * local machine. 353 * 354 * @param endpoint An endpoint on the local machine to which the socket 355 * acceptor will be bound. 356 * 357 * @throws asio::system_error Thrown on failure. 358 * 359 * @par Example 360 * @code 361 * asio::ip::tcp::acceptor acceptor(io_service); 362 * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), 12345); 363 * acceptor.open(endpoint.protocol()); 364 * acceptor.bind(endpoint); 365 * @endcode 366 */ bind(const endpoint_type & endpoint)367 void bind(const endpoint_type& endpoint) 368 { 369 asio::error_code ec; 370 this->get_service().bind(this->get_implementation(), endpoint, ec); 371 asio::detail::throw_error(ec, "bind"); 372 } 373 374 /// Bind the acceptor to the given local endpoint. 375 /** 376 * This function binds the socket acceptor to the specified endpoint on the 377 * local machine. 378 * 379 * @param endpoint An endpoint on the local machine to which the socket 380 * acceptor will be bound. 381 * 382 * @param ec Set to indicate what error occurred, if any. 383 * 384 * @par Example 385 * @code 386 * asio::ip::tcp::acceptor acceptor(io_service); 387 * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), 12345); 388 * acceptor.open(endpoint.protocol()); 389 * asio::error_code ec; 390 * acceptor.bind(endpoint, ec); 391 * if (ec) 392 * { 393 * // An error occurred. 394 * } 395 * @endcode 396 */ bind(const endpoint_type & endpoint,asio::error_code & ec)397 asio::error_code bind(const endpoint_type& endpoint, 398 asio::error_code& ec) 399 { 400 return this->get_service().bind(this->get_implementation(), endpoint, ec); 401 } 402 403 /// Place the acceptor into the state where it will listen for new 404 /// connections. 405 /** 406 * This function puts the socket acceptor into the state where it may accept 407 * new connections. 408 * 409 * @param backlog The maximum length of the queue of pending connections. 410 * 411 * @throws asio::system_error Thrown on failure. 412 */ listen(int backlog=socket_base::max_connections)413 void listen(int backlog = socket_base::max_connections) 414 { 415 asio::error_code ec; 416 this->get_service().listen(this->get_implementation(), backlog, ec); 417 asio::detail::throw_error(ec, "listen"); 418 } 419 420 /// Place the acceptor into the state where it will listen for new 421 /// connections. 422 /** 423 * This function puts the socket acceptor into the state where it may accept 424 * new connections. 425 * 426 * @param backlog The maximum length of the queue of pending connections. 427 * 428 * @param ec Set to indicate what error occurred, if any. 429 * 430 * @par Example 431 * @code 432 * asio::ip::tcp::acceptor acceptor(io_service); 433 * ... 434 * asio::error_code ec; 435 * acceptor.listen(asio::socket_base::max_connections, ec); 436 * if (ec) 437 * { 438 * // An error occurred. 439 * } 440 * @endcode 441 */ listen(int backlog,asio::error_code & ec)442 asio::error_code listen(int backlog, asio::error_code& ec) 443 { 444 return this->get_service().listen(this->get_implementation(), backlog, ec); 445 } 446 447 /// Close the acceptor. 448 /** 449 * This function is used to close the acceptor. Any asynchronous accept 450 * operations will be cancelled immediately. 451 * 452 * A subsequent call to open() is required before the acceptor can again be 453 * used to again perform socket accept operations. 454 * 455 * @throws asio::system_error Thrown on failure. 456 */ close()457 void close() 458 { 459 asio::error_code ec; 460 this->get_service().close(this->get_implementation(), ec); 461 asio::detail::throw_error(ec, "close"); 462 } 463 464 /// Close the acceptor. 465 /** 466 * This function is used to close the acceptor. Any asynchronous accept 467 * operations will be cancelled immediately. 468 * 469 * A subsequent call to open() is required before the acceptor can again be 470 * used to again perform socket accept operations. 471 * 472 * @param ec Set to indicate what error occurred, if any. 473 * 474 * @par Example 475 * @code 476 * asio::ip::tcp::acceptor acceptor(io_service); 477 * ... 478 * asio::error_code ec; 479 * acceptor.close(ec); 480 * if (ec) 481 * { 482 * // An error occurred. 483 * } 484 * @endcode 485 */ close(asio::error_code & ec)486 asio::error_code close(asio::error_code& ec) 487 { 488 return this->get_service().close(this->get_implementation(), ec); 489 } 490 491 /// (Deprecated: Use native_handle().) Get the native acceptor representation. 492 /** 493 * This function may be used to obtain the underlying representation of the 494 * acceptor. This is intended to allow access to native acceptor functionality 495 * that is not otherwise provided. 496 */ native()497 native_type native() 498 { 499 return this->get_service().native_handle(this->get_implementation()); 500 } 501 502 /// Get the native acceptor representation. 503 /** 504 * This function may be used to obtain the underlying representation of the 505 * acceptor. This is intended to allow access to native acceptor functionality 506 * that is not otherwise provided. 507 */ native_handle()508 native_handle_type native_handle() 509 { 510 return this->get_service().native_handle(this->get_implementation()); 511 } 512 513 /// Cancel all asynchronous operations associated with the acceptor. 514 /** 515 * This function causes all outstanding asynchronous connect, send and receive 516 * operations to finish immediately, and the handlers for cancelled operations 517 * will be passed the asio::error::operation_aborted error. 518 * 519 * @throws asio::system_error Thrown on failure. 520 */ cancel()521 void cancel() 522 { 523 asio::error_code ec; 524 this->get_service().cancel(this->get_implementation(), ec); 525 asio::detail::throw_error(ec, "cancel"); 526 } 527 528 /// Cancel all asynchronous operations associated with the acceptor. 529 /** 530 * This function causes all outstanding asynchronous connect, send and receive 531 * operations to finish immediately, and the handlers for cancelled operations 532 * will be passed the asio::error::operation_aborted error. 533 * 534 * @param ec Set to indicate what error occurred, if any. 535 */ cancel(asio::error_code & ec)536 asio::error_code cancel(asio::error_code& ec) 537 { 538 return this->get_service().cancel(this->get_implementation(), ec); 539 } 540 541 /// Set an option on the acceptor. 542 /** 543 * This function is used to set an option on the acceptor. 544 * 545 * @param option The new option value to be set on the acceptor. 546 * 547 * @throws asio::system_error Thrown on failure. 548 * 549 * @sa SettableSocketOption @n 550 * asio::socket_base::reuse_address 551 * asio::socket_base::enable_connection_aborted 552 * 553 * @par Example 554 * Setting the SOL_SOCKET/SO_REUSEADDR option: 555 * @code 556 * asio::ip::tcp::acceptor acceptor(io_service); 557 * ... 558 * asio::ip::tcp::acceptor::reuse_address option(true); 559 * acceptor.set_option(option); 560 * @endcode 561 */ 562 template <typename SettableSocketOption> set_option(const SettableSocketOption & option)563 void set_option(const SettableSocketOption& option) 564 { 565 asio::error_code ec; 566 this->get_service().set_option(this->get_implementation(), option, ec); 567 asio::detail::throw_error(ec, "set_option"); 568 } 569 570 /// Set an option on the acceptor. 571 /** 572 * This function is used to set an option on the acceptor. 573 * 574 * @param option The new option value to be set on the acceptor. 575 * 576 * @param ec Set to indicate what error occurred, if any. 577 * 578 * @sa SettableSocketOption @n 579 * asio::socket_base::reuse_address 580 * asio::socket_base::enable_connection_aborted 581 * 582 * @par Example 583 * Setting the SOL_SOCKET/SO_REUSEADDR option: 584 * @code 585 * asio::ip::tcp::acceptor acceptor(io_service); 586 * ... 587 * asio::ip::tcp::acceptor::reuse_address option(true); 588 * asio::error_code ec; 589 * acceptor.set_option(option, ec); 590 * if (ec) 591 * { 592 * // An error occurred. 593 * } 594 * @endcode 595 */ 596 template <typename SettableSocketOption> set_option(const SettableSocketOption & option,asio::error_code & ec)597 asio::error_code set_option(const SettableSocketOption& option, 598 asio::error_code& ec) 599 { 600 return this->get_service().set_option( 601 this->get_implementation(), option, ec); 602 } 603 604 /// Get an option from the acceptor. 605 /** 606 * This function is used to get the current value of an option on the 607 * acceptor. 608 * 609 * @param option The option value to be obtained from the acceptor. 610 * 611 * @throws asio::system_error Thrown on failure. 612 * 613 * @sa GettableSocketOption @n 614 * asio::socket_base::reuse_address 615 * 616 * @par Example 617 * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: 618 * @code 619 * asio::ip::tcp::acceptor acceptor(io_service); 620 * ... 621 * asio::ip::tcp::acceptor::reuse_address option; 622 * acceptor.get_option(option); 623 * bool is_set = option.get(); 624 * @endcode 625 */ 626 template <typename GettableSocketOption> get_option(GettableSocketOption & option)627 void get_option(GettableSocketOption& option) 628 { 629 asio::error_code ec; 630 this->get_service().get_option(this->get_implementation(), option, ec); 631 asio::detail::throw_error(ec, "get_option"); 632 } 633 634 /// Get an option from the acceptor. 635 /** 636 * This function is used to get the current value of an option on the 637 * acceptor. 638 * 639 * @param option The option value to be obtained from the acceptor. 640 * 641 * @param ec Set to indicate what error occurred, if any. 642 * 643 * @sa GettableSocketOption @n 644 * asio::socket_base::reuse_address 645 * 646 * @par Example 647 * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: 648 * @code 649 * asio::ip::tcp::acceptor acceptor(io_service); 650 * ... 651 * asio::ip::tcp::acceptor::reuse_address option; 652 * asio::error_code ec; 653 * acceptor.get_option(option, ec); 654 * if (ec) 655 * { 656 * // An error occurred. 657 * } 658 * bool is_set = option.get(); 659 * @endcode 660 */ 661 template <typename GettableSocketOption> get_option(GettableSocketOption & option,asio::error_code & ec)662 asio::error_code get_option(GettableSocketOption& option, 663 asio::error_code& ec) 664 { 665 return this->get_service().get_option( 666 this->get_implementation(), option, ec); 667 } 668 669 /// Perform an IO control command on the acceptor. 670 /** 671 * This function is used to execute an IO control command on the acceptor. 672 * 673 * @param command The IO control command to be performed on the acceptor. 674 * 675 * @throws asio::system_error Thrown on failure. 676 * 677 * @sa IoControlCommand @n 678 * asio::socket_base::non_blocking_io 679 * 680 * @par Example 681 * Getting the number of bytes ready to read: 682 * @code 683 * asio::ip::tcp::acceptor acceptor(io_service); 684 * ... 685 * asio::ip::tcp::acceptor::non_blocking_io command(true); 686 * socket.io_control(command); 687 * @endcode 688 */ 689 template <typename IoControlCommand> io_control(IoControlCommand & command)690 void io_control(IoControlCommand& command) 691 { 692 asio::error_code ec; 693 this->get_service().io_control(this->get_implementation(), command, ec); 694 asio::detail::throw_error(ec, "io_control"); 695 } 696 697 /// Perform an IO control command on the acceptor. 698 /** 699 * This function is used to execute an IO control command on the acceptor. 700 * 701 * @param command The IO control command to be performed on the acceptor. 702 * 703 * @param ec Set to indicate what error occurred, if any. 704 * 705 * @sa IoControlCommand @n 706 * asio::socket_base::non_blocking_io 707 * 708 * @par Example 709 * Getting the number of bytes ready to read: 710 * @code 711 * asio::ip::tcp::acceptor acceptor(io_service); 712 * ... 713 * asio::ip::tcp::acceptor::non_blocking_io command(true); 714 * asio::error_code ec; 715 * socket.io_control(command, ec); 716 * if (ec) 717 * { 718 * // An error occurred. 719 * } 720 * @endcode 721 */ 722 template <typename IoControlCommand> io_control(IoControlCommand & command,asio::error_code & ec)723 asio::error_code io_control(IoControlCommand& command, 724 asio::error_code& ec) 725 { 726 return this->get_service().io_control( 727 this->get_implementation(), command, ec); 728 } 729 730 /// Gets the non-blocking mode of the acceptor. 731 /** 732 * @returns @c true if the acceptor's synchronous operations will fail with 733 * asio::error::would_block if they are unable to perform the requested 734 * operation immediately. If @c false, synchronous operations will block 735 * until complete. 736 * 737 * @note The non-blocking mode has no effect on the behaviour of asynchronous 738 * operations. Asynchronous operations will never fail with the error 739 * asio::error::would_block. 740 */ non_blocking() const741 bool non_blocking() const 742 { 743 return this->get_service().non_blocking(this->get_implementation()); 744 } 745 746 /// Sets the non-blocking mode of the acceptor. 747 /** 748 * @param mode If @c true, the acceptor's synchronous operations will fail 749 * with asio::error::would_block if they are unable to perform the 750 * requested operation immediately. If @c false, synchronous operations will 751 * block until complete. 752 * 753 * @throws asio::system_error Thrown on failure. 754 * 755 * @note The non-blocking mode has no effect on the behaviour of asynchronous 756 * operations. Asynchronous operations will never fail with the error 757 * asio::error::would_block. 758 */ non_blocking(bool mode)759 void non_blocking(bool mode) 760 { 761 asio::error_code ec; 762 this->get_service().non_blocking(this->get_implementation(), mode, ec); 763 asio::detail::throw_error(ec, "non_blocking"); 764 } 765 766 /// Sets the non-blocking mode of the acceptor. 767 /** 768 * @param mode If @c true, the acceptor's synchronous operations will fail 769 * with asio::error::would_block if they are unable to perform the 770 * requested operation immediately. If @c false, synchronous operations will 771 * block until complete. 772 * 773 * @param ec Set to indicate what error occurred, if any. 774 * 775 * @note The non-blocking mode has no effect on the behaviour of asynchronous 776 * operations. Asynchronous operations will never fail with the error 777 * asio::error::would_block. 778 */ non_blocking(bool mode,asio::error_code & ec)779 asio::error_code non_blocking( 780 bool mode, asio::error_code& ec) 781 { 782 return this->get_service().non_blocking( 783 this->get_implementation(), mode, ec); 784 } 785 786 /// Gets the non-blocking mode of the native acceptor implementation. 787 /** 788 * This function is used to retrieve the non-blocking mode of the underlying 789 * native acceptor. This mode has no effect on the behaviour of the acceptor 790 * object's synchronous operations. 791 * 792 * @returns @c true if the underlying acceptor is in non-blocking mode and 793 * direct system calls may fail with asio::error::would_block (or the 794 * equivalent system error). 795 * 796 * @note The current non-blocking mode is cached by the acceptor object. 797 * Consequently, the return value may be incorrect if the non-blocking mode 798 * was set directly on the native acceptor. 799 */ native_non_blocking() const800 bool native_non_blocking() const 801 { 802 return this->get_service().native_non_blocking(this->get_implementation()); 803 } 804 805 /// Sets the non-blocking mode of the native acceptor implementation. 806 /** 807 * This function is used to modify the non-blocking mode of the underlying 808 * native acceptor. It has no effect on the behaviour of the acceptor object's 809 * synchronous operations. 810 * 811 * @param mode If @c true, the underlying acceptor is put into non-blocking 812 * mode and direct system calls may fail with asio::error::would_block 813 * (or the equivalent system error). 814 * 815 * @throws asio::system_error Thrown on failure. If the @c mode is 816 * @c false, but the current value of @c non_blocking() is @c true, this 817 * function fails with asio::error::invalid_argument, as the 818 * combination does not make sense. 819 */ native_non_blocking(bool mode)820 void native_non_blocking(bool mode) 821 { 822 asio::error_code ec; 823 this->get_service().native_non_blocking( 824 this->get_implementation(), mode, ec); 825 asio::detail::throw_error(ec, "native_non_blocking"); 826 } 827 828 /// Sets the non-blocking mode of the native acceptor implementation. 829 /** 830 * This function is used to modify the non-blocking mode of the underlying 831 * native acceptor. It has no effect on the behaviour of the acceptor object's 832 * synchronous operations. 833 * 834 * @param mode If @c true, the underlying acceptor is put into non-blocking 835 * mode and direct system calls may fail with asio::error::would_block 836 * (or the equivalent system error). 837 * 838 * @param ec Set to indicate what error occurred, if any. If the @c mode is 839 * @c false, but the current value of @c non_blocking() is @c true, this 840 * function fails with asio::error::invalid_argument, as the 841 * combination does not make sense. 842 */ native_non_blocking(bool mode,asio::error_code & ec)843 asio::error_code native_non_blocking( 844 bool mode, asio::error_code& ec) 845 { 846 return this->get_service().native_non_blocking( 847 this->get_implementation(), mode, ec); 848 } 849 850 /// Get the local endpoint of the acceptor. 851 /** 852 * This function is used to obtain the locally bound endpoint of the acceptor. 853 * 854 * @returns An object that represents the local endpoint of the acceptor. 855 * 856 * @throws asio::system_error Thrown on failure. 857 * 858 * @par Example 859 * @code 860 * asio::ip::tcp::acceptor acceptor(io_service); 861 * ... 862 * asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(); 863 * @endcode 864 */ local_endpoint() const865 endpoint_type local_endpoint() const 866 { 867 asio::error_code ec; 868 endpoint_type ep = this->get_service().local_endpoint( 869 this->get_implementation(), ec); 870 asio::detail::throw_error(ec, "local_endpoint"); 871 return ep; 872 } 873 874 /// Get the local endpoint of the acceptor. 875 /** 876 * This function is used to obtain the locally bound endpoint of the acceptor. 877 * 878 * @param ec Set to indicate what error occurred, if any. 879 * 880 * @returns An object that represents the local endpoint of the acceptor. 881 * Returns a default-constructed endpoint object if an error occurred and the 882 * error handler did not throw an exception. 883 * 884 * @par Example 885 * @code 886 * asio::ip::tcp::acceptor acceptor(io_service); 887 * ... 888 * asio::error_code ec; 889 * asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec); 890 * if (ec) 891 * { 892 * // An error occurred. 893 * } 894 * @endcode 895 */ local_endpoint(asio::error_code & ec) const896 endpoint_type local_endpoint(asio::error_code& ec) const 897 { 898 return this->get_service().local_endpoint(this->get_implementation(), ec); 899 } 900 901 /// Accept a new connection. 902 /** 903 * This function is used to accept a new connection from a peer into the 904 * given socket. The function call will block until a new connection has been 905 * accepted successfully or an error occurs. 906 * 907 * @param peer The socket into which the new connection will be accepted. 908 * 909 * @throws asio::system_error Thrown on failure. 910 * 911 * @par Example 912 * @code 913 * asio::ip::tcp::acceptor acceptor(io_service); 914 * ... 915 * asio::ip::tcp::socket socket(io_service); 916 * acceptor.accept(socket); 917 * @endcode 918 */ 919 template <typename Protocol1, typename SocketService> accept(basic_socket<Protocol1,SocketService> & peer,typename enable_if<is_convertible<Protocol,Protocol1>::value>::type * =0)920 void accept(basic_socket<Protocol1, SocketService>& peer, 921 typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0) 922 { 923 asio::error_code ec; 924 this->get_service().accept(this->get_implementation(), 925 peer, static_cast<endpoint_type*>(0), ec); 926 asio::detail::throw_error(ec, "accept"); 927 } 928 929 /// Accept a new connection. 930 /** 931 * This function is used to accept a new connection from a peer into the 932 * given socket. The function call will block until a new connection has been 933 * accepted successfully or an error occurs. 934 * 935 * @param peer The socket into which the new connection will be accepted. 936 * 937 * @param ec Set to indicate what error occurred, if any. 938 * 939 * @par Example 940 * @code 941 * asio::ip::tcp::acceptor acceptor(io_service); 942 * ... 943 * asio::ip::tcp::soocket socket(io_service); 944 * asio::error_code ec; 945 * acceptor.accept(socket, ec); 946 * if (ec) 947 * { 948 * // An error occurred. 949 * } 950 * @endcode 951 */ 952 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)953 asio::error_code accept( 954 basic_socket<Protocol1, SocketService>& peer, 955 asio::error_code& ec, 956 typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0) 957 { 958 return this->get_service().accept(this->get_implementation(), 959 peer, static_cast<endpoint_type*>(0), ec); 960 } 961 962 /// Start an asynchronous accept. 963 /** 964 * This function is used to asynchronously accept a new connection into a 965 * socket. The function call always returns immediately. 966 * 967 * @param peer The socket into which the new connection will be accepted. 968 * Ownership of the peer object is retained by the caller, which must 969 * guarantee that it is valid until the handler is called. 970 * 971 * @param handler The handler to be called when the accept operation 972 * completes. Copies will be made of the handler as required. The function 973 * signature of the handler must be: 974 * @code void handler( 975 * const asio::error_code& error // Result of operation. 976 * ); @endcode 977 * Regardless of whether the asynchronous operation completes immediately or 978 * not, the handler will not be invoked from within this function. Invocation 979 * of the handler will be performed in a manner equivalent to using 980 * asio::io_service::post(). 981 * 982 * @par Example 983 * @code 984 * void accept_handler(const asio::error_code& error) 985 * { 986 * if (!error) 987 * { 988 * // Accept succeeded. 989 * } 990 * } 991 * 992 * ... 993 * 994 * asio::ip::tcp::acceptor acceptor(io_service); 995 * ... 996 * asio::ip::tcp::socket socket(io_service); 997 * acceptor.async_accept(socket, accept_handler); 998 * @endcode 999 */ 1000 template <typename Protocol1, typename SocketService, typename AcceptHandler> ASIO_INITFN_RESULT_TYPE(AcceptHandler,void (asio::error_code))1001 ASIO_INITFN_RESULT_TYPE(AcceptHandler, 1002 void (asio::error_code)) 1003 async_accept(basic_socket<Protocol1, SocketService>& peer, 1004 ASIO_MOVE_ARG(AcceptHandler) handler, 1005 typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0) 1006 { 1007 // If you get an error on the following line it means that your handler does 1008 // not meet the documented type requirements for a AcceptHandler. 1009 ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; 1010 1011 return this->get_service().async_accept(this->get_implementation(), 1012 peer, static_cast<endpoint_type*>(0), 1013 ASIO_MOVE_CAST(AcceptHandler)(handler)); 1014 } 1015 1016 /// Accept a new connection and obtain the endpoint of the peer 1017 /** 1018 * This function is used to accept a new connection from a peer into the 1019 * given socket, and additionally provide the endpoint of the remote peer. 1020 * The function call will block until a new connection has been accepted 1021 * successfully or an error occurs. 1022 * 1023 * @param peer The socket into which the new connection will be accepted. 1024 * 1025 * @param peer_endpoint An endpoint object which will receive the endpoint of 1026 * the remote peer. 1027 * 1028 * @throws asio::system_error Thrown on failure. 1029 * 1030 * @par Example 1031 * @code 1032 * asio::ip::tcp::acceptor acceptor(io_service); 1033 * ... 1034 * asio::ip::tcp::socket socket(io_service); 1035 * asio::ip::tcp::endpoint endpoint; 1036 * acceptor.accept(socket, endpoint); 1037 * @endcode 1038 */ 1039 template <typename SocketService> accept(basic_socket<protocol_type,SocketService> & peer,endpoint_type & peer_endpoint)1040 void accept(basic_socket<protocol_type, SocketService>& peer, 1041 endpoint_type& peer_endpoint) 1042 { 1043 asio::error_code ec; 1044 this->get_service().accept(this->get_implementation(), 1045 peer, &peer_endpoint, ec); 1046 asio::detail::throw_error(ec, "accept"); 1047 } 1048 1049 /// Accept a new connection and obtain the endpoint of the peer 1050 /** 1051 * This function is used to accept a new connection from a peer into the 1052 * given socket, and additionally provide the endpoint of the remote peer. 1053 * The function call will block until a new connection has been accepted 1054 * successfully or an error occurs. 1055 * 1056 * @param peer The socket into which the new connection will be accepted. 1057 * 1058 * @param peer_endpoint An endpoint object which will receive the endpoint of 1059 * the remote peer. 1060 * 1061 * @param ec Set to indicate what error occurred, if any. 1062 * 1063 * @par Example 1064 * @code 1065 * asio::ip::tcp::acceptor acceptor(io_service); 1066 * ... 1067 * asio::ip::tcp::socket socket(io_service); 1068 * asio::ip::tcp::endpoint endpoint; 1069 * asio::error_code ec; 1070 * acceptor.accept(socket, endpoint, ec); 1071 * if (ec) 1072 * { 1073 * // An error occurred. 1074 * } 1075 * @endcode 1076 */ 1077 template <typename SocketService> accept(basic_socket<protocol_type,SocketService> & peer,endpoint_type & peer_endpoint,asio::error_code & ec)1078 asio::error_code accept( 1079 basic_socket<protocol_type, SocketService>& peer, 1080 endpoint_type& peer_endpoint, asio::error_code& ec) 1081 { 1082 return this->get_service().accept( 1083 this->get_implementation(), peer, &peer_endpoint, ec); 1084 } 1085 1086 /// Start an asynchronous accept. 1087 /** 1088 * This function is used to asynchronously accept a new connection into a 1089 * socket, and additionally obtain the endpoint of the remote peer. The 1090 * function call always returns immediately. 1091 * 1092 * @param peer The socket into which the new connection will be accepted. 1093 * Ownership of the peer object is retained by the caller, which must 1094 * guarantee that it is valid until the handler is called. 1095 * 1096 * @param peer_endpoint An endpoint object into which the endpoint of the 1097 * remote peer will be written. Ownership of the peer_endpoint object is 1098 * retained by the caller, which must guarantee that it is valid until the 1099 * handler is called. 1100 * 1101 * @param handler The handler to be called when the accept operation 1102 * completes. Copies will be made of the handler as required. The function 1103 * signature of the handler must be: 1104 * @code void handler( 1105 * const asio::error_code& error // Result of operation. 1106 * ); @endcode 1107 * Regardless of whether the asynchronous operation completes immediately or 1108 * not, the handler will not be invoked from within this function. Invocation 1109 * of the handler will be performed in a manner equivalent to using 1110 * asio::io_service::post(). 1111 */ 1112 template <typename SocketService, typename AcceptHandler> ASIO_INITFN_RESULT_TYPE(AcceptHandler,void (asio::error_code))1113 ASIO_INITFN_RESULT_TYPE(AcceptHandler, 1114 void (asio::error_code)) 1115 async_accept(basic_socket<protocol_type, SocketService>& peer, 1116 endpoint_type& peer_endpoint, ASIO_MOVE_ARG(AcceptHandler) handler) 1117 { 1118 // If you get an error on the following line it means that your handler does 1119 // not meet the documented type requirements for a AcceptHandler. 1120 ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; 1121 1122 return this->get_service().async_accept(this->get_implementation(), peer, 1123 &peer_endpoint, ASIO_MOVE_CAST(AcceptHandler)(handler)); 1124 } 1125 }; 1126 1127 } // namespace asio 1128 1129 #include "asio/detail/pop_options.hpp" 1130 1131 #endif // ASIO_BASIC_SOCKET_ACCEPTOR_HPP 1132