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