Home | History | Annotate | Download | only in asio
      1 //
      2 // basic_stream_socket.hpp
      3 // ~~~~~~~~~~~~~~~~~~~~~~~
      4 //
      5 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
      6 //
      7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
      8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
      9 //
     10 
     11 #ifndef ASIO_BASIC_STREAM_SOCKET_HPP
     12 #define ASIO_BASIC_STREAM_SOCKET_HPP
     13 
     14 
     15 #include "asio/detail/config.hpp"
     16 #include <cstddef>
     17 #include "asio/async_result.hpp"
     18 #include "asio/basic_socket.hpp"
     19 #include "asio/detail/handler_type_requirements.hpp"
     20 #include "asio/detail/throw_error.hpp"
     21 #include "asio/error.hpp"
     22 #include "asio/stream_socket_service.hpp"
     23 
     24 #include "asio/detail/push_options.hpp"
     25 
     26 namespace asio {
     27 
     28 /// Provides stream-oriented socket functionality.
     29 /**
     30  * The basic_stream_socket class template provides asynchronous and blocking
     31  * stream-oriented socket functionality.
     32  *
     33  * @par Thread Safety
     34  * @e Distinct @e objects: Safe.@n
     35  * @e Shared @e objects: Unsafe.
     36  *
     37  * @par Concepts:
     38  * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
     39  */
     40 template <typename Protocol,
     41     typename StreamSocketService = stream_socket_service<Protocol> >
     42 class basic_stream_socket
     43   : public basic_socket<Protocol, StreamSocketService>
     44 {
     45 public:
     46   /// (Deprecated: Use native_handle_type.) The native representation of a
     47   /// socket.
     48   typedef typename StreamSocketService::native_handle_type native_type;
     49 
     50   /// The native representation of a socket.
     51   typedef typename StreamSocketService::native_handle_type native_handle_type;
     52 
     53   /// The protocol type.
     54   typedef Protocol protocol_type;
     55 
     56   /// The endpoint type.
     57   typedef typename Protocol::endpoint endpoint_type;
     58 
     59   /// Construct a basic_stream_socket without opening it.
     60   /**
     61    * This constructor creates a stream socket without opening it. The socket
     62    * needs to be opened and then connected or accepted before data can be sent
     63    * or received on it.
     64    *
     65    * @param io_service The io_service object that the stream socket will use to
     66    * dispatch handlers for any asynchronous operations performed on the socket.
     67    */
     68   explicit basic_stream_socket(asio::io_service& io_service)
     69     : basic_socket<Protocol, StreamSocketService>(io_service)
     70   {
     71   }
     72 
     73   /// Construct and open a basic_stream_socket.
     74   /**
     75    * This constructor creates and opens a stream socket. The socket needs to be
     76    * connected or accepted before data can be sent or received on it.
     77    *
     78    * @param io_service The io_service object that the stream socket will use to
     79    * dispatch handlers for any asynchronous operations performed on the socket.
     80    *
     81    * @param protocol An object specifying protocol parameters to be used.
     82    *
     83    * @throws asio::system_error Thrown on failure.
     84    */
     85   basic_stream_socket(asio::io_service& io_service,
     86       const protocol_type& protocol)
     87     : basic_socket<Protocol, StreamSocketService>(io_service, protocol)
     88   {
     89   }
     90 
     91   /// Construct a basic_stream_socket, opening it and binding it to the given
     92   /// local endpoint.
     93   /**
     94    * This constructor creates a stream socket and automatically opens it bound
     95    * to the specified endpoint on the local machine. The protocol used is the
     96    * protocol associated with the given endpoint.
     97    *
     98    * @param io_service The io_service object that the stream socket will use to
     99    * dispatch handlers for any asynchronous operations performed on the socket.
    100    *
    101    * @param endpoint An endpoint on the local machine to which the stream
    102    * socket will be bound.
    103    *
    104    * @throws asio::system_error Thrown on failure.
    105    */
    106   basic_stream_socket(asio::io_service& io_service,
    107       const endpoint_type& endpoint)
    108     : basic_socket<Protocol, StreamSocketService>(io_service, endpoint)
    109   {
    110   }
    111 
    112   /// Construct a basic_stream_socket on an existing native socket.
    113   /**
    114    * This constructor creates a stream socket object to hold an existing native
    115    * socket.
    116    *
    117    * @param io_service The io_service object that the stream socket will use to
    118    * dispatch handlers for any asynchronous operations performed on the socket.
    119    *
    120    * @param protocol An object specifying protocol parameters to be used.
    121    *
    122    * @param native_socket The new underlying socket implementation.
    123    *
    124    * @throws asio::system_error Thrown on failure.
    125    */
    126   basic_stream_socket(asio::io_service& io_service,
    127       const protocol_type& protocol, const native_handle_type& native_socket)
    128     : basic_socket<Protocol, StreamSocketService>(
    129         io_service, protocol, native_socket)
    130   {
    131   }
    132 
    133   /// Move-construct a basic_stream_socket from another.
    134   /**
    135    * This constructor moves a stream socket from one object to another.
    136    *
    137    * @param other The other basic_stream_socket object from which the move
    138    * will occur.
    139    *
    140    * @note Following the move, the moved-from object is in the same state as if
    141    * constructed using the @c basic_stream_socket(io_service&) constructor.
    142    */
    143   basic_stream_socket(basic_stream_socket&& other)
    144     : basic_socket<Protocol, StreamSocketService>(
    145         ASIO_MOVE_CAST(basic_stream_socket)(other))
    146   {
    147   }
    148 
    149   /// Move-assign a basic_stream_socket from another.
    150   /**
    151    * This assignment operator moves a stream socket from one object to another.
    152    *
    153    * @param other The other basic_stream_socket object from which the move
    154    * will occur.
    155    *
    156    * @note Following the move, the moved-from object is in the same state as if
    157    * constructed using the @c basic_stream_socket(io_service&) constructor.
    158    */
    159   basic_stream_socket& operator=(basic_stream_socket&& other)
    160   {
    161     basic_socket<Protocol, StreamSocketService>::operator=(
    162         ASIO_MOVE_CAST(basic_stream_socket)(other));
    163     return *this;
    164   }
    165 
    166   /// Move-construct a basic_stream_socket from a socket of another protocol
    167   /// type.
    168   /**
    169    * This constructor moves a stream socket from one object to another.
    170    *
    171    * @param other The other basic_stream_socket object from which the move
    172    * will occur.
    173    *
    174    * @note Following the move, the moved-from object is in the same state as if
    175    * constructed using the @c basic_stream_socket(io_service&) constructor.
    176    */
    177   template <typename Protocol1, typename StreamSocketService1>
    178   basic_stream_socket(
    179       basic_stream_socket<Protocol1, StreamSocketService1>&& other,
    180       typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
    181     : basic_socket<Protocol, StreamSocketService>(
    182         ASIO_MOVE_CAST2(basic_stream_socket<
    183           Protocol1, StreamSocketService1>)(other))
    184   {
    185   }
    186 
    187   /// Move-assign a basic_stream_socket from a socket of another protocol type.
    188   /**
    189    * This assignment operator moves a stream socket from one object to another.
    190    *
    191    * @param other The other basic_stream_socket object from which the move
    192    * will occur.
    193    *
    194    * @note Following the move, the moved-from object is in the same state as if
    195    * constructed using the @c basic_stream_socket(io_service&) constructor.
    196    */
    197   template <typename Protocol1, typename StreamSocketService1>
    198   typename enable_if<is_convertible<Protocol1, Protocol>::value,
    199       basic_stream_socket>::type& operator=(
    200         basic_stream_socket<Protocol1, StreamSocketService1>&& other)
    201   {
    202     basic_socket<Protocol, StreamSocketService>::operator=(
    203         ASIO_MOVE_CAST2(basic_stream_socket<
    204           Protocol1, StreamSocketService1>)(other));
    205     return *this;
    206   }
    207 
    208   /// Send some data on the socket.
    209   /**
    210    * This function is used to send data on the stream socket. The function
    211    * call will block until one or more bytes of the data has been sent
    212    * successfully, or an until error occurs.
    213    *
    214    * @param buffers One or more data buffers to be sent on the socket.
    215    *
    216    * @returns The number of bytes sent.
    217    *
    218    * @throws asio::system_error Thrown on failure.
    219    *
    220    * @note The send operation may not transmit all of the data to the peer.
    221    * Consider using the @ref write function if you need to ensure that all data
    222    * is written before the blocking operation completes.
    223    *
    224    * @par Example
    225    * To send a single data buffer use the @ref buffer function as follows:
    226    * @code
    227    * socket.send(asio::buffer(data, size));
    228    * @endcode
    229    * See the @ref buffer documentation for information on sending multiple
    230    * buffers in one go, and how to use it with arrays, boost::array or
    231    * std::vector.
    232    */
    233   template <typename ConstBufferSequence>
    234   std::size_t send(const ConstBufferSequence& buffers)
    235   {
    236     asio::error_code ec;
    237     std::size_t s = this->get_service().send(
    238         this->get_implementation(), buffers, 0, ec);
    239     asio::detail::throw_error(ec, "send");
    240     return s;
    241   }
    242 
    243   /// Send some data on the socket.
    244   /**
    245    * This function is used to send data on the stream socket. The function
    246    * call will block until one or more bytes of the data has been sent
    247    * successfully, or an until error occurs.
    248    *
    249    * @param buffers One or more data buffers to be sent on the socket.
    250    *
    251    * @param flags Flags specifying how the send call is to be made.
    252    *
    253    * @returns The number of bytes sent.
    254    *
    255    * @throws asio::system_error Thrown on failure.
    256    *
    257    * @note The send operation may not transmit all of the data to the peer.
    258    * Consider using the @ref write function if you need to ensure that all data
    259    * is written before the blocking operation completes.
    260    *
    261    * @par Example
    262    * To send a single data buffer use the @ref buffer function as follows:
    263    * @code
    264    * socket.send(asio::buffer(data, size), 0);
    265    * @endcode
    266    * See the @ref buffer documentation for information on sending multiple
    267    * buffers in one go, and how to use it with arrays, boost::array or
    268    * std::vector.
    269    */
    270   template <typename ConstBufferSequence>
    271   std::size_t send(const ConstBufferSequence& buffers,
    272       socket_base::message_flags flags)
    273   {
    274     asio::error_code ec;
    275     std::size_t s = this->get_service().send(
    276         this->get_implementation(), buffers, flags, ec);
    277     asio::detail::throw_error(ec, "send");
    278     return s;
    279   }
    280 
    281   /// Send some data on the socket.
    282   /**
    283    * This function is used to send data on the stream socket. The function
    284    * call will block until one or more bytes of the data has been sent
    285    * successfully, or an until error occurs.
    286    *
    287    * @param buffers One or more data buffers to be sent on the socket.
    288    *
    289    * @param flags Flags specifying how the send call is to be made.
    290    *
    291    * @param ec Set to indicate what error occurred, if any.
    292    *
    293    * @returns The number of bytes sent. Returns 0 if an error occurred.
    294    *
    295    * @note The send operation may not transmit all of the data to the peer.
    296    * Consider using the @ref write function if you need to ensure that all data
    297    * is written before the blocking operation completes.
    298    */
    299   template <typename ConstBufferSequence>
    300   std::size_t send(const ConstBufferSequence& buffers,
    301       socket_base::message_flags flags, asio::error_code& ec)
    302   {
    303     return this->get_service().send(
    304         this->get_implementation(), buffers, flags, ec);
    305   }
    306 
    307   /// Start an asynchronous send.
    308   /**
    309    * This function is used to asynchronously send data on the stream socket.
    310    * The function call always returns immediately.
    311    *
    312    * @param buffers One or more data buffers to be sent on the socket. Although
    313    * the buffers object may be copied as necessary, ownership of the underlying
    314    * memory blocks is retained by the caller, which must guarantee that they
    315    * remain valid until the handler is called.
    316    *
    317    * @param handler The handler to be called when the send operation completes.
    318    * Copies will be made of the handler as required. The function signature of
    319    * the handler must be:
    320    * @code void handler(
    321    *   const asio::error_code& error, // Result of operation.
    322    *   std::size_t bytes_transferred           // Number of bytes sent.
    323    * ); @endcode
    324    * Regardless of whether the asynchronous operation completes immediately or
    325    * not, the handler will not be invoked from within this function. Invocation
    326    * of the handler will be performed in a manner equivalent to using
    327    * asio::io_service::post().
    328    *
    329    * @note The send operation may not transmit all of the data to the peer.
    330    * Consider using the @ref async_write function if you need to ensure that all
    331    * data is written before the asynchronous operation completes.
    332    *
    333    * @par Example
    334    * To send a single data buffer use the @ref buffer function as follows:
    335    * @code
    336    * socket.async_send(asio::buffer(data, size), handler);
    337    * @endcode
    338    * See the @ref buffer documentation for information on sending multiple
    339    * buffers in one go, and how to use it with arrays, boost::array or
    340    * std::vector.
    341    */
    342   template <typename ConstBufferSequence, typename WriteHandler>
    343   ASIO_INITFN_RESULT_TYPE(WriteHandler,
    344       void (asio::error_code, std::size_t))
    345   async_send(const ConstBufferSequence& buffers,
    346       ASIO_MOVE_ARG(WriteHandler) handler)
    347   {
    348     // If you get an error on the following line it means that your handler does
    349     // not meet the documented type requirements for a WriteHandler.
    350     ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
    351 
    352     return this->get_service().async_send(
    353         this->get_implementation(), buffers, 0,
    354         ASIO_MOVE_CAST(WriteHandler)(handler));
    355   }
    356 
    357   /// Start an asynchronous send.
    358   /**
    359    * This function is used to asynchronously send data on the stream socket.
    360    * The function call always returns immediately.
    361    *
    362    * @param buffers One or more data buffers to be sent on the socket. Although
    363    * the buffers object may be copied as necessary, ownership of the underlying
    364    * memory blocks is retained by the caller, which must guarantee that they
    365    * remain valid until the handler is called.
    366    *
    367    * @param flags Flags specifying how the send call is to be made.
    368    *
    369    * @param handler The handler to be called when the send operation completes.
    370    * Copies will be made of the handler as required. The function signature of
    371    * the handler must be:
    372    * @code void handler(
    373    *   const asio::error_code& error, // Result of operation.
    374    *   std::size_t bytes_transferred           // Number of bytes sent.
    375    * ); @endcode
    376    * Regardless of whether the asynchronous operation completes immediately or
    377    * not, the handler will not be invoked from within this function. Invocation
    378    * of the handler will be performed in a manner equivalent to using
    379    * asio::io_service::post().
    380    *
    381    * @note The send operation may not transmit all of the data to the peer.
    382    * Consider using the @ref async_write function if you need to ensure that all
    383    * data is written before the asynchronous operation completes.
    384    *
    385    * @par Example
    386    * To send a single data buffer use the @ref buffer function as follows:
    387    * @code
    388    * socket.async_send(asio::buffer(data, size), 0, handler);
    389    * @endcode
    390    * See the @ref buffer documentation for information on sending multiple
    391    * buffers in one go, and how to use it with arrays, boost::array or
    392    * std::vector.
    393    */
    394   template <typename ConstBufferSequence, typename WriteHandler>
    395   ASIO_INITFN_RESULT_TYPE(WriteHandler,
    396       void (asio::error_code, std::size_t))
    397   async_send(const ConstBufferSequence& buffers,
    398       socket_base::message_flags flags,
    399       ASIO_MOVE_ARG(WriteHandler) handler)
    400   {
    401     // If you get an error on the following line it means that your handler does
    402     // not meet the documented type requirements for a WriteHandler.
    403     ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
    404 
    405     return this->get_service().async_send(
    406         this->get_implementation(), buffers, flags,
    407         ASIO_MOVE_CAST(WriteHandler)(handler));
    408   }
    409 
    410   /// Receive some data on the socket.
    411   /**
    412    * This function is used to receive data on the stream socket. The function
    413    * call will block until one or more bytes of data has been received
    414    * successfully, or until an error occurs.
    415    *
    416    * @param buffers One or more buffers into which the data will be received.
    417    *
    418    * @returns The number of bytes received.
    419    *
    420    * @throws asio::system_error Thrown on failure. An error code of
    421    * asio::error::eof indicates that the connection was closed by the
    422    * peer.
    423    *
    424    * @note The receive operation may not receive all of the requested number of
    425    * bytes. Consider using the @ref read function if you need to ensure that the
    426    * requested amount of data is read before the blocking operation completes.
    427    *
    428    * @par Example
    429    * To receive into a single data buffer use the @ref buffer function as
    430    * follows:
    431    * @code
    432    * socket.receive(asio::buffer(data, size));
    433    * @endcode
    434    * See the @ref buffer documentation for information on receiving into
    435    * multiple buffers in one go, and how to use it with arrays, boost::array or
    436    * std::vector.
    437    */
    438   template <typename MutableBufferSequence>
    439   std::size_t receive(const MutableBufferSequence& buffers)
    440   {
    441     asio::error_code ec;
    442     std::size_t s = this->get_service().receive(
    443         this->get_implementation(), buffers, 0, ec);
    444     asio::detail::throw_error(ec, "receive");
    445     return s;
    446   }
    447 
    448   /// Receive some data on the socket.
    449   /**
    450    * This function is used to receive data on the stream socket. The function
    451    * call will block until one or more bytes of data has been received
    452    * successfully, or until an error occurs.
    453    *
    454    * @param buffers One or more buffers into which the data will be received.
    455    *
    456    * @param flags Flags specifying how the receive call is to be made.
    457    *
    458    * @returns The number of bytes received.
    459    *
    460    * @throws asio::system_error Thrown on failure. An error code of
    461    * asio::error::eof indicates that the connection was closed by the
    462    * peer.
    463    *
    464    * @note The receive operation may not receive all of the requested number of
    465    * bytes. Consider using the @ref read function if you need to ensure that the
    466    * requested amount of data is read before the blocking operation completes.
    467    *
    468    * @par Example
    469    * To receive into a single data buffer use the @ref buffer function as
    470    * follows:
    471    * @code
    472    * socket.receive(asio::buffer(data, size), 0);
    473    * @endcode
    474    * See the @ref buffer documentation for information on receiving into
    475    * multiple buffers in one go, and how to use it with arrays, boost::array or
    476    * std::vector.
    477    */
    478   template <typename MutableBufferSequence>
    479   std::size_t receive(const MutableBufferSequence& buffers,
    480       socket_base::message_flags flags)
    481   {
    482     asio::error_code ec;
    483     std::size_t s = this->get_service().receive(
    484         this->get_implementation(), buffers, flags, ec);
    485     asio::detail::throw_error(ec, "receive");
    486     return s;
    487   }
    488 
    489   /// Receive some data on a connected socket.
    490   /**
    491    * This function is used to receive data on the stream socket. The function
    492    * call will block until one or more bytes of data has been received
    493    * successfully, or until an error occurs.
    494    *
    495    * @param buffers One or more buffers into which the data will be received.
    496    *
    497    * @param flags Flags specifying how the receive call is to be made.
    498    *
    499    * @param ec Set to indicate what error occurred, if any.
    500    *
    501    * @returns The number of bytes received. Returns 0 if an error occurred.
    502    *
    503    * @note The receive operation may not receive all of the requested number of
    504    * bytes. Consider using the @ref read function if you need to ensure that the
    505    * requested amount of data is read before the blocking operation completes.
    506    */
    507   template <typename MutableBufferSequence>
    508   std::size_t receive(const MutableBufferSequence& buffers,
    509       socket_base::message_flags flags, asio::error_code& ec)
    510   {
    511     return this->get_service().receive(
    512         this->get_implementation(), buffers, flags, ec);
    513   }
    514 
    515   /// Start an asynchronous receive.
    516   /**
    517    * This function is used to asynchronously receive data from the stream
    518    * socket. The function call always returns immediately.
    519    *
    520    * @param buffers One or more buffers into which the data will be received.
    521    * Although the buffers object may be copied as necessary, ownership of the
    522    * underlying memory blocks is retained by the caller, which must guarantee
    523    * that they remain valid until the handler is called.
    524    *
    525    * @param handler The handler to be called when the receive operation
    526    * completes. Copies will be made of the handler as required. The function
    527    * signature of the handler must be:
    528    * @code void handler(
    529    *   const asio::error_code& error, // Result of operation.
    530    *   std::size_t bytes_transferred           // Number of bytes received.
    531    * ); @endcode
    532    * Regardless of whether the asynchronous operation completes immediately or
    533    * not, the handler will not be invoked from within this function. Invocation
    534    * of the handler will be performed in a manner equivalent to using
    535    * asio::io_service::post().
    536    *
    537    * @note The receive operation may not receive all of the requested number of
    538    * bytes. Consider using the @ref async_read function if you need to ensure
    539    * that the requested amount of data is received before the asynchronous
    540    * operation completes.
    541    *
    542    * @par Example
    543    * To receive into a single data buffer use the @ref buffer function as
    544    * follows:
    545    * @code
    546    * socket.async_receive(asio::buffer(data, size), handler);
    547    * @endcode
    548    * See the @ref buffer documentation for information on receiving into
    549    * multiple buffers in one go, and how to use it with arrays, boost::array or
    550    * std::vector.
    551    */
    552   template <typename MutableBufferSequence, typename ReadHandler>
    553   ASIO_INITFN_RESULT_TYPE(ReadHandler,
    554       void (asio::error_code, std::size_t))
    555   async_receive(const MutableBufferSequence& buffers,
    556       ASIO_MOVE_ARG(ReadHandler) handler)
    557   {
    558     // If you get an error on the following line it means that your handler does
    559     // not meet the documented type requirements for a ReadHandler.
    560     ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
    561 
    562     return this->get_service().async_receive(this->get_implementation(),
    563         buffers, 0, ASIO_MOVE_CAST(ReadHandler)(handler));
    564   }
    565 
    566   /// Start an asynchronous receive.
    567   /**
    568    * This function is used to asynchronously receive data from the stream
    569    * socket. The function call always returns immediately.
    570    *
    571    * @param buffers One or more buffers into which the data will be received.
    572    * Although the buffers object may be copied as necessary, ownership of the
    573    * underlying memory blocks is retained by the caller, which must guarantee
    574    * that they remain valid until the handler is called.
    575    *
    576    * @param flags Flags specifying how the receive call is to be made.
    577    *
    578    * @param handler The handler to be called when the receive operation
    579    * completes. Copies will be made of the handler as required. The function
    580    * signature of the handler must be:
    581    * @code void handler(
    582    *   const asio::error_code& error, // Result of operation.
    583    *   std::size_t bytes_transferred           // Number of bytes received.
    584    * ); @endcode
    585    * Regardless of whether the asynchronous operation completes immediately or
    586    * not, the handler will not be invoked from within this function. Invocation
    587    * of the handler will be performed in a manner equivalent to using
    588    * asio::io_service::post().
    589    *
    590    * @note The receive operation may not receive all of the requested number of
    591    * bytes. Consider using the @ref async_read function if you need to ensure
    592    * that the requested amount of data is received before the asynchronous
    593    * operation completes.
    594    *
    595    * @par Example
    596    * To receive into a single data buffer use the @ref buffer function as
    597    * follows:
    598    * @code
    599    * socket.async_receive(asio::buffer(data, size), 0, handler);
    600    * @endcode
    601    * See the @ref buffer documentation for information on receiving into
    602    * multiple buffers in one go, and how to use it with arrays, boost::array or
    603    * std::vector.
    604    */
    605   template <typename MutableBufferSequence, typename ReadHandler>
    606   ASIO_INITFN_RESULT_TYPE(ReadHandler,
    607       void (asio::error_code, std::size_t))
    608   async_receive(const MutableBufferSequence& buffers,
    609       socket_base::message_flags flags,
    610       ASIO_MOVE_ARG(ReadHandler) handler)
    611   {
    612     // If you get an error on the following line it means that your handler does
    613     // not meet the documented type requirements for a ReadHandler.
    614     ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
    615 
    616     return this->get_service().async_receive(this->get_implementation(),
    617         buffers, flags, ASIO_MOVE_CAST(ReadHandler)(handler));
    618   }
    619 
    620   /// Write some data to the socket.
    621   /**
    622    * This function is used to write data to the stream socket. The function call
    623    * will block until one or more bytes of the data has been written
    624    * successfully, or until an error occurs.
    625    *
    626    * @param buffers One or more data buffers to be written to the socket.
    627    *
    628    * @returns The number of bytes written.
    629    *
    630    * @throws asio::system_error Thrown on failure. An error code of
    631    * asio::error::eof indicates that the connection was closed by the
    632    * peer.
    633    *
    634    * @note The write_some operation may not transmit all of the data to the
    635    * peer. Consider using the @ref write function if you need to ensure that
    636    * all data is written before the blocking operation completes.
    637    *
    638    * @par Example
    639    * To write a single data buffer use the @ref buffer function as follows:
    640    * @code
    641    * socket.write_some(asio::buffer(data, size));
    642    * @endcode
    643    * See the @ref buffer documentation for information on writing multiple
    644    * buffers in one go, and how to use it with arrays, boost::array or
    645    * std::vector.
    646    */
    647   template <typename ConstBufferSequence>
    648   std::size_t write_some(const ConstBufferSequence& buffers)
    649   {
    650     asio::error_code ec;
    651     std::size_t s = this->get_service().send(
    652         this->get_implementation(), buffers, 0, ec);
    653     asio::detail::throw_error(ec, "write_some");
    654     return s;
    655   }
    656 
    657   /// Write some data to the socket.
    658   /**
    659    * This function is used to write data to the stream socket. The function call
    660    * will block until one or more bytes of the data has been written
    661    * successfully, or until an error occurs.
    662    *
    663    * @param buffers One or more data buffers to be written to the socket.
    664    *
    665    * @param ec Set to indicate what error occurred, if any.
    666    *
    667    * @returns The number of bytes written. Returns 0 if an error occurred.
    668    *
    669    * @note The write_some operation may not transmit all of the data to the
    670    * peer. Consider using the @ref write function if you need to ensure that
    671    * all data is written before the blocking operation completes.
    672    */
    673   template <typename ConstBufferSequence>
    674   std::size_t write_some(const ConstBufferSequence& buffers,
    675       asio::error_code& ec)
    676   {
    677     return this->get_service().send(this->get_implementation(), buffers, 0, ec);
    678   }
    679 
    680   /// Start an asynchronous write.
    681   /**
    682    * This function is used to asynchronously write data to the stream socket.
    683    * The function call always returns immediately.
    684    *
    685    * @param buffers One or more data buffers to be written to the socket.
    686    * Although the buffers object may be copied as necessary, ownership of the
    687    * underlying memory blocks is retained by the caller, which must guarantee
    688    * that they remain valid until the handler is called.
    689    *
    690    * @param handler The handler to be called when the write operation completes.
    691    * Copies will be made of the handler as required. The function signature of
    692    * the handler must be:
    693    * @code void handler(
    694    *   const asio::error_code& error, // Result of operation.
    695    *   std::size_t bytes_transferred           // Number of bytes written.
    696    * ); @endcode
    697    * Regardless of whether the asynchronous operation completes immediately or
    698    * not, the handler will not be invoked from within this function. Invocation
    699    * of the handler will be performed in a manner equivalent to using
    700    * asio::io_service::post().
    701    *
    702    * @note The write operation may not transmit all of the data to the peer.
    703    * Consider using the @ref async_write function if you need to ensure that all
    704    * data is written before the asynchronous operation completes.
    705    *
    706    * @par Example
    707    * To write a single data buffer use the @ref buffer function as follows:
    708    * @code
    709    * socket.async_write_some(asio::buffer(data, size), handler);
    710    * @endcode
    711    * See the @ref buffer documentation for information on writing multiple
    712    * buffers in one go, and how to use it with arrays, boost::array or
    713    * std::vector.
    714    */
    715   template <typename ConstBufferSequence, typename WriteHandler>
    716   ASIO_INITFN_RESULT_TYPE(WriteHandler,
    717       void (asio::error_code, std::size_t))
    718   async_write_some(const ConstBufferSequence& buffers,
    719       ASIO_MOVE_ARG(WriteHandler) handler)
    720   {
    721     // If you get an error on the following line it means that your handler does
    722     // not meet the documented type requirements for a WriteHandler.
    723     ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
    724 
    725     return this->get_service().async_send(this->get_implementation(),
    726         buffers, 0, ASIO_MOVE_CAST(WriteHandler)(handler));
    727   }
    728 
    729   /// Read some data from the socket.
    730   /**
    731    * This function is used to read data from the stream socket. The function
    732    * call will block until one or more bytes of data has been read successfully,
    733    * or until an error occurs.
    734    *
    735    * @param buffers One or more buffers into which the data will be read.
    736    *
    737    * @returns The number of bytes read.
    738    *
    739    * @throws asio::system_error Thrown on failure. An error code of
    740    * asio::error::eof indicates that the connection was closed by the
    741    * peer.
    742    *
    743    * @note The read_some operation may not read all of the requested number of
    744    * bytes. Consider using the @ref read function if you need to ensure that
    745    * the requested amount of data is read before the blocking operation
    746    * completes.
    747    *
    748    * @par Example
    749    * To read into a single data buffer use the @ref buffer function as follows:
    750    * @code
    751    * socket.read_some(asio::buffer(data, size));
    752    * @endcode
    753    * See the @ref buffer documentation for information on reading into multiple
    754    * buffers in one go, and how to use it with arrays, boost::array or
    755    * std::vector.
    756    */
    757   template <typename MutableBufferSequence>
    758   std::size_t read_some(const MutableBufferSequence& buffers)
    759   {
    760     asio::error_code ec;
    761     std::size_t s = this->get_service().receive(
    762         this->get_implementation(), buffers, 0, ec);
    763     asio::detail::throw_error(ec, "read_some");
    764     return s;
    765   }
    766 
    767   /// Read some data from the socket.
    768   /**
    769    * This function is used to read data from the stream socket. The function
    770    * call will block until one or more bytes of data has been read successfully,
    771    * or until an error occurs.
    772    *
    773    * @param buffers One or more buffers into which the data will be read.
    774    *
    775    * @param ec Set to indicate what error occurred, if any.
    776    *
    777    * @returns The number of bytes read. Returns 0 if an error occurred.
    778    *
    779    * @note The read_some operation may not read all of the requested number of
    780    * bytes. Consider using the @ref read function if you need to ensure that
    781    * the requested amount of data is read before the blocking operation
    782    * completes.
    783    */
    784   template <typename MutableBufferSequence>
    785   std::size_t read_some(const MutableBufferSequence& buffers,
    786       asio::error_code& ec)
    787   {
    788     return this->get_service().receive(
    789         this->get_implementation(), buffers, 0, ec);
    790   }
    791 
    792   /// Start an asynchronous read.
    793   /**
    794    * This function is used to asynchronously read data from the stream socket.
    795    * The function call always returns immediately.
    796    *
    797    * @param buffers One or more buffers into which the data will be read.
    798    * Although the buffers object may be copied as necessary, ownership of the
    799    * underlying memory blocks is retained by the caller, which must guarantee
    800    * that they remain valid until the handler is called.
    801    *
    802    * @param handler The handler to be called when the read operation completes.
    803    * Copies will be made of the handler as required. The function signature of
    804    * the handler must be:
    805    * @code void handler(
    806    *   const asio::error_code& error, // Result of operation.
    807    *   std::size_t bytes_transferred           // Number of bytes read.
    808    * ); @endcode
    809    * Regardless of whether the asynchronous operation completes immediately or
    810    * not, the handler will not be invoked from within this function. Invocation
    811    * of the handler will be performed in a manner equivalent to using
    812    * asio::io_service::post().
    813    *
    814    * @note The read operation may not read all of the requested number of bytes.
    815    * Consider using the @ref async_read function if you need to ensure that the
    816    * requested amount of data is read before the asynchronous operation
    817    * completes.
    818    *
    819    * @par Example
    820    * To read into a single data buffer use the @ref buffer function as follows:
    821    * @code
    822    * socket.async_read_some(asio::buffer(data, size), handler);
    823    * @endcode
    824    * See the @ref buffer documentation for information on reading into multiple
    825    * buffers in one go, and how to use it with arrays, boost::array or
    826    * std::vector.
    827    */
    828   template <typename MutableBufferSequence, typename ReadHandler>
    829   ASIO_INITFN_RESULT_TYPE(ReadHandler,
    830       void (asio::error_code, std::size_t))
    831   async_read_some(const MutableBufferSequence& buffers,
    832       ASIO_MOVE_ARG(ReadHandler) handler)
    833   {
    834     // If you get an error on the following line it means that your handler does
    835     // not meet the documented type requirements for a ReadHandler.
    836     ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
    837 
    838     return this->get_service().async_receive(this->get_implementation(),
    839         buffers, 0, ASIO_MOVE_CAST(ReadHandler)(handler));
    840   }
    841 };
    842 
    843 } // namespace asio
    844 
    845 #include "asio/detail/pop_options.hpp"
    846 
    847 #endif // ASIO_BASIC_STREAM_SOCKET_HPP
    848