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