PageRenderTime 4ms CodeModel.GetById 4ms app.highlight 50ms RepoModel.GetById 4ms app.codeStats 1ms

/include/boost/asio/basic_socket.hpp

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

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