| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896 | //// basic_socket.hpp// ~~~~~~~~~~~~~~~~//// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)//// Distributed under the Boost Software License, Version 1.0. (See accompanying// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)//#ifndef BOOST_ASIO_BASIC_SOCKET_HPP#define BOOST_ASIO_BASIC_SOCKET_HPP#if defined(_MSC_VER) && (_MSC_VER >= 1200)# pragma once#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)#include <boost/asio/detail/config.hpp>#include <boost/asio/async_result.hpp>#include <boost/asio/detail/handler_type_requirements.hpp>#include <boost/asio/detail/io_object_impl.hpp>#include <boost/asio/detail/non_const_lvalue.hpp>#include <boost/asio/detail/throw_error.hpp>#include <boost/asio/detail/type_traits.hpp>#include <boost/asio/error.hpp>#include <boost/asio/execution_context.hpp>#include <boost/asio/executor.hpp>#include <boost/asio/post.hpp>#include <boost/asio/socket_base.hpp>#if defined(BOOST_ASIO_WINDOWS_RUNTIME)# include <boost/asio/detail/null_socket_service.hpp>#elif defined(BOOST_ASIO_HAS_IOCP)# include <boost/asio/detail/win_iocp_socket_service.hpp>#else# include <boost/asio/detail/reactive_socket_service.hpp>#endif#if defined(BOOST_ASIO_HAS_MOVE)# include <utility>#endif // defined(BOOST_ASIO_HAS_MOVE)#include <boost/asio/detail/push_options.hpp>namespace boost {namespace asio {#if !defined(BOOST_ASIO_BASIC_SOCKET_FWD_DECL)#define BOOST_ASIO_BASIC_SOCKET_FWD_DECL// Forward declaration with defaulted arguments.template <typename Protocol, typename Executor = executor>class basic_socket;#endif // !defined(BOOST_ASIO_BASIC_SOCKET_FWD_DECL)/// Provides socket functionality./** * The basic_socket class template provides functionality that is common to both * stream-oriented and datagram-oriented sockets. * * @par Thread Safety * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */template <typename Protocol, typename Executor>class basic_socket  : public socket_base{public:  /// The type of the executor associated with the object.  typedef Executor executor_type;  /// Rebinds the socket type to another executor.  template <typename Executor1>  struct rebind_executor  {    /// The socket type when rebound to the specified executor.    typedef basic_socket<Protocol, Executor1> other;  };  /// The native representation of a socket.#if defined(GENERATING_DOCUMENTATION)  typedef implementation_defined native_handle_type;#elif defined(BOOST_ASIO_WINDOWS_RUNTIME)  typedef typename detail::null_socket_service<    Protocol>::native_handle_type native_handle_type;#elif defined(BOOST_ASIO_HAS_IOCP)  typedef typename detail::win_iocp_socket_service<    Protocol>::native_handle_type native_handle_type;#else  typedef typename detail::reactive_socket_service<    Protocol>::native_handle_type native_handle_type;#endif  /// The protocol type.  typedef Protocol protocol_type;  /// The endpoint type.  typedef typename Protocol::endpoint endpoint_type;#if !defined(BOOST_ASIO_NO_EXTENSIONS)  /// A basic_socket is always the lowest layer.  typedef basic_socket<Protocol, Executor> lowest_layer_type;#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)  /// Construct a basic_socket without opening it.  /**   * This constructor creates a socket without opening it.   *   * @param ex The I/O executor that the socket will use, by default, to   * dispatch handlers for any asynchronous operations performed on the socket.   */  explicit basic_socket(const executor_type& ex)    : impl_(ex)  {  }  /// Construct a basic_socket without opening it.  /**   * This constructor creates a socket without opening it.   *   * @param context An execution context which provides the I/O executor that   * the socket will use, by default, to dispatch handlers for any asynchronous   * operations performed on the socket.   */  template <typename ExecutionContext>  explicit basic_socket(ExecutionContext& context,      typename enable_if<        is_convertible<ExecutionContext&, execution_context&>::value      >::type* = 0)    : impl_(context)  {  }  /// Construct and open a basic_socket.  /**   * This constructor creates and opens a socket.   *   * @param ex The I/O executor that the socket will use, by default, to   * dispatch handlers for any asynchronous operations performed on the socket.   *   * @param protocol An object specifying protocol parameters to be used.   *   * @throws boost::system::system_error Thrown on failure.   */  basic_socket(const executor_type& ex, const protocol_type& protocol)    : impl_(ex)  {    boost::system::error_code ec;    impl_.get_service().open(impl_.get_implementation(), protocol, ec);    boost::asio::detail::throw_error(ec, "open");  }  /// Construct and open a basic_socket.  /**   * This constructor creates and opens a socket.   *   * @param context An execution context which provides the I/O executor that   * the socket will use, by default, to dispatch handlers for any asynchronous   * operations performed on the socket.   *   * @param protocol An object specifying protocol parameters to be used.   *   * @throws boost::system::system_error Thrown on failure.   */  template <typename ExecutionContext>  basic_socket(ExecutionContext& context, const protocol_type& protocol,      typename enable_if<        is_convertible<ExecutionContext&, execution_context&>::value      >::type* = 0)    : impl_(context)  {    boost::system::error_code ec;    impl_.get_service().open(impl_.get_implementation(), protocol, ec);    boost::asio::detail::throw_error(ec, "open");  }  /// Construct a basic_socket, opening it and binding it to the given local  /// endpoint.  /**   * This constructor creates a socket and automatically opens it bound to the   * specified endpoint on the local machine. The protocol used is the protocol   * associated with the given endpoint.   *   * @param ex The I/O executor that the socket will use, by default, to   * dispatch handlers for any asynchronous operations performed on the socket.   *   * @param endpoint An endpoint on the local machine to which the socket will   * be bound.   *   * @throws boost::system::system_error Thrown on failure.   */  basic_socket(const executor_type& ex, const endpoint_type& endpoint)    : impl_(ex)  {    boost::system::error_code ec;    const protocol_type protocol = endpoint.protocol();    impl_.get_service().open(impl_.get_implementation(), protocol, ec);    boost::asio::detail::throw_error(ec, "open");    impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);    boost::asio::detail::throw_error(ec, "bind");  }  /// Construct a basic_socket, opening it and binding it to the given local  /// endpoint.  /**   * This constructor creates a socket and automatically opens it bound to the   * specified endpoint on the local machine. The protocol used is the protocol   * associated with the given endpoint.   *   * @param context An execution context which provides the I/O executor that   * the socket will use, by default, to dispatch handlers for any asynchronous   * operations performed on the socket.   *   * @param endpoint An endpoint on the local machine to which the socket will   * be bound.   *   * @throws boost::system::system_error Thrown on failure.   */  template <typename ExecutionContext>  basic_socket(ExecutionContext& context, const endpoint_type& endpoint,      typename enable_if<        is_convertible<ExecutionContext&, execution_context&>::value      >::type* = 0)    : impl_(context)  {    boost::system::error_code ec;    const protocol_type protocol = endpoint.protocol();    impl_.get_service().open(impl_.get_implementation(), protocol, ec);    boost::asio::detail::throw_error(ec, "open");    impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);    boost::asio::detail::throw_error(ec, "bind");  }  /// Construct a basic_socket on an existing native socket.  /**   * This constructor creates a socket object to hold an existing native socket.   *   * @param ex The I/O executor that the socket will use, by default, to   * dispatch handlers for any asynchronous operations performed on the socket.   *   * @param protocol An object specifying protocol parameters to be used.   *   * @param native_socket A native socket.   *   * @throws boost::system::system_error Thrown on failure.   */  basic_socket(const executor_type& ex, const protocol_type& protocol,      const native_handle_type& native_socket)    : impl_(ex)  {    boost::system::error_code ec;    impl_.get_service().assign(impl_.get_implementation(),        protocol, native_socket, ec);    boost::asio::detail::throw_error(ec, "assign");  }  /// Construct a basic_socket on an existing native socket.  /**   * This constructor creates a socket object to hold an existing native socket.   *   * @param context An execution context which provides the I/O executor that   * the socket will use, by default, to dispatch handlers for any asynchronous   * operations performed on the socket.   *   * @param protocol An object specifying protocol parameters to be used.   *   * @param native_socket A native socket.   *   * @throws boost::system::system_error Thrown on failure.   */  template <typename ExecutionContext>  basic_socket(ExecutionContext& context, const protocol_type& protocol,      const native_handle_type& native_socket,      typename enable_if<        is_convertible<ExecutionContext&, execution_context&>::value      >::type* = 0)    : impl_(context)  {    boost::system::error_code ec;    impl_.get_service().assign(impl_.get_implementation(),        protocol, native_socket, ec);    boost::asio::detail::throw_error(ec, "assign");  }#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)  /// Move-construct a basic_socket from another.  /**   * This constructor moves a socket from one object to another.   *   * @param other The other basic_socket object from which the move will   * occur.   *   * @note Following the move, the moved-from object is in the same state as if   * constructed using the @c basic_socket(const executor_type&) constructor.   */  basic_socket(basic_socket&& other) BOOST_ASIO_NOEXCEPT    : impl_(std::move(other.impl_))  {  }  /// Move-assign a basic_socket from another.  /**   * This assignment operator moves a socket from one object to another.   *   * @param other The other basic_socket object from which the move will   * occur.   *   * @note Following the move, the moved-from object is in the same state as if   * constructed using the @c basic_socket(const executor_type&) constructor.   */  basic_socket& operator=(basic_socket&& other)  {    impl_ = std::move(other.impl_);    return *this;  }  // All sockets have access to each other's implementations.  template <typename Protocol1, typename Executor1>  friend class basic_socket;  /// Move-construct a basic_socket from a socket of another protocol type.  /**   * This constructor moves a socket from one object to another.   *   * @param other The other basic_socket object from which the move will   * occur.   *   * @note Following the move, the moved-from object is in the same state as if   * constructed using the @c basic_socket(const executor_type&) constructor.   */  template <typename Protocol1, typename Executor1>  basic_socket(basic_socket<Protocol1, Executor1>&& other,      typename enable_if<        is_convertible<Protocol1, Protocol>::value          && is_convertible<Executor1, Executor>::value      >::type* = 0)    : impl_(std::move(other.impl_))  {  }  /// Move-assign a basic_socket from a socket of another protocol type.  /**   * This assignment operator moves a socket from one object to another.   *   * @param other The other basic_socket object from which the move will   * occur.   *   * @note Following the move, the moved-from object is in the same state as if   * constructed using the @c basic_socket(const executor_type&) constructor.   */  template <typename Protocol1, typename Executor1>  typename enable_if<    is_convertible<Protocol1, Protocol>::value      && is_convertible<Executor1, Executor>::value,    basic_socket&  >::type operator=(basic_socket<Protocol1, Executor1> && other)  {    basic_socket tmp(std::move(other));    impl_ = std::move(tmp.impl_);    return *this;  }#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)  /// Get the executor associated with the object.  executor_type get_executor() BOOST_ASIO_NOEXCEPT  {    return impl_.get_executor();  }#if !defined(BOOST_ASIO_NO_EXTENSIONS)  /// Get a reference to the lowest layer.  /**   * This function returns a reference to the lowest layer in a stack of   * layers. Since a basic_socket cannot contain any further layers, it simply   * returns a reference to itself.   *   * @return A reference to the lowest layer in the stack of layers. Ownership   * is not transferred to the caller.   */  lowest_layer_type& lowest_layer()  {    return *this;  }  /// Get a const reference to the lowest layer.  /**   * This function returns a const reference to the lowest layer in a stack of   * layers. Since a basic_socket cannot contain any further layers, it simply   * returns a reference to itself.   *   * @return A const reference to the lowest layer in the stack of layers.   * Ownership is not transferred to the caller.   */  const lowest_layer_type& lowest_layer() const  {    return *this;  }#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)  /// Open the socket using the specified protocol.  /**   * This function opens the socket so that it will use the specified protocol.   *   * @param protocol An object specifying protocol parameters to be used.   *   * @throws boost::system::system_error Thrown on failure.   *   * @par Example   * @code   * boost::asio::ip::tcp::socket socket(my_context);   * socket.open(boost::asio::ip::tcp::v4());   * @endcode   */  void open(const protocol_type& protocol = protocol_type())  {    boost::system::error_code ec;    impl_.get_service().open(impl_.get_implementation(), protocol, ec);    boost::asio::detail::throw_error(ec, "open");  }  /// Open the socket using the specified protocol.  /**   * This function opens the socket so that it will use the specified protocol.   *   * @param protocol An object specifying which protocol is to be used.   *   * @param ec Set to indicate what error occurred, if any.   *   * @par Example   * @code   * boost::asio::ip::tcp::socket socket(my_context);   * boost::system::error_code ec;   * socket.open(boost::asio::ip::tcp::v4(), ec);   * if (ec)   * {   *   // An error occurred.   * }   * @endcode   */  BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol,      boost::system::error_code& ec)  {    impl_.get_service().open(impl_.get_implementation(), protocol, ec);    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);  }  /// Assign an existing native socket to the socket.  /*   * This function opens the socket to hold an existing native socket.   *   * @param protocol An object specifying which protocol is to be used.   *   * @param native_socket A native socket.   *   * @throws boost::system::system_error Thrown on failure.   */  void assign(const protocol_type& protocol,      const native_handle_type& native_socket)  {    boost::system::error_code ec;    impl_.get_service().assign(impl_.get_implementation(),        protocol, native_socket, ec);    boost::asio::detail::throw_error(ec, "assign");  }  /// Assign an existing native socket to the socket.  /*   * This function opens the socket to hold an existing native socket.   *   * @param protocol An object specifying which protocol is to be used.   *   * @param native_socket A native socket.   *   * @param ec Set to indicate what error occurred, if any.   */  BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol,      const native_handle_type& native_socket, boost::system::error_code& ec)  {    impl_.get_service().assign(impl_.get_implementation(),        protocol, native_socket, ec);    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);  }  /// Determine whether the socket is open.  bool is_open() const  {    return impl_.get_service().is_open(impl_.get_implementation());  }  /// Close the socket.  /**   * This function is used to close the socket. Any asynchronous send, receive   * or connect operations will be cancelled immediately, and will complete   * with the boost::asio::error::operation_aborted error.   *   * @throws boost::system::system_error Thrown on failure. Note that, even if   * the function indicates an error, the underlying descriptor is closed.   *   * @note For portable behaviour with respect to graceful closure of a   * connected socket, call shutdown() before closing the socket.   */  void close()  {    boost::system::error_code ec;    impl_.get_service().close(impl_.get_implementation(), ec);    boost::asio::detail::throw_error(ec, "close");  }  /// Close the socket.  /**   * This function is used to close the socket. Any asynchronous send, receive   * or connect operations will be cancelled immediately, and will complete   * with the boost::asio::error::operation_aborted error.   *   * @param ec Set to indicate what error occurred, if any. Note that, even if   * the function indicates an error, the underlying descriptor is closed.   *   * @par Example   * @code   * boost::asio::ip::tcp::socket socket(my_context);   * ...   * boost::system::error_code ec;   * socket.close(ec);   * if (ec)   * {   *   // An error occurred.   * }   * @endcode   *   * @note For portable behaviour with respect to graceful closure of a   * connected socket, call shutdown() before closing the socket.   */  BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)  {    impl_.get_service().close(impl_.get_implementation(), ec);    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);  }  /// Release ownership of the underlying native socket.  /**   * This function causes all outstanding asynchronous connect, send and receive   * operations to finish immediately, and the handlers for cancelled operations   * will be passed the boost::asio::error::operation_aborted error. Ownership   * of the native socket is then transferred to the caller.   *   * @throws boost::system::system_error Thrown on failure.   *   * @note This function is unsupported on Windows versions prior to Windows   * 8.1, and will fail with boost::asio::error::operation_not_supported on   * these platforms.   */#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \  && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)  __declspec(deprecated("This function always fails with "        "operation_not_supported when used on Windows versions "        "prior to Windows 8.1."))#endif  native_handle_type release()  {    boost::system::error_code ec;    native_handle_type s = impl_.get_service().release(        impl_.get_implementation(), ec);    boost::asio::detail::throw_error(ec, "release");    return s;  }  /// Release ownership of the underlying native socket.  /**   * This function causes all outstanding asynchronous connect, send and receive   * operations to finish immediately, and the handlers for cancelled operations   * will be passed the boost::asio::error::operation_aborted error. Ownership   * of the native socket is then transferred to the caller.   *   * @param ec Set to indicate what error occurred, if any.   *   * @note This function is unsupported on Windows versions prior to Windows   * 8.1, and will fail with boost::asio::error::operation_not_supported on   * these platforms.   */#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \  && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)  __declspec(deprecated("This function always fails with "        "operation_not_supported when used on Windows versions "        "prior to Windows 8.1."))#endif  native_handle_type release(boost::system::error_code& ec)  {    return impl_.get_service().release(impl_.get_implementation(), ec);  }  /// Get the native socket representation.  /**   * This function may be used to obtain the underlying representation of the   * socket. This is intended to allow access to native socket functionality   * that is not otherwise provided.   */  native_handle_type native_handle()  {    return impl_.get_service().native_handle(impl_.get_implementation());  }  /// Cancel all asynchronous operations associated with the socket.  /**   * This function causes all outstanding asynchronous connect, send and receive   * operations to finish immediately, and the handlers for cancelled operations   * will be passed the boost::asio::error::operation_aborted error.   *   * @throws boost::system::system_error Thrown on failure.   *   * @note Calls to cancel() will always fail with   * boost::asio::error::operation_not_supported when run on Windows XP, Windows   * Server 2003, and earlier versions of Windows, unless   * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has   * two issues that should be considered before enabling its use:   *   * @li It will only cancel asynchronous operations that were initiated in the   * current thread.   *   * @li It can appear to complete without error, but the request to cancel the   * unfinished operations may be silently ignored by the operating system.   * Whether it works or not seems to depend on the drivers that are installed.   *   * For portable cancellation, consider using one of the following   * alternatives:   *   * @li Disable asio's I/O completion port backend by defining   * BOOST_ASIO_DISABLE_IOCP.   *   * @li Use the close() function to simultaneously cancel the outstanding   * operations and close the socket.   *   * When running on Windows Vista, Windows Server 2008, and later, the   * CancelIoEx function is always used. This function does not have the   * problems described above.   */#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \  && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \  && !defined(BOOST_ASIO_ENABLE_CANCELIO)  __declspec(deprecated("By default, this function always fails with "        "operation_not_supported when used on Windows XP, Windows Server 2003, "        "or earlier. Consult documentation for details."))#endif  void cancel()  {    boost::system::error_code ec;    impl_.get_service().cancel(impl_.get_implementation(), ec);    boost::asio::detail::throw_error(ec, "cancel");  }  /// Cancel all asynchronous operations associated with the socket.  /**   * This function causes all outstanding asynchronous connect, send and receive   * operations to finish immediately, and the handlers for cancelled operations   * will be passed the boost::asio::error::operation_aborted error.   *   * @param ec Set to indicate what error occurred, if any.   *   * @note Calls to cancel() will always fail with   * boost::asio::error::operation_not_supported when run on Windows XP, Windows   * Server 2003, and earlier versions of Windows, unless   * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has   * two issues that should be considered before enabling its use:   *   * @li It will only cancel asynchronous operations that were initiated in the   * current thread.   *   * @li It can appear to complete without error, but the request to cancel the   * unfinished operations may be silently ignored by the operating system.   * Whether it works or not seems to depend on the drivers that are installed.   *   * For portable cancellation, consider using one of the following   * alternatives:   *   * @li Disable asio's I/O completion port backend by defining   * BOOST_ASIO_DISABLE_IOCP.   *   * @li Use the close() function to simultaneously cancel the outstanding   * operations and close the socket.   *   * When running on Windows Vista, Windows Server 2008, and later, the   * CancelIoEx function is always used. This function does not have the   * problems described above.   */#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \  && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \  && !defined(BOOST_ASIO_ENABLE_CANCELIO)  __declspec(deprecated("By default, this function always fails with "        "operation_not_supported when used on Windows XP, Windows Server 2003, "        "or earlier. Consult documentation for details."))#endif  BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)  {    impl_.get_service().cancel(impl_.get_implementation(), ec);    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);  }  /// Determine whether the socket is at the out-of-band data mark.  /**   * This function is used to check whether the socket input is currently   * positioned at the out-of-band data mark.   *   * @return A bool indicating whether the socket is at the out-of-band data   * mark.   *   * @throws boost::system::system_error Thrown on failure.   */  bool at_mark() const  {    boost::system::error_code ec;    bool b = impl_.get_service().at_mark(impl_.get_implementation(), ec);    boost::asio::detail::throw_error(ec, "at_mark");    return b;  }  /// Determine whether the socket is at the out-of-band data mark.  /**   * This function is used to check whether the socket input is currently   * positioned at the out-of-band data mark.   *   * @param ec Set to indicate what error occurred, if any.   *   * @return A bool indicating whether the socket is at the out-of-band data   * mark.   */  bool at_mark(boost::system::error_code& ec) const  {    return impl_.get_service().at_mark(impl_.get_implementation(), ec);  }  /// Determine the number of bytes available for reading.  /**   * This function is used to determine the number of bytes that may be read   * without blocking.   *   * @return The number of bytes that may be read without blocking, or 0 if an   * error occurs.   *   * @throws boost::system::system_error Thrown on failure.   */  std::size_t available() const  {    boost::system::error_code ec;    std::size_t s = impl_.get_service().available(        impl_.get_implementation(), ec);    boost::asio::detail::throw_error(ec, "available");    return s;  }  /// Determine the number of bytes available for reading.  /**   * This function is used to determine the number of bytes that may be read   * without blocking.   *   * @param ec Set to indicate what error occurred, if any.   *   * @return The number of bytes that may be read without blocking, or 0 if an   * error occurs.   */  std::size_t available(boost::system::error_code& ec) const  {    return impl_.get_service().available(impl_.get_implementation(), ec);  }  /// Bind the socket to the given local endpoint.  /**   * This function binds the socket to the specified endpoint on the local   * machine.   *   * @param endpoint An endpoint on the local machine to which the socket will   * be bound.   *   * @throws boost::system::system_error Thrown on failure.   *   * @par Example   * @code   * boost::asio::ip::tcp::socket socket(my_context);   * socket.open(boost::asio::ip::tcp::v4());   * socket.bind(boost::asio::ip::tcp::endpoint(   *       boost::asio::ip::tcp::v4(), 12345));   * @endcode   */  void bind(const endpoint_type& endpoint)  {    boost::system::error_code ec;    impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);    boost::asio::detail::throw_error(ec, "bind");  }  /// Bind the socket to the given local endpoint.  /**   * This function binds the socket to the specified endpoint on the local   * machine.   *   * @param endpoint An endpoint on the local machine to which the socket will   * be bound.   *   * @param ec Set to indicate what error occurred, if any.   *   * @par Example   * @code   * boost::asio::ip::tcp::socket socket(my_context);   * socket.open(boost::asio::ip::tcp::v4());   * boost::system::error_code ec;   * socket.bind(boost::asio::ip::tcp::endpoint(   *       boost::asio::ip::tcp::v4(), 12345), ec);   * if (ec)   * {   *   // An error occurred.   * }   * @endcode   */  BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint,      boost::system::error_code& ec)  {    impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);  }  /// Connect the socket to the specified endpoint.  /**   * This function is used to connect a socket to the specified remote endpoint.   * The function call will block until the connection is successfully made or   * an error occurs.   *   * The socket is automatically opened if it is not already open. If the   * connect fails, and the socket was automatically opened, the socket is   * not returned to the closed state.   *   * @param peer_endpoint The remote endpoint to which the socket will be   * connected.   *   * @throws boost::system::system_error Thrown on failure.   *   * @par Example   * @code   * boost::asio::ip::tcp::socket socket(my_context);   * boost::asio::ip::tcp::endpoint endpoint(   *     boost::asio::ip::address::from_string("1.2.3.4"), 12345);   * socket.connect(endpoint);   * @endcode   */  void connect(const endpoint_type& peer_endpoint)  {    boost::system::error_code ec;    if (!is_open())    {      impl_.get_service().open(impl_.get_implementation(),          peer_endpoint.protocol(), ec);      boost::asio::detail::throw_error(ec, "connect");    }    impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec);    boost::asio::detail::throw_error(ec, "connect");  }  /// Connect the socket to the specified endpoint.  /**   * This function is used to connect a socket to the specified remote endpoint.   * The function call will block until the connection is successfully made or   * an error occurs.   *   * The socket is automatically opened if it is not already open. If the   * connect fails, and the socket was automatically opened, the socket is   * not returned to the closed state.   *   * @param peer_endpoint The remote endpoint to which the socket will be   * connected.   *   * @param ec Set to indicate what error occurred, if any.   *   * @par Example   * @code   * boost::asio::ip::tcp::socket socket(my_context);   * boost::asio::ip::tcp::endpoint endpoint(   *     boost::asio::ip::address::from_string("1.2.3.4"), 12345);   * boost::system::error_code ec;   * socket.connect(endpoint, ec);   * if (ec)   * {   *   // An error occurred.   * }   * @endcode   */  BOOST_ASIO_SYNC_OP_VOID connect(const endpoint_type& peer_endpoint,      boost::system::error_code& ec)  {    if (!is_open())    {      impl_.get_service().open(impl_.get_implementation(),            peer_endpoint.protocol(), ec);      if (ec)      {        BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);      }    }    impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec);    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);  }  /// Start an asynchronous connect.  /**   * This function is used to asynchronously connect a socket to the specified   * remote endpoint. The function call always returns immediately.   *   * The socket is automatically opened if it is not already open. If the   * connect fails, and the socket was automatically opened, the socket is   * not returned to the closed state.   *   * @param peer_endpoint The remote endpoint to which the socket will be   * connected. Copies will be made of the endpoint object as required.   *   * @param handler The handler to be called when the connection operation   * completes. Copies will be made of the handler as required. The function   * signature of the handler must be:   * @code void handler(   *   const boost::system::error_code& error // Result of operation   * ); @endcode   * Regardless of whether the asynchronous operation completes immediately or   * not, the handler will not be invoked from within this function. On   * immediate completion, invocation of the handler will be performed in a   * manner equivalent to using boost::asio::post().   *   * @par Example   * @code   * void connect_handler(const boost::system::error_code& error)   * {   *   if (!error)   *   {   *     // Connect succeeded.   *   }   * }   *   * ...   *   * boost::asio::ip::tcp::socket socket(my_context);   * boost::asio::ip::tcp::endpoint endpoint(   *     boost::asio::ip::address::from_string("1.2.3.4"), 12345);   * socket.async_connect(endpoint, connect_handler);   * @endcode   */  template <      BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))        ConnectHandler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>  BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ConnectHandler,      void (boost::system::error_code))  async_connect(const endpoint_type& peer_endpoint,      BOOST_ASIO_MOVE_ARG(ConnectHandler) handler        BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))  {    boost::system::error_code open_ec;    if (!is_open())    {      const protocol_type protocol = peer_endpoint.protocol();      impl_.get_service().open(impl_.get_implementation(), protocol, open_ec);    }    return async_initiate<ConnectHandler, void (boost::system::error_code)>(        initiate_async_connect(this), handler, peer_endpoint, open_ec);  }  /// Set an option on the socket.  /**   * This function is used to set an option on the socket.   *   * @param option The new option value to be set on the socket.   *   * @throws boost::system::system_error Thrown on failure.   *   * @sa SettableSocketOption @n   * boost::asio::socket_base::broadcast @n   * boost::asio::socket_base::do_not_route @n   * boost::asio::socket_base::keep_alive @n   * boost::asio::socket_base::linger @n   * boost::asio::socket_base::receive_buffer_size @n   * boost::asio::socket_base::receive_low_watermark @n   * boost::asio::socket_base::reuse_address @n   * boost::asio::socket_base::send_buffer_size @n   * boost::asio::socket_base::send_low_watermark @n   * boost::asio::ip::multicast::join_group @n   * boost::asio::ip::multicast::leave_group @n   * boost::asio::ip::multicast::enable_loopback @n   * boost::asio::ip::multicast::outbound_interface @n   * boost::asio::ip::multicast::hops @n   * boost::asio::ip::tcp::no_delay   *   * @par Example   * Setting the IPPROTO_TCP/TCP_NODELAY option:   * @code   * boost::asio::ip::tcp::socket socket(my_context);   * ...   * boost::asio::ip::tcp::no_delay option(true);   * socket.set_option(option);   * @endcode   */  template <typename SettableSocketOption>  void set_option(const SettableSocketOption& option)  {    boost::system::error_code ec;    impl_.get_service().set_option(impl_.get_implementation(), option, ec);    boost::asio::detail::throw_error(ec, "set_option");  }  /// Set an option on the socket.  /**   * This function is used to set an option on the socket.   *   * @param option The new option value to be set on the socket.   *   * @param ec Set to indicate what error occurred, if any.   *   * @sa SettableSocketOption @n   * boost::asio::socket_base::broadcast @n   * boost::asio::socket_base::do_not_route @n   * boost::asio::socket_base::keep_alive @n   * boost::asio::socket_base::linger @n   * boost::asio::socket_base::receive_buffer_size @n   * boost::asio::socket_base::receive_low_watermark @n   * boost::asio::socket_base::reuse_address @n   * boost::asio::socket_base::send_buffer_size @n   * boost::asio::socket_base::send_low_watermark @n   * boost::asio::ip::multicast::join_group @n   * boost::asio::ip::multicast::leave_group @n   * boost::asio::ip::multicast::enable_loopback @n   * boost::asio::ip::multicast::outbound_interface @n   * boost::asio::ip::multicast::hops @n   * boost::asio::ip::tcp::no_delay   *   * @par Example   * Setting the IPPROTO_TCP/TCP_NODELAY option:   * @code   * boost::asio::ip::tcp::socket socket(my_context);   * ...   * boost::asio::ip::tcp::no_delay option(true);   * boost::system::error_code ec;   * socket.set_option(option, ec);   * if (ec)   * {   *   // An error occurred.   * }   * @endcode   */  template <typename SettableSocketOption>  BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option,      boost::system::error_code& ec)  {    impl_.get_service().set_option(impl_.get_implementation(), option, ec);    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);  }  /// Get an option from the socket.  /**   * This function is used to get the current value of an option on the socket.   *   * @param option The option value to be obtained from the socket.   *   * @throws boost::system::system_error Thrown on failure.   *   * @sa GettableSocketOption @n   * boost::asio::socket_base::broadcast @n   * boost::asio::socket_base::do_not_route @n   * boost::asio::socket_base::keep_alive @n   * boost::asio::socket_base::linger @n   * boost::asio::socket_base::receive_buffer_size @n   * boost::asio::socket_base::receive_low_watermark @n   * boost::asio::socket_base::reuse_address @n   * boost::asio::socket_base::send_buffer_size @n   * boost::asio::socket_base::send_low_watermark @n   * boost::asio::ip::multicast::join_group @n   * boost::asio::ip::multicast::leave_group @n   * boost::asio::ip::multicast::enable_loopback @n   * boost::asio::ip::multicast::outbound_interface @n   * boost::asio::ip::multicast::hops @n   * boost::asio::ip::tcp::no_delay   *   * @par Example   * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:   * @code   * boost::asio::ip::tcp::socket socket(my_context);   * ...   * boost::asio::ip::tcp::socket::keep_alive option;   * socket.get_option(option);   * bool is_set = option.value();   * @endcode   */  template <typename GettableSocketOption>  void get_option(GettableSocketOption& option) const  {    boost::system::error_code ec;    impl_.get_service().get_option(impl_.get_implementation(), option, ec);    boost::asio::detail::throw_error(ec, "get_option");  }  /// Get an option from the socket.  /**   * This function is used to get the current value of an option on the socket.   *   * @param option The option value to be obtained from the socket.   *   * @param ec Set to indicate what error occurred, if any.   *   * @sa GettableSocketOption @n   * boost::asio::socket_base::broadcast @n   * boost::asio::socket_base::do_not_route @n   * boost::asio::socket_base::keep_alive @n   * boost::asio::socket_base::linger @n   * boost::asio::socket_base::receive_buffer_size @n   * boost::asio::socket_base::receive_low_watermark @n   * boost::asio::socket_base::reuse_address @n   * boost::asio::socket_base::send_buffer_size @n   * boost::asio::socket_base::send_low_watermark @n   * boost::asio::ip::multicast::join_group @n   * boost::asio::ip::multicast::leave_group @n   * boost::asio::ip::multicast::enable_loopback @n   * boost::asio::ip::multicast::outbound_interface @n   * boost::asio::ip::multicast::hops @n   * boost::asio::ip::tcp::no_delay   *   * @par Example   * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:   * @code   * boost::asio::ip::tcp::socket socket(my_context);   * ...   * boost::asio::ip::tcp::socket::keep_alive option;   * boost::system::error_code ec;   * socket.get_option(option, ec);   * if (ec)   * {   *   // An error occurred.   * }   * bool is_set = option.value();   * @endcode   */  template <typename GettableSocketOption>  BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option,      boost::system::error_code& ec) const  {    impl_.get_service().get_option(impl_.get_implementation(), option, ec);    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);  }  /// Perform an IO control command on the socket.  /**   * This function is used to execute an IO control command on the socket.   *   * @param command The IO control command to be performed on the socket.   *   * @throws boost::system::system_error Thrown on failure.   *   * @sa IoControlCommand @n   * boost::asio::socket_base::bytes_readable @n   * boost::asio::socket_base::non_blocking_io   *   * @par Example   * Getting the number of bytes ready to read:   * @code   * boost::asio::ip::tcp::socket socket(my_context);   * ...   * boost::asio::ip::tcp::socket::bytes_readable command;   * socket.io_control(command);   * std::size_t bytes_readable = command.get();   * @endcode   */  template <typename IoControlCommand>  void io_control(IoControlCommand& command)  {    boost::system::error_code ec;    impl_.get_service().io_control(impl_.get_implementation(), command, ec);    boost::asio::detail::throw_error(ec, "io_control");  }  /// Perform an IO control command on the socket.  /**   * This function is used to execute an IO control command on the socket.   *   * @param command The IO control command to be performed on the socket.   *   * @param ec Set to indicate what error occurred, if any.   *   * @sa IoControlCommand @n   * boost::asio::socket_base::bytes_readable @n   * boost::asio::socket_base::non_blocking_io   *   * @par Example   * Getting the number of bytes ready to read:   * @code   * boost::asio::ip::tcp::socket socket(my_context);   * ...   * boost::asio::ip::tcp::socket::bytes_readable command;   * boost::system::error_code ec;   * socket.io_control(command, ec);   * if (ec)   * {   *   // An error occurred.   * }   * std::size_t bytes_readable = command.get();   * @endcode   */  template <typename IoControlCommand>  BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command,      boost::system::error_code& ec)  {    impl_.get_service().io_control(impl_.get_implementation(), command, ec);    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);  }  /// Gets the non-blocking mode of the socket.  /**   * @returns @c true if the socket's synchronous operations will fail with   * boost::asio::error::would_block if they are unable to perform the requested   * operation immediately. If @c false, synchronous operations will block   * until complete.   *   * @note The non-blocking mode has no effect on the behaviour of asynchronous   * operations. Asynchronous operations will never fail with the error   * boost::asio::error::would_block.   */  bool non_blocking() const  {    return impl_.get_service().non_blocking(impl_.get_implementation());  }  /// Sets the non-blocking mode of the socket.  /**   * @param mode If @c true, the socket's synchronous operations will fail with   * boost::asio::error::would_block if they are unable to perform the requested   * operation immediately. If @c false, synchronous operations will block   * until complete.   *   * @throws boost::system::system_error Thrown on failure.   *   * @note The non-blocking mode has no effect on the behaviour of asynchronous   * operations. Asynchronous operations will never fail with the error   * boost::asio::error::would_block.   */  void non_blocking(bool mode)  {    boost::system::error_code ec;    impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec);    boost::asio::detail::throw_error(ec, "non_blocking");  }  /// Sets the non-blocking mode of the socket.  /**   * @param mode If @c true, the socket's synchronous operations will fail with   * boost::asio::error::would_block if they are unable to perform the requested   * operation immediately. If @c false, synchronous operations will block   * until complete.   *   * @param ec Set to indicate what error occurred, if any.   *   * @note The non-blocking mode has no effect on the behaviour of asynchronous   * operations. Asynchronous operations will never fail with the error   * boost::asio::error::would_block.   */  BOOST_ASIO_SYNC_OP_VOID non_blocking(      bool mode, boost::system::error_code& ec)  {    impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec);    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);  }  /// Gets the non-blocking mode of the native socket implementation.  /**   * This function is used to retrieve the non-blocking mode of the underlying   * native socket. This mode has no effect on the behaviour of the socket   * object's synchronous operations.   *   * @returns @c true if the underlying socket is in non-blocking mode and   * direct system calls may fail with boost::asio::error::would_block (or the   * equivalent system error).   *   * @note The current non-blocking mode is cached by the socket object.   * Consequently, the return value may be incorrect if the non-blocking mode   * was set directly on the native socket.   *   * @par Example   * This function is intended to allow the encapsulation of arbitrary   * non-blocking system calls as asynchronous operations, in a way that is   * transparent to the user of the socket object. The following example   * illustrates how Linux's @c sendfile system call might be encapsulated:   * @code template <typename Handler>   * struct sendfile_op   * {   *   tcp::socket& sock_;   *   int fd_;   *   Handler handler_;   *   off_t offset_;   *   std::size_t total_bytes_transferred_;   *   *   // Function call operator meeting WriteHandler requirements.   *   // Used as the handler for the async_write_some operation.   *   void operator()(boost::system::error_code ec, std::size_t)   *   {   *     // Put the underlying socket into non-blocking mode.   *     if (!ec)   *       if (!sock_.native_non_blocking())   *         sock_.native_non_blocking(true, ec);   *   *     if (!ec)   *     {   *       for (;;)   *       {   *         // Try the system call.   *         errno = 0;   *         int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);   *         ec = boost::system::error_code(n < 0 ? errno : 0,   *             boost::asio::error::get_system_category());   *         total_bytes_transferred_ += ec ? 0 : n;   *   *         // Retry operation immediately if interrupted by signal.   *         if (ec == boost::asio::error::interrupted)   *           continue;   *   *         // Check if we need to run the operation again.   *         if (ec == boost::asio::error::would_block   *             || ec == boost::asio::error::try_again)   *         {   *           // We have to wait for the socket to become ready again.   *           sock_.async_wait(tcp::socket::wait_write, *this);   *           return;   *         }   *   *         if (ec || n == 0)   *         {   *           // An error occurred, or we have reached the end of the file.   *           // Either way we must exit the loop so we can call the handler.   *           break;   *         }   *   *         // Loop around to try calling sendfile again.   *       }   *     }   *   *     // Pass result back to user's handler.   *     handler_(ec, total_bytes_transferred_);   *   }   * };   *   * template <typename Handler>   * void async_sendfile(tcp::socket& sock, int fd, Handler h)   * {   *   sendfile_op<Handler> op = { sock, fd, h, 0, 0 };   *   sock.async_wait(tcp::socket::wait_write, op);   * } @endcode   */  bool native_non_blocking() const  {    return impl_.get_service().native_non_blocking(impl_.get_implementation());  }  /// Sets the non-blocking mode of the native socket implementation.  /**   * This function is used to modify the non-blocking mode of the underlying   * native socket. It has no effect on the behaviour of the socket object's   * synchronous operations.   *   * @param mode If @c true, the underlying socket is put into non-blocking   * mode and direct system calls may fail with boost::asio::error::would_block   * (or the equivalent system error).   *   * @throws boost::system::system_error Thrown on failure. If the @c mode is   * @c false, but the current value of @c non_blocking() is @c true, this   * function fails with boost::asio::error::invalid_argument, as the   * combination does not make sense.   *   * @par Example   * This function is intended to allow the encapsulation of arbitrary   * non-blocking system calls as asynchronous operations, in a way that is   * transparent to the user of the socket object. The following example   * illustrates how Linux's @c sendfile system call might be encapsulated:   * @code template <typename Handler>   * struct sendfile_op   * {   *   tcp::socket& sock_;   *   int fd_;   *   Handler handler_;   *   off_t offset_;   *   std::size_t total_bytes_transferred_;   *   *   // Function call operator meeting WriteHandler requirements.   *   // Used as the handler for the async_write_some operation.   *   void operator()(boost::system::error_code ec, std::size_t)   *   {   *     // Put the underlying socket into non-blocking mode.   *     if (!ec)   *       if (!sock_.native_non_blocking())   *         sock_.native_non_blocking(true, ec);   *   *     if (!ec)   *     {   *       for (;;)   *       {   *         // Try the system call.   *         errno = 0;   *         int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);   *         ec = boost::system::error_code(n < 0 ? errno : 0,   *             boost::asio::error::get_system_category());   *         total_bytes_transferred_ += ec ? 0 : n;   *   *         // Retry operation immediately if interrupted by signal.   *         if (ec == boost::asio::error::interrupted)   *           continue;   *   *         // Check if we need to run the operation again.   *         if (ec == boost::asio::error::would_block   *             || ec == boost::asio::error::try_again)   *         {   *           // We have to wait for the socket to become ready again.   *           sock_.async_wait(tcp::socket::wait_write, *this);   *           return;   *         }   *   *         if (ec || n == 0)   *         {   *           // An error occurred, or we have reached the end of the file.   *           // Either way we must exit the loop so we can call the handler.   *           break;   *         }   *   *         // Loop around to try calling sendfile again.   *       }   *     }   *   *     // Pass result back to user's handler.   *     handler_(ec, total_bytes_transferred_);   *   }   * };   *   * template <typename Handler>   * void async_sendfile(tcp::socket& sock, int fd, Handler h)   * {   *   sendfile_op<Handler> op = { sock, fd, h, 0, 0 };   *   sock.async_wait(tcp::socket::wait_write, op);   * } @endcode   */  void native_non_blocking(bool mode)  {    boost::system::error_code ec;    impl_.get_service().native_non_blocking(        impl_.get_implementation(), mode, ec);    boost::asio::detail::throw_error(ec, "native_non_blocking");  }  /// Sets the non-blocking mode of the native socket implementation.  /**   * This function is used to modify the non-blocking mode of the underlying   * native socket. It has no effect on the behaviour of the socket object's   * synchronous operations.   *   * @param mode If @c true, the underlying socket is put into non-blocking   * mode and direct system calls may fail with boost::asio::error::would_block   * (or the equivalent system error).   *   * @param ec Set to indicate what error occurred, if any. If the @c mode is   * @c false, but the current value of @c non_blocking() is @c true, this   * function fails with boost::asio::error::invalid_argument, as the   * combination does not make sense.   *   * @par Example   * This function is intended to allow the encapsulation of arbitrary   * non-blocking system calls as asynchronous operations, in a way that is   * transparent to the user of the socket object. The following example   * illustrates how Linux's @c sendfile system call might be encapsulated:   * @code template <typename Handler>   * struct sendfile_op   * {   *   tcp::socket& sock_;   *   int fd_;   *   Handler handler_;   *   off_t offset_;   *   std::size_t total_bytes_transferred_;   *   *   // Function call operator meeting WriteHandler requirements.   *   // Used as the handler for the async_write_some operation.   *   void operator()(boost::system::error_code ec, std::size_t)   *   {   *     // Put the underlying socket into non-blocking mode.   *     if (!ec)   *       if (!sock_.native_non_blocking())   *         sock_.native_non_blocking(true, ec);   *   *     if (!ec)   *     {   *       for (;;)   *       {   *         // Try the system call.   *         errno = 0;   *         int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);   *         ec = boost::system::error_code(n < 0 ? errno : 0,   *             boost::asio::error::get_system_category());   *         total_bytes_transferred_ += ec ? 0 : n;   *   *         // Retry operation immediately if interrupted by signal.   *         if (ec == boost::asio::error::interrupted)   *           continue;   *   *         // Check if we need to run the operation again.   *         if (ec == boost::asio::error::would_block   *             || ec == boost::asio::error::try_again)   *         {   *           // We have to wait for the socket to become ready again.   *           sock_.async_wait(tcp::socket::wait_write, *this);   *           return;   *         }   *   *         if (ec || n == 0)   *         {   *           // An error occurred, or we have reached the end of the file.   *           // Either way we must exit the loop so we can call the handler.   *           break;   *         }   *   *         // Loop around to try calling sendfile again.   *       }   *     }   *   *     // Pass result back to user's handler.   *     handler_(ec, total_bytes_transferred_);   *   }   * };   *   * template <typename Handler>   * void async_sendfile(tcp::socket& sock, int fd, Handler h)   * {   *   sendfile_op<Handler> op = { sock, fd, h, 0, 0 };   *   sock.async_wait(tcp::socket::wait_write, op);   * } @endcode   */  BOOST_ASIO_SYNC_OP_VOID native_non_blocking(      bool mode, boost::system::error_code& ec)  {    impl_.get_service().native_non_blocking(        impl_.get_implementation(), mode, ec);    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);  }  /// Get the local endpoint of the socket.  /**   * This function is used to obtain the locally bound endpoint of the socket.   *   * @returns An object that represents the local endpoint of the socket.   *   * @throws boost::system::system_error Thrown on failure.   *   * @par Example   * @code   * boost::asio::ip::tcp::socket socket(my_context);   * ...   * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint();   * @endcode   */  endpoint_type local_endpoint() const  {    boost::system::error_code ec;    endpoint_type ep = impl_.get_service().local_endpoint(        impl_.get_implementation(), ec);    boost::asio::detail::throw_error(ec, "local_endpoint");    return ep;  }  /// Get the local endpoint of the socket.  /**   * This function is used to obtain the locally bound endpoint of the socket.   *   * @param ec Set to indicate what error occurred, if any.   *   * @returns An object that represents the local endpoint of the socket.   * Returns a default-constructed endpoint object if an error occurred.   *   * @par Example   * @code   * boost::asio::ip::tcp::socket socket(my_context);   * ...   * boost::system::error_code ec;   * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec);   * if (ec)   * {   *   // An error occurred.   * }   * @endcode   */  endpoint_type local_endpoint(boost::system::error_code& ec) const  {    return impl_.get_service().local_endpoint(impl_.get_implementation(), ec);  }  /// Get the remote endpoint of the socket.  /**   * This function is used to obtain the remote endpoint of the socket.   *   * @returns An object that represents the remote endpoint of the socket.   *   * @throws boost::system::system_error Thrown on failure.   *   * @par Example   * @code   * boost::asio::ip::tcp::socket socket(my_context);   * ...   * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint();   * @endcode   */  endpoint_type remote_endpoint() const  {    boost::system::error_code ec;    endpoint_type ep = impl_.get_service().remote_endpoint(        impl_.get_implementation(), ec);    boost::asio::detail::throw_error(ec, "remote_endpoint");    return ep;  }  /// Get the remote endpoint of the socket.  /**   * This function is used to obtain the remote endpoint of the socket.   *   * @param ec Set to indicate what error occurred, if any.   *   * @returns An object that represents the remote endpoint of the socket.   * Returns a default-constructed endpoint object if an error occurred.   *   * @par Example   * @code   * boost::asio::ip::tcp::socket socket(my_context);   * ...   * boost::system::error_code ec;   * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec);   * if (ec)   * {   *   // An error occurred.   * }   * @endcode   */  endpoint_type remote_endpoint(boost::system::error_code& ec) const  {    return impl_.get_service().remote_endpoint(impl_.get_implementation(), ec);  }  /// Disable sends or receives on the socket.  /**   * This function is used to disable send operations, receive operations, or   * both.   *   * @param what Determines what types of operation will no longer be allowed.   *   * @throws boost::system::system_error Thrown on failure.   *   * @par Example   * Shutting down the send side of the socket:   * @code   * boost::asio::ip::tcp::socket socket(my_context);   * ...   * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send);   * @endcode   */  void shutdown(shutdown_type what)  {    boost::system::error_code ec;    impl_.get_service().shutdown(impl_.get_implementation(), what, ec);    boost::asio::detail::throw_error(ec, "shutdown");  }  /// Disable sends or receives on the socket.  /**   * This function is used to disable send operations, receive operations, or   * both.   *   * @param what Determines what types of operation will no longer be allowed.   *   * @param ec Set to indicate what error occurred, if any.   *   * @par Example   * Shutting down the send side of the socket:   * @code   * boost::asio::ip::tcp::socket socket(my_context);   * ...   * boost::system::error_code ec;   * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec);   * if (ec)   * {   *   // An error occurred.   * }   * @endcode   */  BOOST_ASIO_SYNC_OP_VOID shutdown(shutdown_type what,      boost::system::error_code& ec)  {    impl_.get_service().shutdown(impl_.get_implementation(), what, ec);    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);  }  /// Wait for the socket to become ready to read, ready to write, or to have  /// pending error conditions.  /**   * This function is used to perform a blocking wait for a socket to enter   * a ready to read, write or error condition state.   *   * @param w Specifies the desired socket state.   *   * @par Example   * Waiting for a socket to become readable.   * @code   * boost::asio::ip::tcp::socket socket(my_context);   * ...   * socket.wait(boost::asio::ip::tcp::socket::wait_read);   * @endcode   */  void wait(wait_type w)  {    boost::system::error_code ec;    impl_.get_service().wait(impl_.get_implementation(), w, ec);    boost::asio::detail::throw_error(ec, "wait");  }  /// Wait for the socket to become ready to read, ready to write, or to have  /// pending error conditions.  /**   * This function is used to perform a blocking wait for a socket to enter   * a ready to read, write or error condition state.   *   * @param w Specifies the desired socket state.   *   * @param ec Set to indicate what error occurred, if any.   *   * @par Example   * Waiting for a socket to become readable.   * @code   * boost::asio::ip::tcp::socket socket(my_context);   * ...   * boost::system::error_code ec;   * socket.wait(boost::asio::ip::tcp::socket::wait_read, ec);   * @endcode   */  BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec)  {    impl_.get_service().wait(impl_.get_implementation(), w, ec);    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);  }  /// Asynchronously wait for the socket to become ready to read, ready to  /// write, or to have pending error conditions.  /**   * This function is used to perform an asynchronous wait for a socket to enter   * a ready to read, write or error condition state.   *   * @param w Specifies the desired socket state.   *   * @param handler The handler to be called when the wait operation completes.   * Copies will be made of the handler as required. The function signature of   * the handler must be:   * @code void handler(   *   const boost::system::error_code& error // Result of operation   * ); @endcode   * Regardless of whether the asynchronous operation completes immediately or   * not, the handler will not be invoked from within this function. On   * immediate completion, invocation of the handler will be performed in a   * manner equivalent to using boost::asio::post().   *   * @par Example   * @code   * void wait_handler(const boost::system::error_code& error)   * {   *   if (!error)   *   {   *     // Wait succeeded.   *   }   * }   *   * ...   *   * boost::asio::ip::tcp::socket socket(my_context);   * ...   * socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler);   * @endcode   */  template <      BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))        WaitHandler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>  BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WaitHandler,      void (boost::system::error_code))  async_wait(wait_type w,      BOOST_ASIO_MOVE_ARG(WaitHandler) handler        BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))  {    return async_initiate<WaitHandler, void (boost::system::error_code)>(        initiate_async_wait(this), handler, w);  }protected:  /// Protected destructor to prevent deletion through this type.  /**   * This function destroys the socket, cancelling any outstanding asynchronous   * operations associated with the socket as if by calling @c cancel.   */  ~basic_socket()  {  }#if defined(BOOST_ASIO_WINDOWS_RUNTIME)  detail::io_object_impl<    detail::null_socket_service<Protocol>, Executor> impl_;#elif defined(BOOST_ASIO_HAS_IOCP)  detail::io_object_impl<    detail::win_iocp_socket_service<Protocol>, Executor> impl_;#else  detail::io_object_impl<    detail::reactive_socket_service<Protocol>, Executor> impl_;#endifprivate:  // Disallow copying and assignment.  basic_socket(const basic_socket&) BOOST_ASIO_DELETED;  basic_socket& operator=(const basic_socket&) BOOST_ASIO_DELETED;  class initiate_async_connect  {  public:    typedef Executor executor_type;    explicit initiate_async_connect(basic_socket* self)      : self_(self)    {    }    executor_type get_executor() const BOOST_ASIO_NOEXCEPT    {      return self_->get_executor();    }    template <typename ConnectHandler>    void operator()(BOOST_ASIO_MOVE_ARG(ConnectHandler) handler,        const endpoint_type& peer_endpoint,        const boost::system::error_code& open_ec) const    {      // If you get an error on the following line it means that your handler      // does not meet the documented type requirements for a ConnectHandler.      BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check;      if (open_ec)      {          boost::asio::post(self_->impl_.get_executor(),              boost::asio::detail::bind_handler(                BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler), open_ec));      }      else      {        detail::non_const_lvalue<ConnectHandler> handler2(handler);        self_->impl_.get_service().async_connect(            self_->impl_.get_implementation(), peer_endpoint,            handler2.value, self_->impl_.get_implementation_executor());      }    }  private:    basic_socket* self_;  };  class initiate_async_wait  {  public:    typedef Executor executor_type;    explicit initiate_async_wait(basic_socket* self)      : self_(self)    {    }    executor_type get_executor() const BOOST_ASIO_NOEXCEPT    {      return self_->get_executor();    }    template <typename WaitHandler>    void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, wait_type w) const    {      // If you get an error on the following line it means that your handler      // does not meet the documented type requirements for a WaitHandler.      BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;      detail::non_const_lvalue<WaitHandler> handler2(handler);      self_->impl_.get_service().async_wait(          self_->impl_.get_implementation(), w, handler2.value,          self_->impl_.get_implementation_executor());    }  private:    basic_socket* self_;  };};} // namespace asio} // namespace boost#include <boost/asio/detail/pop_options.hpp>#endif // BOOST_ASIO_BASIC_SOCKET_HPP
 |