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