Imported Upstream version 1.57.0
[platform/upstream/boost.git] / boost / asio / basic_socket.hpp
1 //
2 // basic_socket.hpp
3 // ~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2014 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
29 namespace boost {
30 namespace 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  */
41 template <typename Protocol, typename SocketService>
42 class basic_socket
43   : public basic_io_object<SocketService>,
44     public socket_base
45 {
46 public:
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 = socket.remote_endpoint();
1419    * @endcode
1420    */
1421   endpoint_type remote_endpoint() const
1422   {
1423     boost::system::error_code ec;
1424     endpoint_type ep = this->get_service().remote_endpoint(
1425         this->get_implementation(), ec);
1426     boost::asio::detail::throw_error(ec, "remote_endpoint");
1427     return ep;
1428   }
1429
1430   /// Get the remote endpoint of the socket.
1431   /**
1432    * This function is used to obtain the remote endpoint of the socket.
1433    *
1434    * @param ec Set to indicate what error occurred, if any.
1435    *
1436    * @returns An object that represents the remote endpoint of the socket.
1437    * Returns a default-constructed endpoint object if an error occurred.
1438    *
1439    * @par Example
1440    * @code
1441    * boost::asio::ip::tcp::socket socket(io_service);
1442    * ...
1443    * boost::system::error_code ec;
1444    * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec);
1445    * if (ec)
1446    * {
1447    *   // An error occurred.
1448    * }
1449    * @endcode
1450    */
1451   endpoint_type remote_endpoint(boost::system::error_code& ec) const
1452   {
1453     return this->get_service().remote_endpoint(this->get_implementation(), ec);
1454   }
1455
1456   /// Disable sends or receives on the socket.
1457   /**
1458    * This function is used to disable send operations, receive operations, or
1459    * both.
1460    *
1461    * @param what Determines what types of operation will no longer be allowed.
1462    *
1463    * @throws boost::system::system_error Thrown on failure.
1464    *
1465    * @par Example
1466    * Shutting down the send side of the socket:
1467    * @code
1468    * boost::asio::ip::tcp::socket socket(io_service);
1469    * ...
1470    * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send);
1471    * @endcode
1472    */
1473   void shutdown(shutdown_type what)
1474   {
1475     boost::system::error_code ec;
1476     this->get_service().shutdown(this->get_implementation(), what, ec);
1477     boost::asio::detail::throw_error(ec, "shutdown");
1478   }
1479
1480   /// Disable sends or receives on the socket.
1481   /**
1482    * This function is used to disable send operations, receive operations, or
1483    * both.
1484    *
1485    * @param what Determines what types of operation will no longer be allowed.
1486    *
1487    * @param ec Set to indicate what error occurred, if any.
1488    *
1489    * @par Example
1490    * Shutting down the send side of the socket:
1491    * @code
1492    * boost::asio::ip::tcp::socket socket(io_service);
1493    * ...
1494    * boost::system::error_code ec;
1495    * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec);
1496    * if (ec)
1497    * {
1498    *   // An error occurred.
1499    * }
1500    * @endcode
1501    */
1502   boost::system::error_code shutdown(shutdown_type what,
1503       boost::system::error_code& ec)
1504   {
1505     return this->get_service().shutdown(this->get_implementation(), what, ec);
1506   }
1507
1508 protected:
1509   /// Protected destructor to prevent deletion through this type.
1510   ~basic_socket()
1511   {
1512   }
1513 };
1514
1515 } // namespace asio
1516 } // namespace boost
1517
1518 #include <boost/asio/detail/pop_options.hpp>
1519
1520 #endif // BOOST_ASIO_BASIC_SOCKET_HPP