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