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