Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / asio / basic_socket.hpp
1 //
2 // basic_socket.hpp
3 // ~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10
11 #ifndef BOOST_ASIO_BASIC_SOCKET_HPP
12 #define BOOST_ASIO_BASIC_SOCKET_HPP
13
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17
18 #include <boost/asio/detail/config.hpp>
19 #include <boost/asio/async_result.hpp>
20 #include <boost/asio/detail/handler_type_requirements.hpp>
21 #include <boost/asio/detail/io_object_impl.hpp>
22 #include <boost/asio/detail/non_const_lvalue.hpp>
23 #include <boost/asio/detail/throw_error.hpp>
24 #include <boost/asio/detail/type_traits.hpp>
25 #include <boost/asio/error.hpp>
26 #include <boost/asio/execution_context.hpp>
27 #include <boost/asio/executor.hpp>
28 #include <boost/asio/post.hpp>
29 #include <boost/asio/socket_base.hpp>
30
31 #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
32 # include <boost/asio/detail/null_socket_service.hpp>
33 #elif defined(BOOST_ASIO_HAS_IOCP)
34 # include <boost/asio/detail/win_iocp_socket_service.hpp>
35 #else
36 # include <boost/asio/detail/reactive_socket_service.hpp>
37 #endif
38
39 #if defined(BOOST_ASIO_HAS_MOVE)
40 # include <utility>
41 #endif // defined(BOOST_ASIO_HAS_MOVE)
42
43 #include <boost/asio/detail/push_options.hpp>
44
45 namespace boost {
46 namespace asio {
47
48 #if !defined(BOOST_ASIO_BASIC_SOCKET_FWD_DECL)
49 #define BOOST_ASIO_BASIC_SOCKET_FWD_DECL
50
51 // Forward declaration with defaulted arguments.
52 template <typename Protocol, typename Executor = executor>
53 class basic_socket;
54
55 #endif // !defined(BOOST_ASIO_BASIC_SOCKET_FWD_DECL)
56
57 /// Provides socket functionality.
58 /**
59  * The basic_socket class template provides functionality that is common to both
60  * stream-oriented and datagram-oriented sockets.
61  *
62  * @par Thread Safety
63  * @e Distinct @e objects: Safe.@n
64  * @e Shared @e objects: Unsafe.
65  */
66 template <typename Protocol, typename Executor>
67 class basic_socket
68   : public socket_base
69 {
70 public:
71   /// The type of the executor associated with the object.
72   typedef Executor executor_type;
73
74   /// Rebinds the socket type to another executor.
75   template <typename Executor1>
76   struct rebind_executor
77   {
78     /// The socket type when rebound to the specified executor.
79     typedef basic_socket<Protocol, Executor1> other;
80   };
81
82   /// The native representation of a socket.
83 #if defined(GENERATING_DOCUMENTATION)
84   typedef implementation_defined native_handle_type;
85 #elif defined(BOOST_ASIO_WINDOWS_RUNTIME)
86   typedef typename detail::null_socket_service<
87     Protocol>::native_handle_type native_handle_type;
88 #elif defined(BOOST_ASIO_HAS_IOCP)
89   typedef typename detail::win_iocp_socket_service<
90     Protocol>::native_handle_type native_handle_type;
91 #else
92   typedef typename detail::reactive_socket_service<
93     Protocol>::native_handle_type native_handle_type;
94 #endif
95
96   /// The protocol type.
97   typedef Protocol protocol_type;
98
99   /// The endpoint type.
100   typedef typename Protocol::endpoint endpoint_type;
101
102 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
103   /// A basic_socket is always the lowest layer.
104   typedef basic_socket<Protocol, Executor> lowest_layer_type;
105 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
106
107   /// Construct a basic_socket without opening it.
108   /**
109    * This constructor creates a socket without opening it.
110    *
111    * @param ex The I/O executor that the socket will use, by default, to
112    * dispatch handlers for any asynchronous operations performed on the socket.
113    */
114   explicit basic_socket(const executor_type& ex)
115     : impl_(ex)
116   {
117   }
118
119   /// Construct a basic_socket without opening it.
120   /**
121    * This constructor creates a socket without opening it.
122    *
123    * @param context An execution context which provides the I/O executor that
124    * the socket will use, by default, to dispatch handlers for any asynchronous
125    * operations performed on the socket.
126    */
127   template <typename ExecutionContext>
128   explicit basic_socket(ExecutionContext& context,
129       typename enable_if<
130         is_convertible<ExecutionContext&, execution_context&>::value
131       >::type* = 0)
132     : impl_(context)
133   {
134   }
135
136   /// Construct and open a basic_socket.
137   /**
138    * This constructor creates and opens a socket.
139    *
140    * @param ex The I/O executor that the socket will use, by default, to
141    * dispatch handlers for any asynchronous operations performed on the socket.
142    *
143    * @param protocol An object specifying protocol parameters to be used.
144    *
145    * @throws boost::system::system_error Thrown on failure.
146    */
147   basic_socket(const executor_type& ex, const protocol_type& protocol)
148     : impl_(ex)
149   {
150     boost::system::error_code ec;
151     impl_.get_service().open(impl_.get_implementation(), protocol, ec);
152     boost::asio::detail::throw_error(ec, "open");
153   }
154
155   /// Construct and open a basic_socket.
156   /**
157    * This constructor creates and opens a socket.
158    *
159    * @param context An execution context which provides the I/O executor that
160    * the socket will use, by default, to dispatch handlers for any asynchronous
161    * operations performed on the socket.
162    *
163    * @param protocol An object specifying protocol parameters to be used.
164    *
165    * @throws boost::system::system_error Thrown on failure.
166    */
167   template <typename ExecutionContext>
168   basic_socket(ExecutionContext& context, const protocol_type& protocol,
169       typename enable_if<
170         is_convertible<ExecutionContext&, execution_context&>::value
171       >::type* = 0)
172     : impl_(context)
173   {
174     boost::system::error_code ec;
175     impl_.get_service().open(impl_.get_implementation(), protocol, ec);
176     boost::asio::detail::throw_error(ec, "open");
177   }
178
179   /// Construct a basic_socket, opening it and binding it to the given local
180   /// endpoint.
181   /**
182    * This constructor creates a socket and automatically opens it bound to the
183    * specified endpoint on the local machine. The protocol used is the protocol
184    * associated with the given endpoint.
185    *
186    * @param ex The I/O executor that the socket will use, by default, to
187    * dispatch handlers for any asynchronous operations performed on the socket.
188    *
189    * @param endpoint An endpoint on the local machine to which the socket will
190    * be bound.
191    *
192    * @throws boost::system::system_error Thrown on failure.
193    */
194   basic_socket(const executor_type& ex, const endpoint_type& endpoint)
195     : impl_(ex)
196   {
197     boost::system::error_code ec;
198     const protocol_type protocol = endpoint.protocol();
199     impl_.get_service().open(impl_.get_implementation(), protocol, ec);
200     boost::asio::detail::throw_error(ec, "open");
201     impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
202     boost::asio::detail::throw_error(ec, "bind");
203   }
204
205   /// Construct a basic_socket, opening it and binding it to the given local
206   /// endpoint.
207   /**
208    * This constructor creates a socket and automatically opens it bound to the
209    * specified endpoint on the local machine. The protocol used is the protocol
210    * associated with the given endpoint.
211    *
212    * @param context An execution context which provides the I/O executor that
213    * the socket will use, by default, to dispatch handlers for any asynchronous
214    * operations performed on the socket.
215    *
216    * @param endpoint An endpoint on the local machine to which the socket will
217    * be bound.
218    *
219    * @throws boost::system::system_error Thrown on failure.
220    */
221   template <typename ExecutionContext>
222   basic_socket(ExecutionContext& context, const endpoint_type& endpoint,
223       typename enable_if<
224         is_convertible<ExecutionContext&, execution_context&>::value
225       >::type* = 0)
226     : impl_(context)
227   {
228     boost::system::error_code ec;
229     const protocol_type protocol = endpoint.protocol();
230     impl_.get_service().open(impl_.get_implementation(), protocol, ec);
231     boost::asio::detail::throw_error(ec, "open");
232     impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
233     boost::asio::detail::throw_error(ec, "bind");
234   }
235
236   /// Construct a basic_socket on an existing native socket.
237   /**
238    * This constructor creates a socket object to hold an existing native socket.
239    *
240    * @param ex The I/O executor that the socket will use, by default, to
241    * dispatch handlers for any asynchronous operations performed on the socket.
242    *
243    * @param protocol An object specifying protocol parameters to be used.
244    *
245    * @param native_socket A native socket.
246    *
247    * @throws boost::system::system_error Thrown on failure.
248    */
249   basic_socket(const executor_type& ex, const protocol_type& protocol,
250       const native_handle_type& native_socket)
251     : impl_(ex)
252   {
253     boost::system::error_code ec;
254     impl_.get_service().assign(impl_.get_implementation(),
255         protocol, native_socket, ec);
256     boost::asio::detail::throw_error(ec, "assign");
257   }
258
259   /// Construct a basic_socket on an existing native socket.
260   /**
261    * This constructor creates a socket object to hold an existing native socket.
262    *
263    * @param context An execution context which provides the I/O executor that
264    * the socket will use, by default, to dispatch handlers for any asynchronous
265    * operations performed on the socket.
266    *
267    * @param protocol An object specifying protocol parameters to be used.
268    *
269    * @param native_socket A native socket.
270    *
271    * @throws boost::system::system_error Thrown on failure.
272    */
273   template <typename ExecutionContext>
274   basic_socket(ExecutionContext& context, const protocol_type& protocol,
275       const native_handle_type& native_socket,
276       typename enable_if<
277         is_convertible<ExecutionContext&, execution_context&>::value
278       >::type* = 0)
279     : impl_(context)
280   {
281     boost::system::error_code ec;
282     impl_.get_service().assign(impl_.get_implementation(),
283         protocol, native_socket, ec);
284     boost::asio::detail::throw_error(ec, "assign");
285   }
286
287 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
288   /// Move-construct a basic_socket from another.
289   /**
290    * This constructor moves a socket from one object to another.
291    *
292    * @param other The other basic_socket object from which the move will
293    * occur.
294    *
295    * @note Following the move, the moved-from object is in the same state as if
296    * constructed using the @c basic_socket(const executor_type&) constructor.
297    */
298   basic_socket(basic_socket&& other) BOOST_ASIO_NOEXCEPT
299     : impl_(std::move(other.impl_))
300   {
301   }
302
303   /// Move-assign a basic_socket from another.
304   /**
305    * This assignment operator moves a socket from one object to another.
306    *
307    * @param other The other basic_socket object from which the move will
308    * occur.
309    *
310    * @note Following the move, the moved-from object is in the same state as if
311    * constructed using the @c basic_socket(const executor_type&) constructor.
312    */
313   basic_socket& operator=(basic_socket&& other)
314   {
315     impl_ = std::move(other.impl_);
316     return *this;
317   }
318
319   // All sockets have access to each other's implementations.
320   template <typename Protocol1, typename Executor1>
321   friend class basic_socket;
322
323   /// Move-construct a basic_socket from a socket of another protocol type.
324   /**
325    * This constructor moves a socket from one object to another.
326    *
327    * @param other The other basic_socket object from which the move will
328    * occur.
329    *
330    * @note Following the move, the moved-from object is in the same state as if
331    * constructed using the @c basic_socket(const executor_type&) constructor.
332    */
333   template <typename Protocol1, typename Executor1>
334   basic_socket(basic_socket<Protocol1, Executor1>&& other,
335       typename enable_if<
336         is_convertible<Protocol1, Protocol>::value
337           && is_convertible<Executor1, Executor>::value
338       >::type* = 0)
339     : impl_(std::move(other.impl_))
340   {
341   }
342
343   /// Move-assign a basic_socket from a socket of another protocol type.
344   /**
345    * This assignment operator moves a socket from one object to another.
346    *
347    * @param other The other basic_socket object from which the move will
348    * occur.
349    *
350    * @note Following the move, the moved-from object is in the same state as if
351    * constructed using the @c basic_socket(const executor_type&) constructor.
352    */
353   template <typename Protocol1, typename Executor1>
354   typename enable_if<
355     is_convertible<Protocol1, Protocol>::value
356       && is_convertible<Executor1, Executor>::value,
357     basic_socket&
358   >::type operator=(basic_socket<Protocol1, Executor1> && other)
359   {
360     basic_socket tmp(std::move(other));
361     impl_ = std::move(tmp.impl_);
362     return *this;
363   }
364 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
365
366   /// Get the executor associated with the object.
367   executor_type get_executor() BOOST_ASIO_NOEXCEPT
368   {
369     return impl_.get_executor();
370   }
371
372 #if !defined(BOOST_ASIO_NO_EXTENSIONS)
373   /// Get a reference to the lowest layer.
374   /**
375    * This function returns a reference to the lowest layer in a stack of
376    * layers. Since a basic_socket cannot contain any further layers, it simply
377    * returns a reference to itself.
378    *
379    * @return A reference to the lowest layer in the stack of layers. Ownership
380    * is not transferred to the caller.
381    */
382   lowest_layer_type& lowest_layer()
383   {
384     return *this;
385   }
386
387   /// Get a const reference to the lowest layer.
388   /**
389    * This function returns a const reference to the lowest layer in a stack of
390    * layers. Since a basic_socket cannot contain any further layers, it simply
391    * returns a reference to itself.
392    *
393    * @return A const reference to the lowest layer in the stack of layers.
394    * Ownership is not transferred to the caller.
395    */
396   const lowest_layer_type& lowest_layer() const
397   {
398     return *this;
399   }
400 #endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
401
402   /// Open the socket using the specified protocol.
403   /**
404    * This function opens the socket so that it will use the specified protocol.
405    *
406    * @param protocol An object specifying protocol parameters to be used.
407    *
408    * @throws boost::system::system_error Thrown on failure.
409    *
410    * @par Example
411    * @code
412    * boost::asio::ip::tcp::socket socket(my_context);
413    * socket.open(boost::asio::ip::tcp::v4());
414    * @endcode
415    */
416   void open(const protocol_type& protocol = protocol_type())
417   {
418     boost::system::error_code ec;
419     impl_.get_service().open(impl_.get_implementation(), protocol, ec);
420     boost::asio::detail::throw_error(ec, "open");
421   }
422
423   /// Open the socket using the specified protocol.
424   /**
425    * This function opens the socket so that it will use the specified protocol.
426    *
427    * @param protocol An object specifying which protocol is to be used.
428    *
429    * @param ec Set to indicate what error occurred, if any.
430    *
431    * @par Example
432    * @code
433    * boost::asio::ip::tcp::socket socket(my_context);
434    * boost::system::error_code ec;
435    * socket.open(boost::asio::ip::tcp::v4(), ec);
436    * if (ec)
437    * {
438    *   // An error occurred.
439    * }
440    * @endcode
441    */
442   BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol,
443       boost::system::error_code& ec)
444   {
445     impl_.get_service().open(impl_.get_implementation(), protocol, ec);
446     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
447   }
448
449   /// Assign an existing native socket to the socket.
450   /*
451    * This function opens the socket to hold an existing native socket.
452    *
453    * @param protocol An object specifying which protocol is to be used.
454    *
455    * @param native_socket A native socket.
456    *
457    * @throws boost::system::system_error Thrown on failure.
458    */
459   void assign(const protocol_type& protocol,
460       const native_handle_type& native_socket)
461   {
462     boost::system::error_code ec;
463     impl_.get_service().assign(impl_.get_implementation(),
464         protocol, native_socket, ec);
465     boost::asio::detail::throw_error(ec, "assign");
466   }
467
468   /// Assign an existing native socket to the socket.
469   /*
470    * This function opens the socket to hold an existing native socket.
471    *
472    * @param protocol An object specifying which protocol is to be used.
473    *
474    * @param native_socket A native socket.
475    *
476    * @param ec Set to indicate what error occurred, if any.
477    */
478   BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol,
479       const native_handle_type& native_socket, boost::system::error_code& ec)
480   {
481     impl_.get_service().assign(impl_.get_implementation(),
482         protocol, native_socket, ec);
483     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
484   }
485
486   /// Determine whether the socket is open.
487   bool is_open() const
488   {
489     return impl_.get_service().is_open(impl_.get_implementation());
490   }
491
492   /// Close the socket.
493   /**
494    * This function is used to close the socket. Any asynchronous send, receive
495    * or connect operations will be cancelled immediately, and will complete
496    * with the boost::asio::error::operation_aborted error.
497    *
498    * @throws boost::system::system_error Thrown on failure. Note that, even if
499    * the function indicates an error, the underlying descriptor is closed.
500    *
501    * @note For portable behaviour with respect to graceful closure of a
502    * connected socket, call shutdown() before closing the socket.
503    */
504   void close()
505   {
506     boost::system::error_code ec;
507     impl_.get_service().close(impl_.get_implementation(), ec);
508     boost::asio::detail::throw_error(ec, "close");
509   }
510
511   /// Close the socket.
512   /**
513    * This function is used to close the socket. Any asynchronous send, receive
514    * or connect operations will be cancelled immediately, and will complete
515    * with the boost::asio::error::operation_aborted error.
516    *
517    * @param ec Set to indicate what error occurred, if any. Note that, even if
518    * the function indicates an error, the underlying descriptor is closed.
519    *
520    * @par Example
521    * @code
522    * boost::asio::ip::tcp::socket socket(my_context);
523    * ...
524    * boost::system::error_code ec;
525    * socket.close(ec);
526    * if (ec)
527    * {
528    *   // An error occurred.
529    * }
530    * @endcode
531    *
532    * @note For portable behaviour with respect to graceful closure of a
533    * connected socket, call shutdown() before closing the socket.
534    */
535   BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
536   {
537     impl_.get_service().close(impl_.get_implementation(), ec);
538     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
539   }
540
541   /// Release ownership of the underlying native socket.
542   /**
543    * This function causes all outstanding asynchronous connect, send and receive
544    * operations to finish immediately, and the handlers for cancelled operations
545    * will be passed the boost::asio::error::operation_aborted error. Ownership
546    * of the native socket is then transferred to the caller.
547    *
548    * @throws boost::system::system_error Thrown on failure.
549    *
550    * @note This function is unsupported on Windows versions prior to Windows
551    * 8.1, and will fail with boost::asio::error::operation_not_supported on
552    * these platforms.
553    */
554 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
555   && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
556   __declspec(deprecated("This function always fails with "
557         "operation_not_supported when used on Windows versions "
558         "prior to Windows 8.1."))
559 #endif
560   native_handle_type release()
561   {
562     boost::system::error_code ec;
563     native_handle_type s = impl_.get_service().release(
564         impl_.get_implementation(), ec);
565     boost::asio::detail::throw_error(ec, "release");
566     return s;
567   }
568
569   /// Release ownership of the underlying native socket.
570   /**
571    * This function causes all outstanding asynchronous connect, send and receive
572    * operations to finish immediately, and the handlers for cancelled operations
573    * will be passed the boost::asio::error::operation_aborted error. Ownership
574    * of the native socket is then transferred to the caller.
575    *
576    * @param ec Set to indicate what error occurred, if any.
577    *
578    * @note This function is unsupported on Windows versions prior to Windows
579    * 8.1, and will fail with boost::asio::error::operation_not_supported on
580    * these platforms.
581    */
582 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
583   && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
584   __declspec(deprecated("This function always fails with "
585         "operation_not_supported when used on Windows versions "
586         "prior to Windows 8.1."))
587 #endif
588   native_handle_type release(boost::system::error_code& ec)
589   {
590     return impl_.get_service().release(impl_.get_implementation(), ec);
591   }
592
593   /// Get the native socket representation.
594   /**
595    * This function may be used to obtain the underlying representation of the
596    * socket. This is intended to allow access to native socket functionality
597    * that is not otherwise provided.
598    */
599   native_handle_type native_handle()
600   {
601     return impl_.get_service().native_handle(impl_.get_implementation());
602   }
603
604   /// Cancel all asynchronous operations associated with the socket.
605   /**
606    * This function causes all outstanding asynchronous connect, send and receive
607    * operations to finish immediately, and the handlers for cancelled operations
608    * will be passed the boost::asio::error::operation_aborted error.
609    *
610    * @throws boost::system::system_error Thrown on failure.
611    *
612    * @note Calls to cancel() will always fail with
613    * boost::asio::error::operation_not_supported when run on Windows XP, Windows
614    * Server 2003, and earlier versions of Windows, unless
615    * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has
616    * two issues that should be considered before enabling its use:
617    *
618    * @li It will only cancel asynchronous operations that were initiated in the
619    * current thread.
620    *
621    * @li It can appear to complete without error, but the request to cancel the
622    * unfinished operations may be silently ignored by the operating system.
623    * Whether it works or not seems to depend on the drivers that are installed.
624    *
625    * For portable cancellation, consider using one of the following
626    * alternatives:
627    *
628    * @li Disable asio's I/O completion port backend by defining
629    * BOOST_ASIO_DISABLE_IOCP.
630    *
631    * @li Use the close() function to simultaneously cancel the outstanding
632    * operations and close the socket.
633    *
634    * When running on Windows Vista, Windows Server 2008, and later, the
635    * CancelIoEx function is always used. This function does not have the
636    * problems described above.
637    */
638 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
639   && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \
640   && !defined(BOOST_ASIO_ENABLE_CANCELIO)
641   __declspec(deprecated("By default, this function always fails with "
642         "operation_not_supported when used on Windows XP, Windows Server 2003, "
643         "or earlier. Consult documentation for details."))
644 #endif
645   void cancel()
646   {
647     boost::system::error_code ec;
648     impl_.get_service().cancel(impl_.get_implementation(), ec);
649     boost::asio::detail::throw_error(ec, "cancel");
650   }
651
652   /// Cancel all asynchronous operations associated with the socket.
653   /**
654    * This function causes all outstanding asynchronous connect, send and receive
655    * operations to finish immediately, and the handlers for cancelled operations
656    * will be passed the boost::asio::error::operation_aborted error.
657    *
658    * @param ec Set to indicate what error occurred, if any.
659    *
660    * @note Calls to cancel() will always fail with
661    * boost::asio::error::operation_not_supported when run on Windows XP, Windows
662    * Server 2003, and earlier versions of Windows, unless
663    * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has
664    * two issues that should be considered before enabling its use:
665    *
666    * @li It will only cancel asynchronous operations that were initiated in the
667    * current thread.
668    *
669    * @li It can appear to complete without error, but the request to cancel the
670    * unfinished operations may be silently ignored by the operating system.
671    * Whether it works or not seems to depend on the drivers that are installed.
672    *
673    * For portable cancellation, consider using one of the following
674    * alternatives:
675    *
676    * @li Disable asio's I/O completion port backend by defining
677    * BOOST_ASIO_DISABLE_IOCP.
678    *
679    * @li Use the close() function to simultaneously cancel the outstanding
680    * operations and close the socket.
681    *
682    * When running on Windows Vista, Windows Server 2008, and later, the
683    * CancelIoEx function is always used. This function does not have the
684    * problems described above.
685    */
686 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
687   && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \
688   && !defined(BOOST_ASIO_ENABLE_CANCELIO)
689   __declspec(deprecated("By default, this function always fails with "
690         "operation_not_supported when used on Windows XP, Windows Server 2003, "
691         "or earlier. Consult documentation for details."))
692 #endif
693   BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
694   {
695     impl_.get_service().cancel(impl_.get_implementation(), ec);
696     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
697   }
698
699   /// Determine whether the socket is at the out-of-band data mark.
700   /**
701    * This function is used to check whether the socket input is currently
702    * positioned at the out-of-band data mark.
703    *
704    * @return A bool indicating whether the socket is at the out-of-band data
705    * mark.
706    *
707    * @throws boost::system::system_error Thrown on failure.
708    */
709   bool at_mark() const
710   {
711     boost::system::error_code ec;
712     bool b = impl_.get_service().at_mark(impl_.get_implementation(), ec);
713     boost::asio::detail::throw_error(ec, "at_mark");
714     return b;
715   }
716
717   /// Determine whether the socket is at the out-of-band data mark.
718   /**
719    * This function is used to check whether the socket input is currently
720    * positioned at the out-of-band data mark.
721    *
722    * @param ec Set to indicate what error occurred, if any.
723    *
724    * @return A bool indicating whether the socket is at the out-of-band data
725    * mark.
726    */
727   bool at_mark(boost::system::error_code& ec) const
728   {
729     return impl_.get_service().at_mark(impl_.get_implementation(), ec);
730   }
731
732   /// Determine the number of bytes available for reading.
733   /**
734    * This function is used to determine the number of bytes that may be read
735    * without blocking.
736    *
737    * @return The number of bytes that may be read without blocking, or 0 if an
738    * error occurs.
739    *
740    * @throws boost::system::system_error Thrown on failure.
741    */
742   std::size_t available() const
743   {
744     boost::system::error_code ec;
745     std::size_t s = impl_.get_service().available(
746         impl_.get_implementation(), ec);
747     boost::asio::detail::throw_error(ec, "available");
748     return s;
749   }
750
751   /// Determine the number of bytes available for reading.
752   /**
753    * This function is used to determine the number of bytes that may be read
754    * without blocking.
755    *
756    * @param ec Set to indicate what error occurred, if any.
757    *
758    * @return The number of bytes that may be read without blocking, or 0 if an
759    * error occurs.
760    */
761   std::size_t available(boost::system::error_code& ec) const
762   {
763     return impl_.get_service().available(impl_.get_implementation(), ec);
764   }
765
766   /// Bind the socket to the given local endpoint.
767   /**
768    * This function binds the socket to the specified endpoint on the local
769    * machine.
770    *
771    * @param endpoint An endpoint on the local machine to which the socket will
772    * be bound.
773    *
774    * @throws boost::system::system_error Thrown on failure.
775    *
776    * @par Example
777    * @code
778    * boost::asio::ip::tcp::socket socket(my_context);
779    * socket.open(boost::asio::ip::tcp::v4());
780    * socket.bind(boost::asio::ip::tcp::endpoint(
781    *       boost::asio::ip::tcp::v4(), 12345));
782    * @endcode
783    */
784   void bind(const endpoint_type& endpoint)
785   {
786     boost::system::error_code ec;
787     impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
788     boost::asio::detail::throw_error(ec, "bind");
789   }
790
791   /// Bind the socket to the given local endpoint.
792   /**
793    * This function binds the socket to the specified endpoint on the local
794    * machine.
795    *
796    * @param endpoint An endpoint on the local machine to which the socket will
797    * be bound.
798    *
799    * @param ec Set to indicate what error occurred, if any.
800    *
801    * @par Example
802    * @code
803    * boost::asio::ip::tcp::socket socket(my_context);
804    * socket.open(boost::asio::ip::tcp::v4());
805    * boost::system::error_code ec;
806    * socket.bind(boost::asio::ip::tcp::endpoint(
807    *       boost::asio::ip::tcp::v4(), 12345), ec);
808    * if (ec)
809    * {
810    *   // An error occurred.
811    * }
812    * @endcode
813    */
814   BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint,
815       boost::system::error_code& ec)
816   {
817     impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
818     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
819   }
820
821   /// Connect the socket to the specified endpoint.
822   /**
823    * This function is used to connect a socket to the specified remote endpoint.
824    * The function call will block until the connection is successfully made or
825    * an error occurs.
826    *
827    * The socket is automatically opened if it is not already open. If the
828    * connect fails, and the socket was automatically opened, the socket is
829    * not returned to the closed state.
830    *
831    * @param peer_endpoint The remote endpoint to which the socket will be
832    * connected.
833    *
834    * @throws boost::system::system_error Thrown on failure.
835    *
836    * @par Example
837    * @code
838    * boost::asio::ip::tcp::socket socket(my_context);
839    * boost::asio::ip::tcp::endpoint endpoint(
840    *     boost::asio::ip::address::from_string("1.2.3.4"), 12345);
841    * socket.connect(endpoint);
842    * @endcode
843    */
844   void connect(const endpoint_type& peer_endpoint)
845   {
846     boost::system::error_code ec;
847     if (!is_open())
848     {
849       impl_.get_service().open(impl_.get_implementation(),
850           peer_endpoint.protocol(), ec);
851       boost::asio::detail::throw_error(ec, "connect");
852     }
853     impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec);
854     boost::asio::detail::throw_error(ec, "connect");
855   }
856
857   /// Connect the socket to the specified endpoint.
858   /**
859    * This function is used to connect a socket to the specified remote endpoint.
860    * The function call will block until the connection is successfully made or
861    * an error occurs.
862    *
863    * The socket is automatically opened if it is not already open. If the
864    * connect fails, and the socket was automatically opened, the socket is
865    * not returned to the closed state.
866    *
867    * @param peer_endpoint The remote endpoint to which the socket will be
868    * connected.
869    *
870    * @param ec Set to indicate what error occurred, if any.
871    *
872    * @par Example
873    * @code
874    * boost::asio::ip::tcp::socket socket(my_context);
875    * boost::asio::ip::tcp::endpoint endpoint(
876    *     boost::asio::ip::address::from_string("1.2.3.4"), 12345);
877    * boost::system::error_code ec;
878    * socket.connect(endpoint, ec);
879    * if (ec)
880    * {
881    *   // An error occurred.
882    * }
883    * @endcode
884    */
885   BOOST_ASIO_SYNC_OP_VOID connect(const endpoint_type& peer_endpoint,
886       boost::system::error_code& ec)
887   {
888     if (!is_open())
889     {
890       impl_.get_service().open(impl_.get_implementation(),
891             peer_endpoint.protocol(), ec);
892       if (ec)
893       {
894         BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
895       }
896     }
897
898     impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec);
899     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
900   }
901
902   /// Start an asynchronous connect.
903   /**
904    * This function is used to asynchronously connect a socket to the specified
905    * remote endpoint. The function call always returns immediately.
906    *
907    * The socket is automatically opened if it is not already open. If the
908    * connect fails, and the socket was automatically opened, the socket is
909    * not returned to the closed state.
910    *
911    * @param peer_endpoint The remote endpoint to which the socket will be
912    * connected. Copies will be made of the endpoint object as required.
913    *
914    * @param handler The handler to be called when the connection operation
915    * completes. Copies will be made of the handler as required. The function
916    * signature of the handler must be:
917    * @code void handler(
918    *   const boost::system::error_code& error // Result of operation
919    * ); @endcode
920    * Regardless of whether the asynchronous operation completes immediately or
921    * not, the handler will not be invoked from within this function. On
922    * immediate completion, invocation of the handler will be performed in a
923    * manner equivalent to using boost::asio::post().
924    *
925    * @par Example
926    * @code
927    * void connect_handler(const boost::system::error_code& error)
928    * {
929    *   if (!error)
930    *   {
931    *     // Connect succeeded.
932    *   }
933    * }
934    *
935    * ...
936    *
937    * boost::asio::ip::tcp::socket socket(my_context);
938    * boost::asio::ip::tcp::endpoint endpoint(
939    *     boost::asio::ip::address::from_string("1.2.3.4"), 12345);
940    * socket.async_connect(endpoint, connect_handler);
941    * @endcode
942    */
943   template <
944       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
945         ConnectHandler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
946   BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ConnectHandler,
947       void (boost::system::error_code))
948   async_connect(const endpoint_type& peer_endpoint,
949       BOOST_ASIO_MOVE_ARG(ConnectHandler) handler
950         BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
951   {
952     boost::system::error_code open_ec;
953     if (!is_open())
954     {
955       const protocol_type protocol = peer_endpoint.protocol();
956       impl_.get_service().open(impl_.get_implementation(), protocol, open_ec);
957     }
958
959     return async_initiate<ConnectHandler, void (boost::system::error_code)>(
960         initiate_async_connect(this), handler, peer_endpoint, open_ec);
961   }
962
963   /// Set an option on the socket.
964   /**
965    * This function is used to set an option on the socket.
966    *
967    * @param option The new option value to be set on the socket.
968    *
969    * @throws boost::system::system_error Thrown on failure.
970    *
971    * @sa SettableSocketOption @n
972    * boost::asio::socket_base::broadcast @n
973    * boost::asio::socket_base::do_not_route @n
974    * boost::asio::socket_base::keep_alive @n
975    * boost::asio::socket_base::linger @n
976    * boost::asio::socket_base::receive_buffer_size @n
977    * boost::asio::socket_base::receive_low_watermark @n
978    * boost::asio::socket_base::reuse_address @n
979    * boost::asio::socket_base::send_buffer_size @n
980    * boost::asio::socket_base::send_low_watermark @n
981    * boost::asio::ip::multicast::join_group @n
982    * boost::asio::ip::multicast::leave_group @n
983    * boost::asio::ip::multicast::enable_loopback @n
984    * boost::asio::ip::multicast::outbound_interface @n
985    * boost::asio::ip::multicast::hops @n
986    * boost::asio::ip::tcp::no_delay
987    *
988    * @par Example
989    * Setting the IPPROTO_TCP/TCP_NODELAY option:
990    * @code
991    * boost::asio::ip::tcp::socket socket(my_context);
992    * ...
993    * boost::asio::ip::tcp::no_delay option(true);
994    * socket.set_option(option);
995    * @endcode
996    */
997   template <typename SettableSocketOption>
998   void set_option(const SettableSocketOption& option)
999   {
1000     boost::system::error_code ec;
1001     impl_.get_service().set_option(impl_.get_implementation(), option, ec);
1002     boost::asio::detail::throw_error(ec, "set_option");
1003   }
1004
1005   /// Set an option on the socket.
1006   /**
1007    * This function is used to set an option on the socket.
1008    *
1009    * @param option The new option value to be set on the socket.
1010    *
1011    * @param ec Set to indicate what error occurred, if any.
1012    *
1013    * @sa SettableSocketOption @n
1014    * boost::asio::socket_base::broadcast @n
1015    * boost::asio::socket_base::do_not_route @n
1016    * boost::asio::socket_base::keep_alive @n
1017    * boost::asio::socket_base::linger @n
1018    * boost::asio::socket_base::receive_buffer_size @n
1019    * boost::asio::socket_base::receive_low_watermark @n
1020    * boost::asio::socket_base::reuse_address @n
1021    * boost::asio::socket_base::send_buffer_size @n
1022    * boost::asio::socket_base::send_low_watermark @n
1023    * boost::asio::ip::multicast::join_group @n
1024    * boost::asio::ip::multicast::leave_group @n
1025    * boost::asio::ip::multicast::enable_loopback @n
1026    * boost::asio::ip::multicast::outbound_interface @n
1027    * boost::asio::ip::multicast::hops @n
1028    * boost::asio::ip::tcp::no_delay
1029    *
1030    * @par Example
1031    * Setting the IPPROTO_TCP/TCP_NODELAY option:
1032    * @code
1033    * boost::asio::ip::tcp::socket socket(my_context);
1034    * ...
1035    * boost::asio::ip::tcp::no_delay option(true);
1036    * boost::system::error_code ec;
1037    * socket.set_option(option, ec);
1038    * if (ec)
1039    * {
1040    *   // An error occurred.
1041    * }
1042    * @endcode
1043    */
1044   template <typename SettableSocketOption>
1045   BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option,
1046       boost::system::error_code& ec)
1047   {
1048     impl_.get_service().set_option(impl_.get_implementation(), option, ec);
1049     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
1050   }
1051
1052   /// Get an option from the socket.
1053   /**
1054    * This function is used to get the current value of an option on the socket.
1055    *
1056    * @param option The option value to be obtained from the socket.
1057    *
1058    * @throws boost::system::system_error Thrown on failure.
1059    *
1060    * @sa GettableSocketOption @n
1061    * boost::asio::socket_base::broadcast @n
1062    * boost::asio::socket_base::do_not_route @n
1063    * boost::asio::socket_base::keep_alive @n
1064    * boost::asio::socket_base::linger @n
1065    * boost::asio::socket_base::receive_buffer_size @n
1066    * boost::asio::socket_base::receive_low_watermark @n
1067    * boost::asio::socket_base::reuse_address @n
1068    * boost::asio::socket_base::send_buffer_size @n
1069    * boost::asio::socket_base::send_low_watermark @n
1070    * boost::asio::ip::multicast::join_group @n
1071    * boost::asio::ip::multicast::leave_group @n
1072    * boost::asio::ip::multicast::enable_loopback @n
1073    * boost::asio::ip::multicast::outbound_interface @n
1074    * boost::asio::ip::multicast::hops @n
1075    * boost::asio::ip::tcp::no_delay
1076    *
1077    * @par Example
1078    * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
1079    * @code
1080    * boost::asio::ip::tcp::socket socket(my_context);
1081    * ...
1082    * boost::asio::ip::tcp::socket::keep_alive option;
1083    * socket.get_option(option);
1084    * bool is_set = option.value();
1085    * @endcode
1086    */
1087   template <typename GettableSocketOption>
1088   void get_option(GettableSocketOption& option) const
1089   {
1090     boost::system::error_code ec;
1091     impl_.get_service().get_option(impl_.get_implementation(), option, ec);
1092     boost::asio::detail::throw_error(ec, "get_option");
1093   }
1094
1095   /// Get an option from the socket.
1096   /**
1097    * This function is used to get the current value of an option on the socket.
1098    *
1099    * @param option The option value to be obtained from the socket.
1100    *
1101    * @param ec Set to indicate what error occurred, if any.
1102    *
1103    * @sa GettableSocketOption @n
1104    * boost::asio::socket_base::broadcast @n
1105    * boost::asio::socket_base::do_not_route @n
1106    * boost::asio::socket_base::keep_alive @n
1107    * boost::asio::socket_base::linger @n
1108    * boost::asio::socket_base::receive_buffer_size @n
1109    * boost::asio::socket_base::receive_low_watermark @n
1110    * boost::asio::socket_base::reuse_address @n
1111    * boost::asio::socket_base::send_buffer_size @n
1112    * boost::asio::socket_base::send_low_watermark @n
1113    * boost::asio::ip::multicast::join_group @n
1114    * boost::asio::ip::multicast::leave_group @n
1115    * boost::asio::ip::multicast::enable_loopback @n
1116    * boost::asio::ip::multicast::outbound_interface @n
1117    * boost::asio::ip::multicast::hops @n
1118    * boost::asio::ip::tcp::no_delay
1119    *
1120    * @par Example
1121    * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
1122    * @code
1123    * boost::asio::ip::tcp::socket socket(my_context);
1124    * ...
1125    * boost::asio::ip::tcp::socket::keep_alive option;
1126    * boost::system::error_code ec;
1127    * socket.get_option(option, ec);
1128    * if (ec)
1129    * {
1130    *   // An error occurred.
1131    * }
1132    * bool is_set = option.value();
1133    * @endcode
1134    */
1135   template <typename GettableSocketOption>
1136   BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option,
1137       boost::system::error_code& ec) const
1138   {
1139     impl_.get_service().get_option(impl_.get_implementation(), option, ec);
1140     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
1141   }
1142
1143   /// Perform an IO control command on the socket.
1144   /**
1145    * This function is used to execute an IO control command on the socket.
1146    *
1147    * @param command The IO control command to be performed on the socket.
1148    *
1149    * @throws boost::system::system_error Thrown on failure.
1150    *
1151    * @sa IoControlCommand @n
1152    * boost::asio::socket_base::bytes_readable @n
1153    * boost::asio::socket_base::non_blocking_io
1154    *
1155    * @par Example
1156    * Getting the number of bytes ready to read:
1157    * @code
1158    * boost::asio::ip::tcp::socket socket(my_context);
1159    * ...
1160    * boost::asio::ip::tcp::socket::bytes_readable command;
1161    * socket.io_control(command);
1162    * std::size_t bytes_readable = command.get();
1163    * @endcode
1164    */
1165   template <typename IoControlCommand>
1166   void io_control(IoControlCommand& command)
1167   {
1168     boost::system::error_code ec;
1169     impl_.get_service().io_control(impl_.get_implementation(), command, ec);
1170     boost::asio::detail::throw_error(ec, "io_control");
1171   }
1172
1173   /// Perform an IO control command on the socket.
1174   /**
1175    * This function is used to execute an IO control command on the socket.
1176    *
1177    * @param command The IO control command to be performed on the socket.
1178    *
1179    * @param ec Set to indicate what error occurred, if any.
1180    *
1181    * @sa IoControlCommand @n
1182    * boost::asio::socket_base::bytes_readable @n
1183    * boost::asio::socket_base::non_blocking_io
1184    *
1185    * @par Example
1186    * Getting the number of bytes ready to read:
1187    * @code
1188    * boost::asio::ip::tcp::socket socket(my_context);
1189    * ...
1190    * boost::asio::ip::tcp::socket::bytes_readable command;
1191    * boost::system::error_code ec;
1192    * socket.io_control(command, ec);
1193    * if (ec)
1194    * {
1195    *   // An error occurred.
1196    * }
1197    * std::size_t bytes_readable = command.get();
1198    * @endcode
1199    */
1200   template <typename IoControlCommand>
1201   BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command,
1202       boost::system::error_code& ec)
1203   {
1204     impl_.get_service().io_control(impl_.get_implementation(), command, ec);
1205     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
1206   }
1207
1208   /// Gets the non-blocking mode of the socket.
1209   /**
1210    * @returns @c true if the socket's synchronous operations will fail with
1211    * boost::asio::error::would_block if they are unable to perform the requested
1212    * operation immediately. If @c false, synchronous operations will block
1213    * until complete.
1214    *
1215    * @note The non-blocking mode has no effect on the behaviour of asynchronous
1216    * operations. Asynchronous operations will never fail with the error
1217    * boost::asio::error::would_block.
1218    */
1219   bool non_blocking() const
1220   {
1221     return impl_.get_service().non_blocking(impl_.get_implementation());
1222   }
1223
1224   /// Sets the non-blocking mode of the socket.
1225   /**
1226    * @param mode If @c true, the socket's synchronous operations will fail with
1227    * boost::asio::error::would_block if they are unable to perform the requested
1228    * operation immediately. If @c false, synchronous operations will block
1229    * until complete.
1230    *
1231    * @throws boost::system::system_error Thrown on failure.
1232    *
1233    * @note The non-blocking mode has no effect on the behaviour of asynchronous
1234    * operations. Asynchronous operations will never fail with the error
1235    * boost::asio::error::would_block.
1236    */
1237   void non_blocking(bool mode)
1238   {
1239     boost::system::error_code ec;
1240     impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec);
1241     boost::asio::detail::throw_error(ec, "non_blocking");
1242   }
1243
1244   /// Sets the non-blocking mode of the socket.
1245   /**
1246    * @param mode If @c true, the socket's synchronous operations will fail with
1247    * boost::asio::error::would_block if they are unable to perform the requested
1248    * operation immediately. If @c false, synchronous operations will block
1249    * until complete.
1250    *
1251    * @param ec Set to indicate what error occurred, if any.
1252    *
1253    * @note The non-blocking mode has no effect on the behaviour of asynchronous
1254    * operations. Asynchronous operations will never fail with the error
1255    * boost::asio::error::would_block.
1256    */
1257   BOOST_ASIO_SYNC_OP_VOID non_blocking(
1258       bool mode, boost::system::error_code& ec)
1259   {
1260     impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec);
1261     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
1262   }
1263
1264   /// Gets the non-blocking mode of the native socket implementation.
1265   /**
1266    * This function is used to retrieve the non-blocking mode of the underlying
1267    * native socket. This mode has no effect on the behaviour of the socket
1268    * object's synchronous operations.
1269    *
1270    * @returns @c true if the underlying socket is in non-blocking mode and
1271    * direct system calls may fail with boost::asio::error::would_block (or the
1272    * equivalent system error).
1273    *
1274    * @note The current non-blocking mode is cached by the socket object.
1275    * Consequently, the return value may be incorrect if the non-blocking mode
1276    * was set directly on the native socket.
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()(boost::system::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 = boost::system::error_code(n < 0 ? errno : 0,
1309    *             boost::asio::error::get_system_category());
1310    *         total_bytes_transferred_ += ec ? 0 : n;
1311    *
1312    *         // Retry operation immediately if interrupted by signal.
1313    *         if (ec == boost::asio::error::interrupted)
1314    *           continue;
1315    *
1316    *         // Check if we need to run the operation again.
1317    *         if (ec == boost::asio::error::would_block
1318    *             || ec == boost::asio::error::try_again)
1319    *         {
1320    *           // We have to wait for the socket to become ready again.
1321    *           sock_.async_wait(tcp::socket::wait_write, *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_wait(tcp::socket::wait_write, op);
1346    * } @endcode
1347    */
1348   bool native_non_blocking() const
1349   {
1350     return impl_.get_service().native_non_blocking(impl_.get_implementation());
1351   }
1352
1353   /// Sets the non-blocking mode of the native socket implementation.
1354   /**
1355    * This function is used to modify the non-blocking mode of the underlying
1356    * native socket. It has no effect on the behaviour of the socket object's
1357    * synchronous operations.
1358    *
1359    * @param mode If @c true, the underlying socket is put into non-blocking
1360    * mode and direct system calls may fail with boost::asio::error::would_block
1361    * (or the equivalent system error).
1362    *
1363    * @throws boost::system::system_error Thrown on failure. If the @c mode is
1364    * @c false, but the current value of @c non_blocking() is @c true, this
1365    * function fails with boost::asio::error::invalid_argument, as the
1366    * combination does not make sense.
1367    *
1368    * @par Example
1369    * This function is intended to allow the encapsulation of arbitrary
1370    * non-blocking system calls as asynchronous operations, in a way that is
1371    * transparent to the user of the socket object. The following example
1372    * illustrates how Linux's @c sendfile system call might be encapsulated:
1373    * @code template <typename Handler>
1374    * struct sendfile_op
1375    * {
1376    *   tcp::socket& sock_;
1377    *   int fd_;
1378    *   Handler handler_;
1379    *   off_t offset_;
1380    *   std::size_t total_bytes_transferred_;
1381    *
1382    *   // Function call operator meeting WriteHandler requirements.
1383    *   // Used as the handler for the async_write_some operation.
1384    *   void operator()(boost::system::error_code ec, std::size_t)
1385    *   {
1386    *     // Put the underlying socket into non-blocking mode.
1387    *     if (!ec)
1388    *       if (!sock_.native_non_blocking())
1389    *         sock_.native_non_blocking(true, ec);
1390    *
1391    *     if (!ec)
1392    *     {
1393    *       for (;;)
1394    *       {
1395    *         // Try the system call.
1396    *         errno = 0;
1397    *         int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
1398    *         ec = boost::system::error_code(n < 0 ? errno : 0,
1399    *             boost::asio::error::get_system_category());
1400    *         total_bytes_transferred_ += ec ? 0 : n;
1401    *
1402    *         // Retry operation immediately if interrupted by signal.
1403    *         if (ec == boost::asio::error::interrupted)
1404    *           continue;
1405    *
1406    *         // Check if we need to run the operation again.
1407    *         if (ec == boost::asio::error::would_block
1408    *             || ec == boost::asio::error::try_again)
1409    *         {
1410    *           // We have to wait for the socket to become ready again.
1411    *           sock_.async_wait(tcp::socket::wait_write, *this);
1412    *           return;
1413    *         }
1414    *
1415    *         if (ec || n == 0)
1416    *         {
1417    *           // An error occurred, or we have reached the end of the file.
1418    *           // Either way we must exit the loop so we can call the handler.
1419    *           break;
1420    *         }
1421    *
1422    *         // Loop around to try calling sendfile again.
1423    *       }
1424    *     }
1425    *
1426    *     // Pass result back to user's handler.
1427    *     handler_(ec, total_bytes_transferred_);
1428    *   }
1429    * };
1430    *
1431    * template <typename Handler>
1432    * void async_sendfile(tcp::socket& sock, int fd, Handler h)
1433    * {
1434    *   sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
1435    *   sock.async_wait(tcp::socket::wait_write, op);
1436    * } @endcode
1437    */
1438   void native_non_blocking(bool mode)
1439   {
1440     boost::system::error_code ec;
1441     impl_.get_service().native_non_blocking(
1442         impl_.get_implementation(), mode, ec);
1443     boost::asio::detail::throw_error(ec, "native_non_blocking");
1444   }
1445
1446   /// Sets the non-blocking mode of the native socket implementation.
1447   /**
1448    * This function is used to modify the non-blocking mode of the underlying
1449    * native socket. It has no effect on the behaviour of the socket object's
1450    * synchronous operations.
1451    *
1452    * @param mode If @c true, the underlying socket is put into non-blocking
1453    * mode and direct system calls may fail with boost::asio::error::would_block
1454    * (or the equivalent system error).
1455    *
1456    * @param ec Set to indicate what error occurred, if any. If the @c mode is
1457    * @c false, but the current value of @c non_blocking() is @c true, this
1458    * function fails with boost::asio::error::invalid_argument, as the
1459    * combination does not make sense.
1460    *
1461    * @par Example
1462    * This function is intended to allow the encapsulation of arbitrary
1463    * non-blocking system calls as asynchronous operations, in a way that is
1464    * transparent to the user of the socket object. The following example
1465    * illustrates how Linux's @c sendfile system call might be encapsulated:
1466    * @code template <typename Handler>
1467    * struct sendfile_op
1468    * {
1469    *   tcp::socket& sock_;
1470    *   int fd_;
1471    *   Handler handler_;
1472    *   off_t offset_;
1473    *   std::size_t total_bytes_transferred_;
1474    *
1475    *   // Function call operator meeting WriteHandler requirements.
1476    *   // Used as the handler for the async_write_some operation.
1477    *   void operator()(boost::system::error_code ec, std::size_t)
1478    *   {
1479    *     // Put the underlying socket into non-blocking mode.
1480    *     if (!ec)
1481    *       if (!sock_.native_non_blocking())
1482    *         sock_.native_non_blocking(true, ec);
1483    *
1484    *     if (!ec)
1485    *     {
1486    *       for (;;)
1487    *       {
1488    *         // Try the system call.
1489    *         errno = 0;
1490    *         int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
1491    *         ec = boost::system::error_code(n < 0 ? errno : 0,
1492    *             boost::asio::error::get_system_category());
1493    *         total_bytes_transferred_ += ec ? 0 : n;
1494    *
1495    *         // Retry operation immediately if interrupted by signal.
1496    *         if (ec == boost::asio::error::interrupted)
1497    *           continue;
1498    *
1499    *         // Check if we need to run the operation again.
1500    *         if (ec == boost::asio::error::would_block
1501    *             || ec == boost::asio::error::try_again)
1502    *         {
1503    *           // We have to wait for the socket to become ready again.
1504    *           sock_.async_wait(tcp::socket::wait_write, *this);
1505    *           return;
1506    *         }
1507    *
1508    *         if (ec || n == 0)
1509    *         {
1510    *           // An error occurred, or we have reached the end of the file.
1511    *           // Either way we must exit the loop so we can call the handler.
1512    *           break;
1513    *         }
1514    *
1515    *         // Loop around to try calling sendfile again.
1516    *       }
1517    *     }
1518    *
1519    *     // Pass result back to user's handler.
1520    *     handler_(ec, total_bytes_transferred_);
1521    *   }
1522    * };
1523    *
1524    * template <typename Handler>
1525    * void async_sendfile(tcp::socket& sock, int fd, Handler h)
1526    * {
1527    *   sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
1528    *   sock.async_wait(tcp::socket::wait_write, op);
1529    * } @endcode
1530    */
1531   BOOST_ASIO_SYNC_OP_VOID native_non_blocking(
1532       bool mode, boost::system::error_code& ec)
1533   {
1534     impl_.get_service().native_non_blocking(
1535         impl_.get_implementation(), mode, ec);
1536     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
1537   }
1538
1539   /// Get the local endpoint of the socket.
1540   /**
1541    * This function is used to obtain the locally bound endpoint of the socket.
1542    *
1543    * @returns An object that represents the local endpoint of the socket.
1544    *
1545    * @throws boost::system::system_error Thrown on failure.
1546    *
1547    * @par Example
1548    * @code
1549    * boost::asio::ip::tcp::socket socket(my_context);
1550    * ...
1551    * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint();
1552    * @endcode
1553    */
1554   endpoint_type local_endpoint() const
1555   {
1556     boost::system::error_code ec;
1557     endpoint_type ep = impl_.get_service().local_endpoint(
1558         impl_.get_implementation(), ec);
1559     boost::asio::detail::throw_error(ec, "local_endpoint");
1560     return ep;
1561   }
1562
1563   /// Get the local endpoint of the socket.
1564   /**
1565    * This function is used to obtain the locally bound endpoint of the socket.
1566    *
1567    * @param ec Set to indicate what error occurred, if any.
1568    *
1569    * @returns An object that represents the local endpoint of the socket.
1570    * Returns a default-constructed endpoint object if an error occurred.
1571    *
1572    * @par Example
1573    * @code
1574    * boost::asio::ip::tcp::socket socket(my_context);
1575    * ...
1576    * boost::system::error_code ec;
1577    * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec);
1578    * if (ec)
1579    * {
1580    *   // An error occurred.
1581    * }
1582    * @endcode
1583    */
1584   endpoint_type local_endpoint(boost::system::error_code& ec) const
1585   {
1586     return impl_.get_service().local_endpoint(impl_.get_implementation(), ec);
1587   }
1588
1589   /// Get the remote endpoint of the socket.
1590   /**
1591    * This function is used to obtain the remote endpoint of the socket.
1592    *
1593    * @returns An object that represents the remote endpoint of the socket.
1594    *
1595    * @throws boost::system::system_error Thrown on failure.
1596    *
1597    * @par Example
1598    * @code
1599    * boost::asio::ip::tcp::socket socket(my_context);
1600    * ...
1601    * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint();
1602    * @endcode
1603    */
1604   endpoint_type remote_endpoint() const
1605   {
1606     boost::system::error_code ec;
1607     endpoint_type ep = impl_.get_service().remote_endpoint(
1608         impl_.get_implementation(), ec);
1609     boost::asio::detail::throw_error(ec, "remote_endpoint");
1610     return ep;
1611   }
1612
1613   /// Get the remote endpoint of the socket.
1614   /**
1615    * This function is used to obtain the remote endpoint of the socket.
1616    *
1617    * @param ec Set to indicate what error occurred, if any.
1618    *
1619    * @returns An object that represents the remote endpoint of the socket.
1620    * Returns a default-constructed endpoint object if an error occurred.
1621    *
1622    * @par Example
1623    * @code
1624    * boost::asio::ip::tcp::socket socket(my_context);
1625    * ...
1626    * boost::system::error_code ec;
1627    * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec);
1628    * if (ec)
1629    * {
1630    *   // An error occurred.
1631    * }
1632    * @endcode
1633    */
1634   endpoint_type remote_endpoint(boost::system::error_code& ec) const
1635   {
1636     return impl_.get_service().remote_endpoint(impl_.get_implementation(), ec);
1637   }
1638
1639   /// Disable sends or receives on the socket.
1640   /**
1641    * This function is used to disable send operations, receive operations, or
1642    * both.
1643    *
1644    * @param what Determines what types of operation will no longer be allowed.
1645    *
1646    * @throws boost::system::system_error Thrown on failure.
1647    *
1648    * @par Example
1649    * Shutting down the send side of the socket:
1650    * @code
1651    * boost::asio::ip::tcp::socket socket(my_context);
1652    * ...
1653    * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send);
1654    * @endcode
1655    */
1656   void shutdown(shutdown_type what)
1657   {
1658     boost::system::error_code ec;
1659     impl_.get_service().shutdown(impl_.get_implementation(), what, ec);
1660     boost::asio::detail::throw_error(ec, "shutdown");
1661   }
1662
1663   /// Disable sends or receives on the socket.
1664   /**
1665    * This function is used to disable send operations, receive operations, or
1666    * both.
1667    *
1668    * @param what Determines what types of operation will no longer be allowed.
1669    *
1670    * @param ec Set to indicate what error occurred, if any.
1671    *
1672    * @par Example
1673    * Shutting down the send side of the socket:
1674    * @code
1675    * boost::asio::ip::tcp::socket socket(my_context);
1676    * ...
1677    * boost::system::error_code ec;
1678    * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec);
1679    * if (ec)
1680    * {
1681    *   // An error occurred.
1682    * }
1683    * @endcode
1684    */
1685   BOOST_ASIO_SYNC_OP_VOID shutdown(shutdown_type what,
1686       boost::system::error_code& ec)
1687   {
1688     impl_.get_service().shutdown(impl_.get_implementation(), what, ec);
1689     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
1690   }
1691
1692   /// Wait for the socket to become ready to read, ready to write, or to have
1693   /// pending error conditions.
1694   /**
1695    * This function is used to perform a blocking wait for a socket to enter
1696    * a ready to read, write or error condition state.
1697    *
1698    * @param w Specifies the desired socket state.
1699    *
1700    * @par Example
1701    * Waiting for a socket to become readable.
1702    * @code
1703    * boost::asio::ip::tcp::socket socket(my_context);
1704    * ...
1705    * socket.wait(boost::asio::ip::tcp::socket::wait_read);
1706    * @endcode
1707    */
1708   void wait(wait_type w)
1709   {
1710     boost::system::error_code ec;
1711     impl_.get_service().wait(impl_.get_implementation(), w, ec);
1712     boost::asio::detail::throw_error(ec, "wait");
1713   }
1714
1715   /// Wait for the socket to become ready to read, ready to write, or to have
1716   /// pending error conditions.
1717   /**
1718    * This function is used to perform a blocking wait for a socket to enter
1719    * a ready to read, write or error condition state.
1720    *
1721    * @param w Specifies the desired socket state.
1722    *
1723    * @param ec Set to indicate what error occurred, if any.
1724    *
1725    * @par Example
1726    * Waiting for a socket to become readable.
1727    * @code
1728    * boost::asio::ip::tcp::socket socket(my_context);
1729    * ...
1730    * boost::system::error_code ec;
1731    * socket.wait(boost::asio::ip::tcp::socket::wait_read, ec);
1732    * @endcode
1733    */
1734   BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec)
1735   {
1736     impl_.get_service().wait(impl_.get_implementation(), w, ec);
1737     BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
1738   }
1739
1740   /// Asynchronously wait for the socket to become ready to read, ready to
1741   /// write, or to have pending error conditions.
1742   /**
1743    * This function is used to perform an asynchronous wait for a socket to enter
1744    * a ready to read, write or error condition state.
1745    *
1746    * @param w Specifies the desired socket state.
1747    *
1748    * @param handler The handler to be called when the wait operation completes.
1749    * Copies will be made of the handler as required. The function signature of
1750    * the handler must be:
1751    * @code void handler(
1752    *   const boost::system::error_code& error // Result of operation
1753    * ); @endcode
1754    * Regardless of whether the asynchronous operation completes immediately or
1755    * not, the handler will not be invoked from within this function. On
1756    * immediate completion, invocation of the handler will be performed in a
1757    * manner equivalent to using boost::asio::post().
1758    *
1759    * @par Example
1760    * @code
1761    * void wait_handler(const boost::system::error_code& error)
1762    * {
1763    *   if (!error)
1764    *   {
1765    *     // Wait succeeded.
1766    *   }
1767    * }
1768    *
1769    * ...
1770    *
1771    * boost::asio::ip::tcp::socket socket(my_context);
1772    * ...
1773    * socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler);
1774    * @endcode
1775    */
1776   template <
1777       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code))
1778         WaitHandler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
1779   BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WaitHandler,
1780       void (boost::system::error_code))
1781   async_wait(wait_type w,
1782       BOOST_ASIO_MOVE_ARG(WaitHandler) handler
1783         BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
1784   {
1785     return async_initiate<WaitHandler, void (boost::system::error_code)>(
1786         initiate_async_wait(this), handler, w);
1787   }
1788
1789 protected:
1790   /// Protected destructor to prevent deletion through this type.
1791   /**
1792    * This function destroys the socket, cancelling any outstanding asynchronous
1793    * operations associated with the socket as if by calling @c cancel.
1794    */
1795   ~basic_socket()
1796   {
1797   }
1798
1799 #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
1800   detail::io_object_impl<
1801     detail::null_socket_service<Protocol>, Executor> impl_;
1802 #elif defined(BOOST_ASIO_HAS_IOCP)
1803   detail::io_object_impl<
1804     detail::win_iocp_socket_service<Protocol>, Executor> impl_;
1805 #else
1806   detail::io_object_impl<
1807     detail::reactive_socket_service<Protocol>, Executor> impl_;
1808 #endif
1809
1810 private:
1811   // Disallow copying and assignment.
1812   basic_socket(const basic_socket&) BOOST_ASIO_DELETED;
1813   basic_socket& operator=(const basic_socket&) BOOST_ASIO_DELETED;
1814
1815   class initiate_async_connect
1816   {
1817   public:
1818     typedef Executor executor_type;
1819
1820     explicit initiate_async_connect(basic_socket* self)
1821       : self_(self)
1822     {
1823     }
1824
1825     executor_type get_executor() const BOOST_ASIO_NOEXCEPT
1826     {
1827       return self_->get_executor();
1828     }
1829
1830     template <typename ConnectHandler>
1831     void operator()(BOOST_ASIO_MOVE_ARG(ConnectHandler) handler,
1832         const endpoint_type& peer_endpoint,
1833         const boost::system::error_code& open_ec) const
1834     {
1835       // If you get an error on the following line it means that your handler
1836       // does not meet the documented type requirements for a ConnectHandler.
1837       BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check;
1838
1839       if (open_ec)
1840       {
1841           boost::asio::post(self_->impl_.get_executor(),
1842               boost::asio::detail::bind_handler(
1843                 BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler), open_ec));
1844       }
1845       else
1846       {
1847         detail::non_const_lvalue<ConnectHandler> handler2(handler);
1848         self_->impl_.get_service().async_connect(
1849             self_->impl_.get_implementation(), peer_endpoint,
1850             handler2.value, self_->impl_.get_implementation_executor());
1851       }
1852     }
1853
1854   private:
1855     basic_socket* self_;
1856   };
1857
1858   class initiate_async_wait
1859   {
1860   public:
1861     typedef Executor executor_type;
1862
1863     explicit initiate_async_wait(basic_socket* self)
1864       : self_(self)
1865     {
1866     }
1867
1868     executor_type get_executor() const BOOST_ASIO_NOEXCEPT
1869     {
1870       return self_->get_executor();
1871     }
1872
1873     template <typename WaitHandler>
1874     void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, wait_type w) const
1875     {
1876       // If you get an error on the following line it means that your handler
1877       // does not meet the documented type requirements for a WaitHandler.
1878       BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
1879
1880       detail::non_const_lvalue<WaitHandler> handler2(handler);
1881       self_->impl_.get_service().async_wait(
1882           self_->impl_.get_implementation(), w, handler2.value,
1883           self_->impl_.get_implementation_executor());
1884     }
1885
1886   private:
1887     basic_socket* self_;
1888   };
1889 };
1890
1891 } // namespace asio
1892 } // namespace boost
1893
1894 #include <boost/asio/detail/pop_options.hpp>
1895
1896 #endif // BOOST_ASIO_BASIC_SOCKET_HPP