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