PageRenderTime 96ms CodeModel.GetById 35ms app.highlight 53ms RepoModel.GetById 2ms app.codeStats 0ms

/include/boost/asio/basic_socket.hpp

https://bitbucket.org/Leijing/lip-measurement
C++ Header | 1464 lines | 348 code | 63 blank | 1053 comment | 15 complexity | cd0ab984778bed4ec8e64c6e811995ce MD5 | raw file

Large files files are truncated, but you can click here to view the full file

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

Large files files are truncated, but you can click here to view the full file