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