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