Home | History | Annotate | Download | only in asio
      1 //
      2 // basic_socket.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_HPP
     12 #define ASIO_BASIC_SOCKET_HPP
     13 
     14 
     15 #include "asio/detail/config.hpp"
     16 #include "asio/async_result.hpp"
     17 #include "asio/basic_io_object.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_base.hpp"
     23 
     24 #include "asio/detail/push_options.hpp"
     25 
     26 namespace asio {
     27 
     28 /// Provides socket functionality.
     29 /**
     30  * The basic_socket class template provides functionality that is common to both
     31  * stream-oriented and datagram-oriented sockets.
     32  *
     33  * @par Thread Safety
     34  * @e Distinct @e objects: Safe.@n
     35  * @e Shared @e objects: Unsafe.
     36  */
     37 template <typename Protocol, typename SocketService>
     38 class basic_socket
     39   : public basic_io_object<SocketService>,
     40     public socket_base
     41 {
     42 public:
     43   /// (Deprecated: Use native_handle_type.) The native representation of a
     44   /// socket.
     45   typedef typename SocketService::native_handle_type native_type;
     46 
     47   /// The native representation of a socket.
     48   typedef typename SocketService::native_handle_type native_handle_type;
     49 
     50   /// The protocol type.
     51   typedef Protocol protocol_type;
     52 
     53   /// The endpoint type.
     54   typedef typename Protocol::endpoint endpoint_type;
     55 
     56   /// A basic_socket is always the lowest layer.
     57   typedef basic_socket<Protocol, SocketService> lowest_layer_type;
     58 
     59   /// Construct a basic_socket without opening it.
     60   /**
     61    * This constructor creates a socket without opening it.
     62    *
     63    * @param io_service The io_service object that the socket will use to
     64    * dispatch handlers for any asynchronous operations performed on the socket.
     65    */
     66   explicit basic_socket(asio::io_service& io_service)
     67     : basic_io_object<SocketService>(io_service)
     68   {
     69   }
     70 
     71   /// Construct and open a basic_socket.
     72   /**
     73    * This constructor creates and opens a socket.
     74    *
     75    * @param io_service The io_service object that the socket will use to
     76    * dispatch handlers for any asynchronous operations performed on the socket.
     77    *
     78    * @param protocol An object specifying protocol parameters to be used.
     79    *
     80    * @throws asio::system_error Thrown on failure.
     81    */
     82   basic_socket(asio::io_service& io_service,
     83       const protocol_type& protocol)
     84     : basic_io_object<SocketService>(io_service)
     85   {
     86     asio::error_code ec;
     87     this->get_service().open(this->get_implementation(), protocol, ec);
     88     asio::detail::throw_error(ec, "open");
     89   }
     90 
     91   /// Construct a basic_socket, opening it and binding it to the given local
     92   /// endpoint.
     93   /**
     94    * This constructor creates a socket and automatically opens it bound to the
     95    * specified endpoint on the local machine. The protocol used is the protocol
     96    * associated with the given endpoint.
     97    *
     98    * @param io_service The io_service object that the socket will use to
     99    * dispatch handlers for any asynchronous operations performed on the socket.
    100    *
    101    * @param endpoint An endpoint on the local machine to which the socket will
    102    * be bound.
    103    *
    104    * @throws asio::system_error Thrown on failure.
    105    */
    106   basic_socket(asio::io_service& io_service,
    107       const endpoint_type& endpoint)
    108     : basic_io_object<SocketService>(io_service)
    109   {
    110     asio::error_code ec;
    111     const protocol_type protocol = endpoint.protocol();
    112     this->get_service().open(this->get_implementation(), protocol, ec);
    113     asio::detail::throw_error(ec, "open");
    114     this->get_service().bind(this->get_implementation(), endpoint, ec);
    115     asio::detail::throw_error(ec, "bind");
    116   }
    117 
    118   /// Construct a basic_socket on an existing native socket.
    119   /**
    120    * This constructor creates a socket object to hold an existing native socket.
    121    *
    122    * @param io_service The io_service object that the socket will use to
    123    * dispatch handlers for any asynchronous operations performed on the socket.
    124    *
    125    * @param protocol An object specifying protocol parameters to be used.
    126    *
    127    * @param native_socket A native socket.
    128    *
    129    * @throws asio::system_error Thrown on failure.
    130    */
    131   basic_socket(asio::io_service& io_service,
    132       const protocol_type& protocol, const native_handle_type& native_socket)
    133     : basic_io_object<SocketService>(io_service)
    134   {
    135     asio::error_code ec;
    136     this->get_service().assign(this->get_implementation(),
    137         protocol, native_socket, ec);
    138     asio::detail::throw_error(ec, "assign");
    139   }
    140 
    141   /// Move-construct a basic_socket from another.
    142   /**
    143    * This constructor moves a socket from one object to another.
    144    *
    145    * @param other The other basic_socket object from which the move will
    146    * occur.
    147    *
    148    * @note Following the move, the moved-from object is in the same state as if
    149    * constructed using the @c basic_socket(io_service&) constructor.
    150    */
    151   basic_socket(basic_socket&& other)
    152     : basic_io_object<SocketService>(
    153         ASIO_MOVE_CAST(basic_socket)(other))
    154   {
    155   }
    156 
    157   /// Move-assign a basic_socket from another.
    158   /**
    159    * This assignment operator moves a socket from one object to another.
    160    *
    161    * @param other The other basic_socket object from which the move will
    162    * occur.
    163    *
    164    * @note Following the move, the moved-from object is in the same state as if
    165    * constructed using the @c basic_socket(io_service&) constructor.
    166    */
    167   basic_socket& operator=(basic_socket&& other)
    168   {
    169     basic_io_object<SocketService>::operator=(
    170         ASIO_MOVE_CAST(basic_socket)(other));
    171     return *this;
    172   }
    173 
    174   // All sockets have access to each other's implementations.
    175   template <typename Protocol1, typename SocketService1>
    176   friend class basic_socket;
    177 
    178   /// Move-construct a basic_socket from a socket of another protocol type.
    179   /**
    180    * This constructor moves a socket from one object to another.
    181    *
    182    * @param other The other basic_socket object from which the move will
    183    * 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(io_service&) constructor.
    187    */
    188   template <typename Protocol1, typename SocketService1>
    189   basic_socket(basic_socket<Protocol1, SocketService1>&& other,
    190       typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
    191     : basic_io_object<SocketService>(other.get_io_service())
    192   {
    193     this->get_service().template converting_move_construct<Protocol1>(
    194         this->get_implementation(), other.get_implementation());
    195   }
    196 
    197   /// Move-assign a basic_socket from a socket of another protocol type.
    198   /**
    199    * This assignment operator moves a socket from one object to another.
    200    *
    201    * @param other The other basic_socket object from which the move will
    202    * occur.
    203    *
    204    * @note Following the move, the moved-from object is in the same state as if
    205    * constructed using the @c basic_socket(io_service&) constructor.
    206    */
    207   template <typename Protocol1, typename SocketService1>
    208   typename enable_if<is_convertible<Protocol1, Protocol>::value,
    209       basic_socket>::type& operator=(
    210         basic_socket<Protocol1, SocketService1>&& other)
    211   {
    212     basic_socket tmp(ASIO_MOVE_CAST2(basic_socket<
    213             Protocol1, SocketService1>)(other));
    214     basic_io_object<SocketService>::operator=(
    215         ASIO_MOVE_CAST(basic_socket)(tmp));
    216     return *this;
    217   }
    218 
    219   /// Get a reference to the lowest layer.
    220   /**
    221    * This function returns a reference to the lowest layer in a stack of
    222    * layers. Since a basic_socket cannot contain any further layers, it simply
    223    * returns a reference to itself.
    224    *
    225    * @return A reference to the lowest layer in the stack of layers. Ownership
    226    * is not transferred to the caller.
    227    */
    228   lowest_layer_type& lowest_layer()
    229   {
    230     return *this;
    231   }
    232 
    233   /// Get a const reference to the lowest layer.
    234   /**
    235    * This function returns a const reference to the lowest layer in a stack of
    236    * layers. Since a basic_socket cannot contain any further layers, it simply
    237    * returns a reference to itself.
    238    *
    239    * @return A const reference to the lowest layer in the stack of layers.
    240    * Ownership is not transferred to the caller.
    241    */
    242   const lowest_layer_type& lowest_layer() const
    243   {
    244     return *this;
    245   }
    246 
    247   /// Open the socket using the specified protocol.
    248   /**
    249    * This function opens the socket so that it will use the specified protocol.
    250    *
    251    * @param protocol An object specifying protocol parameters to be used.
    252    *
    253    * @throws asio::system_error Thrown on failure.
    254    *
    255    * @par Example
    256    * @code
    257    * asio::ip::tcp::socket socket(io_service);
    258    * socket.open(asio::ip::tcp::v4());
    259    * @endcode
    260    */
    261   void open(const protocol_type& protocol = protocol_type())
    262   {
    263     asio::error_code ec;
    264     this->get_service().open(this->get_implementation(), protocol, ec);
    265     asio::detail::throw_error(ec, "open");
    266   }
    267 
    268   /// Open the socket using the specified protocol.
    269   /**
    270    * This function opens the socket so that it will use the specified protocol.
    271    *
    272    * @param protocol An object specifying which protocol is to be used.
    273    *
    274    * @param ec Set to indicate what error occurred, if any.
    275    *
    276    * @par Example
    277    * @code
    278    * asio::ip::tcp::socket socket(io_service);
    279    * asio::error_code ec;
    280    * socket.open(asio::ip::tcp::v4(), ec);
    281    * if (ec)
    282    * {
    283    *   // An error occurred.
    284    * }
    285    * @endcode
    286    */
    287   asio::error_code open(const protocol_type& protocol,
    288       asio::error_code& ec)
    289   {
    290     return this->get_service().open(this->get_implementation(), protocol, ec);
    291   }
    292 
    293   /// Assign an existing native socket to the socket.
    294   /*
    295    * This function opens the socket to hold an existing native socket.
    296    *
    297    * @param protocol An object specifying which protocol is to be used.
    298    *
    299    * @param native_socket A native socket.
    300    *
    301    * @throws asio::system_error Thrown on failure.
    302    */
    303   void assign(const protocol_type& protocol,
    304       const native_handle_type& native_socket)
    305   {
    306     asio::error_code ec;
    307     this->get_service().assign(this->get_implementation(),
    308         protocol, native_socket, ec);
    309     asio::detail::throw_error(ec, "assign");
    310   }
    311 
    312   /// Assign an existing native socket to the socket.
    313   /*
    314    * This function opens the socket to hold an existing native socket.
    315    *
    316    * @param protocol An object specifying which protocol is to be used.
    317    *
    318    * @param native_socket A native socket.
    319    *
    320    * @param ec Set to indicate what error occurred, if any.
    321    */
    322   asio::error_code assign(const protocol_type& protocol,
    323       const native_handle_type& native_socket, asio::error_code& ec)
    324   {
    325     return this->get_service().assign(this->get_implementation(),
    326         protocol, native_socket, ec);
    327   }
    328 
    329   /// Determine whether the socket is open.
    330   bool is_open() const
    331   {
    332     return this->get_service().is_open(this->get_implementation());
    333   }
    334 
    335   /// Close the socket.
    336   /**
    337    * This function is used to close the socket. Any asynchronous send, receive
    338    * or connect operations will be cancelled immediately, and will complete
    339    * with the asio::error::operation_aborted error.
    340    *
    341    * @throws asio::system_error Thrown on failure. Note that, even if
    342    * the function indicates an error, the underlying descriptor is closed.
    343    *
    344    * @note For portable behaviour with respect to graceful closure of a
    345    * connected socket, call shutdown() before closing the socket.
    346    */
    347   void close()
    348   {
    349     asio::error_code ec;
    350     this->get_service().close(this->get_implementation(), ec);
    351     asio::detail::throw_error(ec, "close");
    352   }
    353 
    354   /// Close the socket.
    355   /**
    356    * This function is used to close the socket. Any asynchronous send, receive
    357    * or connect operations will be cancelled immediately, and will complete
    358    * with the asio::error::operation_aborted error.
    359    *
    360    * @param ec Set to indicate what error occurred, if any. Note that, even if
    361    * the function indicates an error, the underlying descriptor is closed.
    362    *
    363    * @par Example
    364    * @code
    365    * asio::ip::tcp::socket socket(io_service);
    366    * ...
    367    * asio::error_code ec;
    368    * socket.close(ec);
    369    * if (ec)
    370    * {
    371    *   // An error occurred.
    372    * }
    373    * @endcode
    374    *
    375    * @note For portable behaviour with respect to graceful closure of a
    376    * connected socket, call shutdown() before closing the socket.
    377    */
    378   asio::error_code close(asio::error_code& ec)
    379   {
    380     return this->get_service().close(this->get_implementation(), ec);
    381   }
    382 
    383   /// (Deprecated: Use native_handle().) Get the native socket representation.
    384   /**
    385    * This function may be used to obtain the underlying representation of the
    386    * socket. This is intended to allow access to native socket functionality
    387    * that is not otherwise provided.
    388    */
    389   native_type native()
    390   {
    391     return this->get_service().native_handle(this->get_implementation());
    392   }
    393 
    394   /// Get the native socket representation.
    395   /**
    396    * This function may be used to obtain the underlying representation of the
    397    * socket. This is intended to allow access to native socket functionality
    398    * that is not otherwise provided.
    399    */
    400   native_handle_type native_handle()
    401   {
    402     return this->get_service().native_handle(this->get_implementation());
    403   }
    404 
    405   /// Cancel all asynchronous operations associated with the socket.
    406   /**
    407    * This function causes all outstanding asynchronous connect, send and receive
    408    * operations to finish immediately, and the handlers for cancelled operations
    409    * will be passed the asio::error::operation_aborted error.
    410    *
    411    * @throws asio::system_error Thrown on failure.
    412    *
    413    * @note Calls to cancel() will always fail with
    414    * asio::error::operation_not_supported when run on Windows XP, Windows
    415    * Server 2003, and earlier versions of Windows, unless
    416    * ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has
    417    * two issues that should be considered before enabling its use:
    418    *
    419    * @li It will only cancel asynchronous operations that were initiated in the
    420    * current thread.
    421    *
    422    * @li It can appear to complete without error, but the request to cancel the
    423    * unfinished operations may be silently ignored by the operating system.
    424    * Whether it works or not seems to depend on the drivers that are installed.
    425    *
    426    * For portable cancellation, consider using one of the following
    427    * alternatives:
    428    *
    429    * @li Disable asio's I/O completion port backend by defining
    430    * ASIO_DISABLE_IOCP.
    431    *
    432    * @li Use the close() function to simultaneously cancel the outstanding
    433    * operations and close the socket.
    434    *
    435    * When running on Windows Vista, Windows Server 2008, and later, the
    436    * CancelIoEx function is always used. This function does not have the
    437    * problems described above.
    438    */
    439   void cancel()
    440   {
    441     asio::error_code ec;
    442     this->get_service().cancel(this->get_implementation(), ec);
    443     asio::detail::throw_error(ec, "cancel");
    444   }
    445 
    446   /// Cancel all asynchronous operations associated with the socket.
    447   /**
    448    * This function causes all outstanding asynchronous connect, send and receive
    449    * operations to finish immediately, and the handlers for cancelled operations
    450    * will be passed the asio::error::operation_aborted error.
    451    *
    452    * @param ec Set to indicate what error occurred, if any.
    453    *
    454    * @note Calls to cancel() will always fail with
    455    * asio::error::operation_not_supported when run on Windows XP, Windows
    456    * Server 2003, and earlier versions of Windows, unless
    457    * ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has
    458    * two issues that should be considered before enabling its use:
    459    *
    460    * @li It will only cancel asynchronous operations that were initiated in the
    461    * current thread.
    462    *
    463    * @li It can appear to complete without error, but the request to cancel the
    464    * unfinished operations may be silently ignored by the operating system.
    465    * Whether it works or not seems to depend on the drivers that are installed.
    466    *
    467    * For portable cancellation, consider using one of the following
    468    * alternatives:
    469    *
    470    * @li Disable asio's I/O completion port backend by defining
    471    * ASIO_DISABLE_IOCP.
    472    *
    473    * @li Use the close() function to simultaneously cancel the outstanding
    474    * operations and close the socket.
    475    *
    476    * When running on Windows Vista, Windows Server 2008, and later, the
    477    * CancelIoEx function is always used. This function does not have the
    478    * problems described above.
    479    */
    480   asio::error_code cancel(asio::error_code& ec)
    481   {
    482     return this->get_service().cancel(this->get_implementation(), ec);
    483   }
    484 
    485   /// Determine whether the socket is at the out-of-band data mark.
    486   /**
    487    * This function is used to check whether the socket input is currently
    488    * positioned at the out-of-band data mark.
    489    *
    490    * @return A bool indicating whether the socket is at the out-of-band data
    491    * mark.
    492    *
    493    * @throws asio::system_error Thrown on failure.
    494    */
    495   bool at_mark() const
    496   {
    497     asio::error_code ec;
    498     bool b = this->get_service().at_mark(this->get_implementation(), ec);
    499     asio::detail::throw_error(ec, "at_mark");
    500     return b;
    501   }
    502 
    503   /// Determine whether the socket is at the out-of-band data mark.
    504   /**
    505    * This function is used to check whether the socket input is currently
    506    * positioned at the out-of-band data mark.
    507    *
    508    * @param ec Set to indicate what error occurred, if any.
    509    *
    510    * @return A bool indicating whether the socket is at the out-of-band data
    511    * mark.
    512    */
    513   bool at_mark(asio::error_code& ec) const
    514   {
    515     return this->get_service().at_mark(this->get_implementation(), ec);
    516   }
    517 
    518   /// Determine the number of bytes available for reading.
    519   /**
    520    * This function is used to determine the number of bytes that may be read
    521    * without blocking.
    522    *
    523    * @return The number of bytes that may be read without blocking, or 0 if an
    524    * error occurs.
    525    *
    526    * @throws asio::system_error Thrown on failure.
    527    */
    528   std::size_t available() const
    529   {
    530     asio::error_code ec;
    531     std::size_t s = this->get_service().available(
    532         this->get_implementation(), ec);
    533     asio::detail::throw_error(ec, "available");
    534     return s;
    535   }
    536 
    537   /// Determine the number of bytes available for reading.
    538   /**
    539    * This function is used to determine the number of bytes that may be read
    540    * without blocking.
    541    *
    542    * @param ec Set to indicate what error occurred, if any.
    543    *
    544    * @return The number of bytes that may be read without blocking, or 0 if an
    545    * error occurs.
    546    */
    547   std::size_t available(asio::error_code& ec) const
    548   {
    549     return this->get_service().available(this->get_implementation(), ec);
    550   }
    551 
    552   /// Bind the socket to the given local endpoint.
    553   /**
    554    * This function binds the socket to the specified endpoint on the local
    555    * machine.
    556    *
    557    * @param endpoint An endpoint on the local machine to which the socket will
    558    * be bound.
    559    *
    560    * @throws asio::system_error Thrown on failure.
    561    *
    562    * @par Example
    563    * @code
    564    * asio::ip::tcp::socket socket(io_service);
    565    * socket.open(asio::ip::tcp::v4());
    566    * socket.bind(asio::ip::tcp::endpoint(
    567    *       asio::ip::tcp::v4(), 12345));
    568    * @endcode
    569    */
    570   void bind(const endpoint_type& endpoint)
    571   {
    572     asio::error_code ec;
    573     this->get_service().bind(this->get_implementation(), endpoint, ec);
    574     asio::detail::throw_error(ec, "bind");
    575   }
    576 
    577   /// Bind the socket to the given local endpoint.
    578   /**
    579    * This function binds the socket to the specified endpoint on the local
    580    * machine.
    581    *
    582    * @param endpoint An endpoint on the local machine to which the socket will
    583    * be bound.
    584    *
    585    * @param ec Set to indicate what error occurred, if any.
    586    *
    587    * @par Example
    588    * @code
    589    * asio::ip::tcp::socket socket(io_service);
    590    * socket.open(asio::ip::tcp::v4());
    591    * asio::error_code ec;
    592    * socket.bind(asio::ip::tcp::endpoint(
    593    *       asio::ip::tcp::v4(), 12345), ec);
    594    * if (ec)
    595    * {
    596    *   // An error occurred.
    597    * }
    598    * @endcode
    599    */
    600   asio::error_code bind(const endpoint_type& endpoint,
    601       asio::error_code& ec)
    602   {
    603     return this->get_service().bind(this->get_implementation(), endpoint, ec);
    604   }
    605 
    606   /// Connect the socket to the specified endpoint.
    607   /**
    608    * This function is used to connect a socket to the specified remote endpoint.
    609    * The function call will block until the connection is successfully made or
    610    * an error occurs.
    611    *
    612    * The socket is automatically opened if it is not already open. If the
    613    * connect fails, and the socket was automatically opened, the socket is
    614    * not returned to the closed state.
    615    *
    616    * @param peer_endpoint The remote endpoint to which the socket will be
    617    * connected.
    618    *
    619    * @throws asio::system_error Thrown on failure.
    620    *
    621    * @par Example
    622    * @code
    623    * asio::ip::tcp::socket socket(io_service);
    624    * asio::ip::tcp::endpoint endpoint(
    625    *     asio::ip::address::from_string("1.2.3.4"), 12345);
    626    * socket.connect(endpoint);
    627    * @endcode
    628    */
    629   void connect(const endpoint_type& peer_endpoint)
    630   {
    631     asio::error_code ec;
    632     if (!is_open())
    633     {
    634       this->get_service().open(this->get_implementation(),
    635           peer_endpoint.protocol(), ec);
    636       asio::detail::throw_error(ec, "connect");
    637     }
    638     this->get_service().connect(this->get_implementation(), peer_endpoint, ec);
    639     asio::detail::throw_error(ec, "connect");
    640   }
    641 
    642   /// Connect the socket to the specified endpoint.
    643   /**
    644    * This function is used to connect a socket to the specified remote endpoint.
    645    * The function call will block until the connection is successfully made or
    646    * an error occurs.
    647    *
    648    * The socket is automatically opened if it is not already open. If the
    649    * connect fails, and the socket was automatically opened, the socket is
    650    * not returned to the closed state.
    651    *
    652    * @param peer_endpoint The remote endpoint to which the socket will be
    653    * connected.
    654    *
    655    * @param ec Set to indicate what error occurred, if any.
    656    *
    657    * @par Example
    658    * @code
    659    * asio::ip::tcp::socket socket(io_service);
    660    * asio::ip::tcp::endpoint endpoint(
    661    *     asio::ip::address::from_string("1.2.3.4"), 12345);
    662    * asio::error_code ec;
    663    * socket.connect(endpoint, ec);
    664    * if (ec)
    665    * {
    666    *   // An error occurred.
    667    * }
    668    * @endcode
    669    */
    670   asio::error_code connect(const endpoint_type& peer_endpoint,
    671       asio::error_code& ec)
    672   {
    673     if (!is_open())
    674     {
    675       if (this->get_service().open(this->get_implementation(),
    676             peer_endpoint.protocol(), ec))
    677       {
    678         return ec;
    679       }
    680     }
    681 
    682     return this->get_service().connect(
    683         this->get_implementation(), peer_endpoint, ec);
    684   }
    685 
    686   /// Start an asynchronous connect.
    687   /**
    688    * This function is used to asynchronously connect a socket to the specified
    689    * remote endpoint. The function call always returns immediately.
    690    *
    691    * The socket is automatically opened if it is not already open. If the
    692    * connect fails, and the socket was automatically opened, the socket is
    693    * not returned to the closed state.
    694    *
    695    * @param peer_endpoint The remote endpoint to which the socket will be
    696    * connected. Copies will be made of the endpoint object as required.
    697    *
    698    * @param handler The handler to be called when the connection operation
    699    * completes. Copies will be made of the handler as required. The function
    700    * signature of the handler must be:
    701    * @code void handler(
    702    *   const asio::error_code& error // Result of operation
    703    * ); @endcode
    704    * Regardless of whether the asynchronous operation completes immediately or
    705    * not, the handler will not be invoked from within this function. Invocation
    706    * of the handler will be performed in a manner equivalent to using
    707    * asio::io_service::post().
    708    *
    709    * @par Example
    710    * @code
    711    * void connect_handler(const asio::error_code& error)
    712    * {
    713    *   if (!error)
    714    *   {
    715    *     // Connect succeeded.
    716    *   }
    717    * }
    718    *
    719    * ...
    720    *
    721    * asio::ip::tcp::socket socket(io_service);
    722    * asio::ip::tcp::endpoint endpoint(
    723    *     asio::ip::address::from_string("1.2.3.4"), 12345);
    724    * socket.async_connect(endpoint, connect_handler);
    725    * @endcode
    726    */
    727   template <typename ConnectHandler>
    728   ASIO_INITFN_RESULT_TYPE(ConnectHandler,
    729       void (asio::error_code))
    730   async_connect(const endpoint_type& peer_endpoint,
    731       ASIO_MOVE_ARG(ConnectHandler) handler)
    732   {
    733     // If you get an error on the following line it means that your handler does
    734     // not meet the documented type requirements for a ConnectHandler.
    735     ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check;
    736 
    737     if (!is_open())
    738     {
    739       asio::error_code ec;
    740       const protocol_type protocol = peer_endpoint.protocol();
    741       if (this->get_service().open(this->get_implementation(), protocol, ec))
    742       {
    743         detail::async_result_init<
    744           ConnectHandler, void (asio::error_code)> init(
    745             ASIO_MOVE_CAST(ConnectHandler)(handler));
    746 
    747         this->get_io_service().post(
    748             asio::detail::bind_handler(
    749               ASIO_MOVE_CAST(ASIO_HANDLER_TYPE(
    750                 ConnectHandler, void (asio::error_code)))(
    751                   init.handler), ec));
    752 
    753         return init.result.get();
    754       }
    755     }
    756 
    757     return this->get_service().async_connect(this->get_implementation(),
    758         peer_endpoint, ASIO_MOVE_CAST(ConnectHandler)(handler));
    759   }
    760 
    761   /// Set an option on the socket.
    762   /**
    763    * This function is used to set an option on the socket.
    764    *
    765    * @param option The new option value to be set on the socket.
    766    *
    767    * @throws asio::system_error Thrown on failure.
    768    *
    769    * @sa SettableSocketOption @n
    770    * asio::socket_base::broadcast @n
    771    * asio::socket_base::do_not_route @n
    772    * asio::socket_base::keep_alive @n
    773    * asio::socket_base::linger @n
    774    * asio::socket_base::receive_buffer_size @n
    775    * asio::socket_base::receive_low_watermark @n
    776    * asio::socket_base::reuse_address @n
    777    * asio::socket_base::send_buffer_size @n
    778    * asio::socket_base::send_low_watermark @n
    779    * asio::ip::multicast::join_group @n
    780    * asio::ip::multicast::leave_group @n
    781    * asio::ip::multicast::enable_loopback @n
    782    * asio::ip::multicast::outbound_interface @n
    783    * asio::ip::multicast::hops @n
    784    * asio::ip::tcp::no_delay
    785    *
    786    * @par Example
    787    * Setting the IPPROTO_TCP/TCP_NODELAY option:
    788    * @code
    789    * asio::ip::tcp::socket socket(io_service);
    790    * ...
    791    * asio::ip::tcp::no_delay option(true);
    792    * socket.set_option(option);
    793    * @endcode
    794    */
    795   template <typename SettableSocketOption>
    796   void set_option(const SettableSocketOption& option)
    797   {
    798     asio::error_code ec;
    799     this->get_service().set_option(this->get_implementation(), option, ec);
    800     asio::detail::throw_error(ec, "set_option");
    801   }
    802 
    803   /// Set an option on the socket.
    804   /**
    805    * This function is used to set an option on the socket.
    806    *
    807    * @param option The new option value to be set on the socket.
    808    *
    809    * @param ec Set to indicate what error occurred, if any.
    810    *
    811    * @sa SettableSocketOption @n
    812    * asio::socket_base::broadcast @n
    813    * asio::socket_base::do_not_route @n
    814    * asio::socket_base::keep_alive @n
    815    * asio::socket_base::linger @n
    816    * asio::socket_base::receive_buffer_size @n
    817    * asio::socket_base::receive_low_watermark @n
    818    * asio::socket_base::reuse_address @n
    819    * asio::socket_base::send_buffer_size @n
    820    * asio::socket_base::send_low_watermark @n
    821    * asio::ip::multicast::join_group @n
    822    * asio::ip::multicast::leave_group @n
    823    * asio::ip::multicast::enable_loopback @n
    824    * asio::ip::multicast::outbound_interface @n
    825    * asio::ip::multicast::hops @n
    826    * asio::ip::tcp::no_delay
    827    *
    828    * @par Example
    829    * Setting the IPPROTO_TCP/TCP_NODELAY option:
    830    * @code
    831    * asio::ip::tcp::socket socket(io_service);
    832    * ...
    833    * asio::ip::tcp::no_delay option(true);
    834    * asio::error_code ec;
    835    * socket.set_option(option, ec);
    836    * if (ec)
    837    * {
    838    *   // An error occurred.
    839    * }
    840    * @endcode
    841    */
    842   template <typename SettableSocketOption>
    843   asio::error_code set_option(const SettableSocketOption& option,
    844       asio::error_code& ec)
    845   {
    846     return this->get_service().set_option(
    847         this->get_implementation(), option, ec);
    848   }
    849 
    850   /// Get an option from the socket.
    851   /**
    852    * This function is used to get the current value of an option on the socket.
    853    *
    854    * @param option The option value to be obtained from the socket.
    855    *
    856    * @throws asio::system_error Thrown on failure.
    857    *
    858    * @sa GettableSocketOption @n
    859    * asio::socket_base::broadcast @n
    860    * asio::socket_base::do_not_route @n
    861    * asio::socket_base::keep_alive @n
    862    * asio::socket_base::linger @n
    863    * asio::socket_base::receive_buffer_size @n
    864    * asio::socket_base::receive_low_watermark @n
    865    * asio::socket_base::reuse_address @n
    866    * asio::socket_base::send_buffer_size @n
    867    * asio::socket_base::send_low_watermark @n
    868    * asio::ip::multicast::join_group @n
    869    * asio::ip::multicast::leave_group @n
    870    * asio::ip::multicast::enable_loopback @n
    871    * asio::ip::multicast::outbound_interface @n
    872    * asio::ip::multicast::hops @n
    873    * asio::ip::tcp::no_delay
    874    *
    875    * @par Example
    876    * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
    877    * @code
    878    * asio::ip::tcp::socket socket(io_service);
    879    * ...
    880    * asio::ip::tcp::socket::keep_alive option;
    881    * socket.get_option(option);
    882    * bool is_set = option.value();
    883    * @endcode
    884    */
    885   template <typename GettableSocketOption>
    886   void get_option(GettableSocketOption& option) const
    887   {
    888     asio::error_code ec;
    889     this->get_service().get_option(this->get_implementation(), option, ec);
    890     asio::detail::throw_error(ec, "get_option");
    891   }
    892 
    893   /// Get an option from the socket.
    894   /**
    895    * This function is used to get the current value of an option on the socket.
    896    *
    897    * @param option The option value to be obtained from the socket.
    898    *
    899    * @param ec Set to indicate what error occurred, if any.
    900    *
    901    * @sa GettableSocketOption @n
    902    * asio::socket_base::broadcast @n
    903    * asio::socket_base::do_not_route @n
    904    * asio::socket_base::keep_alive @n
    905    * asio::socket_base::linger @n
    906    * asio::socket_base::receive_buffer_size @n
    907    * asio::socket_base::receive_low_watermark @n
    908    * asio::socket_base::reuse_address @n
    909    * asio::socket_base::send_buffer_size @n
    910    * asio::socket_base::send_low_watermark @n
    911    * asio::ip::multicast::join_group @n
    912    * asio::ip::multicast::leave_group @n
    913    * asio::ip::multicast::enable_loopback @n
    914    * asio::ip::multicast::outbound_interface @n
    915    * asio::ip::multicast::hops @n
    916    * asio::ip::tcp::no_delay
    917    *
    918    * @par Example
    919    * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
    920    * @code
    921    * asio::ip::tcp::socket socket(io_service);
    922    * ...
    923    * asio::ip::tcp::socket::keep_alive option;
    924    * asio::error_code ec;
    925    * socket.get_option(option, ec);
    926    * if (ec)
    927    * {
    928    *   // An error occurred.
    929    * }
    930    * bool is_set = option.value();
    931    * @endcode
    932    */
    933   template <typename GettableSocketOption>
    934   asio::error_code get_option(GettableSocketOption& option,
    935       asio::error_code& ec) const
    936   {
    937     return this->get_service().get_option(
    938         this->get_implementation(), option, ec);
    939   }
    940 
    941   /// Perform an IO control command on the socket.
    942   /**
    943    * This function is used to execute an IO control command on the socket.
    944    *
    945    * @param command The IO control command to be performed on the socket.
    946    *
    947    * @throws asio::system_error Thrown on failure.
    948    *
    949    * @sa IoControlCommand @n
    950    * asio::socket_base::bytes_readable @n
    951    * asio::socket_base::non_blocking_io
    952    *
    953    * @par Example
    954    * Getting the number of bytes ready to read:
    955    * @code
    956    * asio::ip::tcp::socket socket(io_service);
    957    * ...
    958    * asio::ip::tcp::socket::bytes_readable command;
    959    * socket.io_control(command);
    960    * std::size_t bytes_readable = command.get();
    961    * @endcode
    962    */
    963   template <typename IoControlCommand>
    964   void io_control(IoControlCommand& command)
    965   {
    966     asio::error_code ec;
    967     this->get_service().io_control(this->get_implementation(), command, ec);
    968     asio::detail::throw_error(ec, "io_control");
    969   }
    970 
    971   /// Perform an IO control command on the socket.
    972   /**
    973    * This function is used to execute an IO control command on the socket.
    974    *
    975    * @param command The IO control command to be performed on the socket.
    976    *
    977    * @param ec Set to indicate what error occurred, if any.
    978    *
    979    * @sa IoControlCommand @n
    980    * asio::socket_base::bytes_readable @n
    981    * asio::socket_base::non_blocking_io
    982    *
    983    * @par Example
    984    * Getting the number of bytes ready to read:
    985    * @code
    986    * asio::ip::tcp::socket socket(io_service);
    987    * ...
    988    * asio::ip::tcp::socket::bytes_readable command;
    989    * asio::error_code ec;
    990    * socket.io_control(command, ec);
    991    * if (ec)
    992    * {
    993    *   // An error occurred.
    994    * }
    995    * std::size_t bytes_readable = command.get();
    996    * @endcode
    997    */
    998   template <typename IoControlCommand>
    999   asio::error_code io_control(IoControlCommand& command,
   1000       asio::error_code& ec)
   1001   {
   1002     return this->get_service().io_control(
   1003         this->get_implementation(), command, ec);
   1004   }
   1005 
   1006   /// Gets the non-blocking mode of the socket.
   1007   /**
   1008    * @returns @c true if the socket's synchronous operations will fail with
   1009    * asio::error::would_block if they are unable to perform the requested
   1010    * operation immediately. If @c false, synchronous operations will block
   1011    * until complete.
   1012    *
   1013    * @note The non-blocking mode has no effect on the behaviour of asynchronous
   1014    * operations. Asynchronous operations will never fail with the error
   1015    * asio::error::would_block.
   1016    */
   1017   bool non_blocking() const
   1018   {
   1019     return this->get_service().non_blocking(this->get_implementation());
   1020   }
   1021 
   1022   /// Sets the non-blocking mode of the socket.
   1023   /**
   1024    * @param mode If @c true, the socket's synchronous operations will fail with
   1025    * asio::error::would_block if they are unable to perform the requested
   1026    * operation immediately. If @c false, synchronous operations will block
   1027    * until complete.
   1028    *
   1029    * @throws asio::system_error Thrown on failure.
   1030    *
   1031    * @note The non-blocking mode has no effect on the behaviour of asynchronous
   1032    * operations. Asynchronous operations will never fail with the error
   1033    * asio::error::would_block.
   1034    */
   1035   void non_blocking(bool mode)
   1036   {
   1037     asio::error_code ec;
   1038     this->get_service().non_blocking(this->get_implementation(), mode, ec);
   1039     asio::detail::throw_error(ec, "non_blocking");
   1040   }
   1041 
   1042   /// Sets the non-blocking mode of the socket.
   1043   /**
   1044    * @param mode If @c true, the socket's synchronous operations will fail with
   1045    * asio::error::would_block if they are unable to perform the requested
   1046    * operation immediately. If @c false, synchronous operations will block
   1047    * until complete.
   1048    *
   1049    * @param ec Set to indicate what error occurred, if any.
   1050    *
   1051    * @note The non-blocking mode has no effect on the behaviour of asynchronous
   1052    * operations. Asynchronous operations will never fail with the error
   1053    * asio::error::would_block.
   1054    */
   1055   asio::error_code non_blocking(
   1056       bool mode, asio::error_code& ec)
   1057   {
   1058     return this->get_service().non_blocking(
   1059         this->get_implementation(), mode, ec);
   1060   }
   1061 
   1062   /// Gets the non-blocking mode of the native socket implementation.
   1063   /**
   1064    * This function is used to retrieve the non-blocking mode of the underlying
   1065    * native socket. This mode has no effect on the behaviour of the socket
   1066    * object's synchronous operations.
   1067    *
   1068    * @returns @c true if the underlying socket is in non-blocking mode and
   1069    * direct system calls may fail with asio::error::would_block (or the
   1070    * equivalent system error).
   1071    *
   1072    * @note The current non-blocking mode is cached by the socket object.
   1073    * Consequently, the return value may be incorrect if the non-blocking mode
   1074    * was set directly on the native socket.
   1075    *
   1076    * @par Example
   1077    * This function is intended to allow the encapsulation of arbitrary
   1078    * non-blocking system calls as asynchronous operations, in a way that is
   1079    * transparent to the user of the socket object. The following example
   1080    * illustrates how Linux's @c sendfile system call might be encapsulated:
   1081    * @code template <typename Handler>
   1082    * struct sendfile_op
   1083    * {
   1084    *   tcp::socket& sock_;
   1085    *   int fd_;
   1086    *   Handler handler_;
   1087    *   off_t offset_;
   1088    *   std::size_t total_bytes_transferred_;
   1089    *
   1090    *   // Function call operator meeting WriteHandler requirements.
   1091    *   // Used as the handler for the async_write_some operation.
   1092    *   void operator()(asio::error_code ec, std::size_t)
   1093    *   {
   1094    *     // Put the underlying socket into non-blocking mode.
   1095    *     if (!ec)
   1096    *       if (!sock_.native_non_blocking())
   1097    *         sock_.native_non_blocking(true, ec);
   1098    *
   1099    *     if (!ec)
   1100    *     {
   1101    *       for (;;)
   1102    *       {
   1103    *         // Try the system call.
   1104    *         errno = 0;
   1105    *         int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
   1106    *         ec = asio::error_code(n < 0 ? errno : 0,
   1107    *             asio::error::get_system_category());
   1108    *         total_bytes_transferred_ += ec ? 0 : n;
   1109    *
   1110    *         // Retry operation immediately if interrupted by signal.
   1111    *         if (ec == asio::error::interrupted)
   1112    *           continue;
   1113    *
   1114    *         // Check if we need to run the operation again.
   1115    *         if (ec == asio::error::would_block
   1116    *             || ec == asio::error::try_again)
   1117    *         {
   1118    *           // We have to wait for the socket to become ready again.
   1119    *           sock_.async_write_some(asio::null_buffers(), *this);
   1120    *           return;
   1121    *         }
   1122    *
   1123    *         if (ec || n == 0)
   1124    *         {
   1125    *           // An error occurred, or we have reached the end of the file.
   1126    *           // Either way we must exit the loop so we can call the handler.
   1127    *           break;
   1128    *         }
   1129    *
   1130    *         // Loop around to try calling sendfile again.
   1131    *       }
   1132    *     }
   1133    *
   1134    *     // Pass result back to user's handler.
   1135    *     handler_(ec, total_bytes_transferred_);
   1136    *   }
   1137    * };
   1138    *
   1139    * template <typename Handler>
   1140    * void async_sendfile(tcp::socket& sock, int fd, Handler h)
   1141    * {
   1142    *   sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
   1143    *   sock.async_write_some(asio::null_buffers(), op);
   1144    * } @endcode
   1145    */
   1146   bool native_non_blocking() const
   1147   {
   1148     return this->get_service().native_non_blocking(this->get_implementation());
   1149   }
   1150 
   1151   /// Sets the non-blocking mode of the native socket implementation.
   1152   /**
   1153    * This function is used to modify the non-blocking mode of the underlying
   1154    * native socket. It has no effect on the behaviour of the socket object's
   1155    * synchronous operations.
   1156    *
   1157    * @param mode If @c true, the underlying socket is put into non-blocking
   1158    * mode and direct system calls may fail with asio::error::would_block
   1159    * (or the equivalent system error).
   1160    *
   1161    * @throws asio::system_error Thrown on failure. If the @c mode is
   1162    * @c false, but the current value of @c non_blocking() is @c true, this
   1163    * function fails with asio::error::invalid_argument, as the
   1164    * combination does not make sense.
   1165    *
   1166    * @par Example
   1167    * This function is intended to allow the encapsulation of arbitrary
   1168    * non-blocking system calls as asynchronous operations, in a way that is
   1169    * transparent to the user of the socket object. The following example
   1170    * illustrates how Linux's @c sendfile system call might be encapsulated:
   1171    * @code template <typename Handler>
   1172    * struct sendfile_op
   1173    * {
   1174    *   tcp::socket& sock_;
   1175    *   int fd_;
   1176    *   Handler handler_;
   1177    *   off_t offset_;
   1178    *   std::size_t total_bytes_transferred_;
   1179    *
   1180    *   // Function call operator meeting WriteHandler requirements.
   1181    *   // Used as the handler for the async_write_some operation.
   1182    *   void operator()(asio::error_code ec, std::size_t)
   1183    *   {
   1184    *     // Put the underlying socket into non-blocking mode.
   1185    *     if (!ec)
   1186    *       if (!sock_.native_non_blocking())
   1187    *         sock_.native_non_blocking(true, ec);
   1188    *
   1189    *     if (!ec)
   1190    *     {
   1191    *       for (;;)
   1192    *       {
   1193    *         // Try the system call.
   1194    *         errno = 0;
   1195    *         int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
   1196    *         ec = asio::error_code(n < 0 ? errno : 0,
   1197    *             asio::error::get_system_category());
   1198    *         total_bytes_transferred_ += ec ? 0 : n;
   1199    *
   1200    *         // Retry operation immediately if interrupted by signal.
   1201    *         if (ec == asio::error::interrupted)
   1202    *           continue;
   1203    *
   1204    *         // Check if we need to run the operation again.
   1205    *         if (ec == asio::error::would_block
   1206    *             || ec == asio::error::try_again)
   1207    *         {
   1208    *           // We have to wait for the socket to become ready again.
   1209    *           sock_.async_write_some(asio::null_buffers(), *this);
   1210    *           return;
   1211    *         }
   1212    *
   1213    *         if (ec || n == 0)
   1214    *         {
   1215    *           // An error occurred, or we have reached the end of the file.
   1216    *           // Either way we must exit the loop so we can call the handler.
   1217    *           break;
   1218    *         }
   1219    *
   1220    *         // Loop around to try calling sendfile again.
   1221    *       }
   1222    *     }
   1223    *
   1224    *     // Pass result back to user's handler.
   1225    *     handler_(ec, total_bytes_transferred_);
   1226    *   }
   1227    * };
   1228    *
   1229    * template <typename Handler>
   1230    * void async_sendfile(tcp::socket& sock, int fd, Handler h)
   1231    * {
   1232    *   sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
   1233    *   sock.async_write_some(asio::null_buffers(), op);
   1234    * } @endcode
   1235    */
   1236   void native_non_blocking(bool mode)
   1237   {
   1238     asio::error_code ec;
   1239     this->get_service().native_non_blocking(
   1240         this->get_implementation(), mode, ec);
   1241     asio::detail::throw_error(ec, "native_non_blocking");
   1242   }
   1243 
   1244   /// Sets the non-blocking mode of the native socket implementation.
   1245   /**
   1246    * This function is used to modify the non-blocking mode of the underlying
   1247    * native socket. It has no effect on the behaviour of the socket object's
   1248    * synchronous operations.
   1249    *
   1250    * @param mode If @c true, the underlying socket is put into non-blocking
   1251    * mode and direct system calls may fail with asio::error::would_block
   1252    * (or the equivalent system error).
   1253    *
   1254    * @param ec Set to indicate what error occurred, if any. If the @c mode is
   1255    * @c false, but the current value of @c non_blocking() is @c true, this
   1256    * function fails with asio::error::invalid_argument, as the
   1257    * combination does not make sense.
   1258    *
   1259    * @par Example
   1260    * This function is intended to allow the encapsulation of arbitrary
   1261    * non-blocking system calls as asynchronous operations, in a way that is
   1262    * transparent to the user of the socket object. The following example
   1263    * illustrates how Linux's @c sendfile system call might be encapsulated:
   1264    * @code template <typename Handler>
   1265    * struct sendfile_op
   1266    * {
   1267    *   tcp::socket& sock_;
   1268    *   int fd_;
   1269    *   Handler handler_;
   1270    *   off_t offset_;
   1271    *   std::size_t total_bytes_transferred_;
   1272    *
   1273    *   // Function call operator meeting WriteHandler requirements.
   1274    *   // Used as the handler for the async_write_some operation.
   1275    *   void operator()(asio::error_code ec, std::size_t)
   1276    *   {
   1277    *     // Put the underlying socket into non-blocking mode.
   1278    *     if (!ec)
   1279    *       if (!sock_.native_non_blocking())
   1280    *         sock_.native_non_blocking(true, ec);
   1281    *
   1282    *     if (!ec)
   1283    *     {
   1284    *       for (;;)
   1285    *       {
   1286    *         // Try the system call.
   1287    *         errno = 0;
   1288    *         int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
   1289    *         ec = asio::error_code(n < 0 ? errno : 0,
   1290    *             asio::error::get_system_category());
   1291    *         total_bytes_transferred_ += ec ? 0 : n;
   1292    *
   1293    *         // Retry operation immediately if interrupted by signal.
   1294    *         if (ec == asio::error::interrupted)
   1295    *           continue;
   1296    *
   1297    *         // Check if we need to run the operation again.
   1298    *         if (ec == asio::error::would_block
   1299    *             || ec == asio::error::try_again)
   1300    *         {
   1301    *           // We have to wait for the socket to become ready again.
   1302    *           sock_.async_write_some(asio::null_buffers(), *this);
   1303    *           return;
   1304    *         }
   1305    *
   1306    *         if (ec || n == 0)
   1307    *         {
   1308    *           // An error occurred, or we have reached the end of the file.
   1309    *           // Either way we must exit the loop so we can call the handler.
   1310    *           break;
   1311    *         }
   1312    *
   1313    *         // Loop around to try calling sendfile again.
   1314    *       }
   1315    *     }
   1316    *
   1317    *     // Pass result back to user's handler.
   1318    *     handler_(ec, total_bytes_transferred_);
   1319    *   }
   1320    * };
   1321    *
   1322    * template <typename Handler>
   1323    * void async_sendfile(tcp::socket& sock, int fd, Handler h)
   1324    * {
   1325    *   sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
   1326    *   sock.async_write_some(asio::null_buffers(), op);
   1327    * } @endcode
   1328    */
   1329   asio::error_code native_non_blocking(
   1330       bool mode, asio::error_code& ec)
   1331   {
   1332     return this->get_service().native_non_blocking(
   1333         this->get_implementation(), mode, ec);
   1334   }
   1335 
   1336   /// Get the local endpoint of the socket.
   1337   /**
   1338    * This function is used to obtain the locally bound endpoint of the socket.
   1339    *
   1340    * @returns An object that represents the local endpoint of the socket.
   1341    *
   1342    * @throws asio::system_error Thrown on failure.
   1343    *
   1344    * @par Example
   1345    * @code
   1346    * asio::ip::tcp::socket socket(io_service);
   1347    * ...
   1348    * asio::ip::tcp::endpoint endpoint = socket.local_endpoint();
   1349    * @endcode
   1350    */
   1351   endpoint_type local_endpoint() const
   1352   {
   1353     asio::error_code ec;
   1354     endpoint_type ep = this->get_service().local_endpoint(
   1355         this->get_implementation(), ec);
   1356     asio::detail::throw_error(ec, "local_endpoint");
   1357     return ep;
   1358   }
   1359 
   1360   /// Get the local endpoint of the socket.
   1361   /**
   1362    * This function is used to obtain the locally bound endpoint of the socket.
   1363    *
   1364    * @param ec Set to indicate what error occurred, if any.
   1365    *
   1366    * @returns An object that represents the local endpoint of the socket.
   1367    * Returns a default-constructed endpoint object if an error occurred.
   1368    *
   1369    * @par Example
   1370    * @code
   1371    * asio::ip::tcp::socket socket(io_service);
   1372    * ...
   1373    * asio::error_code ec;
   1374    * asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec);
   1375    * if (ec)
   1376    * {
   1377    *   // An error occurred.
   1378    * }
   1379    * @endcode
   1380    */
   1381   endpoint_type local_endpoint(asio::error_code& ec) const
   1382   {
   1383     return this->get_service().local_endpoint(this->get_implementation(), ec);
   1384   }
   1385 
   1386   /// Get the remote endpoint of the socket.
   1387   /**
   1388    * This function is used to obtain the remote endpoint of the socket.
   1389    *
   1390    * @returns An object that represents the remote endpoint of the socket.
   1391    *
   1392    * @throws asio::system_error Thrown on failure.
   1393    *
   1394    * @par Example
   1395    * @code
   1396    * asio::ip::tcp::socket socket(io_service);
   1397    * ...
   1398    * asio::ip::tcp::endpoint endpoint = socket.remote_endpoint();
   1399    * @endcode
   1400    */
   1401   endpoint_type remote_endpoint() const
   1402   {
   1403     asio::error_code ec;
   1404     endpoint_type ep = this->get_service().remote_endpoint(
   1405         this->get_implementation(), ec);
   1406     asio::detail::throw_error(ec, "remote_endpoint");
   1407     return ep;
   1408   }
   1409 
   1410   /// Get the remote endpoint of the socket.
   1411   /**
   1412    * This function is used to obtain the remote endpoint of the socket.
   1413    *
   1414    * @param ec Set to indicate what error occurred, if any.
   1415    *
   1416    * @returns An object that represents the remote endpoint of the socket.
   1417    * Returns a default-constructed endpoint object if an error occurred.
   1418    *
   1419    * @par Example
   1420    * @code
   1421    * asio::ip::tcp::socket socket(io_service);
   1422    * ...
   1423    * asio::error_code ec;
   1424    * asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec);
   1425    * if (ec)
   1426    * {
   1427    *   // An error occurred.
   1428    * }
   1429    * @endcode
   1430    */
   1431   endpoint_type remote_endpoint(asio::error_code& ec) const
   1432   {
   1433     return this->get_service().remote_endpoint(this->get_implementation(), ec);
   1434   }
   1435 
   1436   /// Disable sends or receives on the socket.
   1437   /**
   1438    * This function is used to disable send operations, receive operations, or
   1439    * both.
   1440    *
   1441    * @param what Determines what types of operation will no longer be allowed.
   1442    *
   1443    * @throws asio::system_error Thrown on failure.
   1444    *
   1445    * @par Example
   1446    * Shutting down the send side of the socket:
   1447    * @code
   1448    * asio::ip::tcp::socket socket(io_service);
   1449    * ...
   1450    * socket.shutdown(asio::ip::tcp::socket::shutdown_send);
   1451    * @endcode
   1452    */
   1453   void shutdown(shutdown_type what)
   1454   {
   1455     asio::error_code ec;
   1456     this->get_service().shutdown(this->get_implementation(), what, ec);
   1457     asio::detail::throw_error(ec, "shutdown");
   1458   }
   1459 
   1460   /// Disable sends or receives on the socket.
   1461   /**
   1462    * This function is used to disable send operations, receive operations, or
   1463    * both.
   1464    *
   1465    * @param what Determines what types of operation will no longer be allowed.
   1466    *
   1467    * @param ec Set to indicate what error occurred, if any.
   1468    *
   1469    * @par Example
   1470    * Shutting down the send side of the socket:
   1471    * @code
   1472    * asio::ip::tcp::socket socket(io_service);
   1473    * ...
   1474    * asio::error_code ec;
   1475    * socket.shutdown(asio::ip::tcp::socket::shutdown_send, ec);
   1476    * if (ec)
   1477    * {
   1478    *   // An error occurred.
   1479    * }
   1480    * @endcode
   1481    */
   1482   asio::error_code shutdown(shutdown_type what,
   1483       asio::error_code& ec)
   1484   {
   1485     return this->get_service().shutdown(this->get_implementation(), what, ec);
   1486   }
   1487 
   1488 protected:
   1489   /// Protected destructor to prevent deletion through this type.
   1490   ~basic_socket()
   1491   {
   1492   }
   1493 };
   1494 
   1495 } // namespace asio
   1496 
   1497 #include "asio/detail/pop_options.hpp"
   1498 
   1499 #endif // ASIO_BASIC_SOCKET_HPP
   1500