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