1 //
2 // basic_socket_acceptor.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10 
11 #ifndef ASIO_BASIC_SOCKET_ACCEPTOR_HPP
12 #define ASIO_BASIC_SOCKET_ACCEPTOR_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/basic_io_object.hpp"
20 #include "asio/basic_socket.hpp"
21 #include "asio/detail/handler_type_requirements.hpp"
22 #include "asio/detail/throw_error.hpp"
23 #include "asio/detail/type_traits.hpp"
24 #include "asio/error.hpp"
25 #include "asio/socket_acceptor_service.hpp"
26 #include "asio/socket_base.hpp"
27 
28 #include "asio/detail/push_options.hpp"
29 
30 namespace asio {
31 
32 /// Provides the ability to accept new connections.
33 /**
34  * The basic_socket_acceptor class template is used for accepting new socket
35  * connections.
36  *
37  * @par Thread Safety
38  * @e Distinct @e objects: Safe.@n
39  * @e Shared @e objects: Unsafe.
40  *
41  * @par Example
42  * Opening a socket acceptor with the SO_REUSEADDR option enabled:
43  * @code
44  * asio::ip::tcp::acceptor acceptor(io_context);
45  * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), port);
46  * acceptor.open(endpoint.protocol());
47  * acceptor.set_option(asio::ip::tcp::acceptor::reuse_address(true));
48  * acceptor.bind(endpoint);
49  * acceptor.listen();
50  * @endcode
51  */
52 template <typename Protocol,
53     typename SocketAcceptorService = socket_acceptor_service<Protocol> >
54 class basic_socket_acceptor
55   : public basic_io_object<SocketAcceptorService>,
56     public socket_base
57 {
58 public:
59   /// The native representation of an acceptor.
60   typedef typename SocketAcceptorService::native_handle_type native_handle_type;
61 
62   /// The protocol type.
63   typedef Protocol protocol_type;
64 
65   /// The endpoint type.
66   typedef typename Protocol::endpoint endpoint_type;
67 
68   /// Construct an acceptor without opening it.
69   /**
70    * This constructor creates an acceptor without opening it to listen for new
71    * connections. The open() function must be called before the acceptor can
72    * accept new socket connections.
73    *
74    * @param io_context The io_context object that the acceptor will use to
75    * dispatch handlers for any asynchronous operations performed on the
76    * acceptor.
77    */
basic_socket_acceptor(asio::io_context & io_context)78   explicit basic_socket_acceptor(asio::io_context& io_context)
79     : basic_io_object<SocketAcceptorService>(io_context)
80   {
81   }
82 
83   /// Construct an open acceptor.
84   /**
85    * This constructor creates an acceptor and automatically opens it.
86    *
87    * @param io_context The io_context object that the acceptor will use to
88    * dispatch handlers for any asynchronous operations performed on the
89    * acceptor.
90    *
91    * @param protocol An object specifying protocol parameters to be used.
92    *
93    * @throws asio::system_error Thrown on failure.
94    */
basic_socket_acceptor(asio::io_context & io_context,const protocol_type & protocol)95   basic_socket_acceptor(asio::io_context& io_context,
96       const protocol_type& protocol)
97     : basic_io_object<SocketAcceptorService>(io_context)
98   {
99     asio::error_code ec;
100     this->get_service().open(this->get_implementation(), protocol, ec);
101     asio::detail::throw_error(ec, "open");
102   }
103 
104   /// Construct an acceptor opened on the given endpoint.
105   /**
106    * This constructor creates an acceptor and automatically opens it to listen
107    * for new connections on the specified endpoint.
108    *
109    * @param io_context The io_context object that the acceptor will use to
110    * dispatch handlers for any asynchronous operations performed on the
111    * acceptor.
112    *
113    * @param endpoint An endpoint on the local machine on which the acceptor
114    * will listen for new connections.
115    *
116    * @param reuse_addr Whether the constructor should set the socket option
117    * socket_base::reuse_address.
118    *
119    * @throws asio::system_error Thrown on failure.
120    *
121    * @note This constructor is equivalent to the following code:
122    * @code
123    * basic_socket_acceptor<Protocol> acceptor(io_context);
124    * acceptor.open(endpoint.protocol());
125    * if (reuse_addr)
126    *   acceptor.set_option(socket_base::reuse_address(true));
127    * acceptor.bind(endpoint);
128    * acceptor.listen(listen_backlog);
129    * @endcode
130    */
basic_socket_acceptor(asio::io_context & io_context,const endpoint_type & endpoint,bool reuse_addr=true)131   basic_socket_acceptor(asio::io_context& io_context,
132       const endpoint_type& endpoint, bool reuse_addr = true)
133     : basic_io_object<SocketAcceptorService>(io_context)
134   {
135     asio::error_code ec;
136     const protocol_type protocol = endpoint.protocol();
137     this->get_service().open(this->get_implementation(), protocol, ec);
138     asio::detail::throw_error(ec, "open");
139     if (reuse_addr)
140     {
141       this->get_service().set_option(this->get_implementation(),
142           socket_base::reuse_address(true), ec);
143       asio::detail::throw_error(ec, "set_option");
144     }
145     this->get_service().bind(this->get_implementation(), endpoint, ec);
146     asio::detail::throw_error(ec, "bind");
147     this->get_service().listen(this->get_implementation(),
148         socket_base::max_connections, ec);
149     asio::detail::throw_error(ec, "listen");
150   }
151 
152   /// Construct a basic_socket_acceptor on an existing native acceptor.
153   /**
154    * This constructor creates an acceptor object to hold an existing native
155    * acceptor.
156    *
157    * @param io_context The io_context object that the acceptor will use to
158    * dispatch handlers for any asynchronous operations performed on the
159    * acceptor.
160    *
161    * @param protocol An object specifying protocol parameters to be used.
162    *
163    * @param native_acceptor A native acceptor.
164    *
165    * @throws asio::system_error Thrown on failure.
166    */
basic_socket_acceptor(asio::io_context & io_context,const protocol_type & protocol,const native_handle_type & native_acceptor)167   basic_socket_acceptor(asio::io_context& io_context,
168       const protocol_type& protocol, const native_handle_type& native_acceptor)
169     : basic_io_object<SocketAcceptorService>(io_context)
170   {
171     asio::error_code ec;
172     this->get_service().assign(this->get_implementation(),
173         protocol, native_acceptor, ec);
174     asio::detail::throw_error(ec, "assign");
175   }
176 
177 #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
178   /// Move-construct a basic_socket_acceptor from another.
179   /**
180    * This constructor moves an acceptor from one object to another.
181    *
182    * @param other The other basic_socket_acceptor object from which the move
183    * will occur.
184    *
185    * @note Following the move, the moved-from object is in the same state as if
186    * constructed using the @c basic_socket_acceptor(io_context&) constructor.
187    */
basic_socket_acceptor(basic_socket_acceptor && other)188   basic_socket_acceptor(basic_socket_acceptor&& other)
189     : basic_io_object<SocketAcceptorService>(
190         ASIO_MOVE_CAST(basic_socket_acceptor)(other))
191   {
192   }
193 
194   /// Move-assign a basic_socket_acceptor from another.
195   /**
196    * This assignment operator moves an acceptor from one object to another.
197    *
198    * @param other The other basic_socket_acceptor object from which the move
199    * will occur.
200    *
201    * @note Following the move, the moved-from object is in the same state as if
202    * constructed using the @c basic_socket_acceptor(io_context&) constructor.
203    */
operator =(basic_socket_acceptor && other)204   basic_socket_acceptor& operator=(basic_socket_acceptor&& other)
205   {
206     basic_io_object<SocketAcceptorService>::operator=(
207         ASIO_MOVE_CAST(basic_socket_acceptor)(other));
208     return *this;
209   }
210 
211   // All socket acceptors have access to each other's implementations.
212   template <typename Protocol1, typename SocketAcceptorService1>
213   friend class basic_socket_acceptor;
214 
215   /// Move-construct a basic_socket_acceptor from an acceptor of another
216   /// protocol type.
217   /**
218    * This constructor moves an acceptor from one object to another.
219    *
220    * @param other The other basic_socket_acceptor object from which the move
221    * will occur.
222    *
223    * @note Following the move, the moved-from object is in the same state as if
224    * constructed using the @c basic_socket(io_context&) constructor.
225    */
226   template <typename Protocol1, typename SocketAcceptorService1>
basic_socket_acceptor(basic_socket_acceptor<Protocol1,SocketAcceptorService1> && other,typename enable_if<is_convertible<Protocol1,Protocol>::value>::type * =0)227   basic_socket_acceptor(
228       basic_socket_acceptor<Protocol1, SocketAcceptorService1>&& other,
229       typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
230     : basic_io_object<SocketAcceptorService>(
231         other.get_service().get_io_context())
232   {
233     this->get_service().template converting_move_construct<Protocol1>(
234         this->get_implementation(), other.get_implementation());
235   }
236 
237   /// Move-assign a basic_socket_acceptor from an acceptor of another protocol
238   /// type.
239   /**
240    * This assignment operator moves an acceptor from one object to another.
241    *
242    * @param other The other basic_socket_acceptor object from which the move
243    * will occur.
244    *
245    * @note Following the move, the moved-from object is in the same state as if
246    * constructed using the @c basic_socket(io_context&) constructor.
247    */
248   template <typename Protocol1, typename SocketAcceptorService1>
249   typename enable_if<is_convertible<Protocol1, Protocol>::value,
operator =(basic_socket_acceptor<Protocol1,SocketAcceptorService1> && other)250       basic_socket_acceptor>::type& operator=(
251         basic_socket_acceptor<Protocol1, SocketAcceptorService1>&& other)
252   {
253     basic_socket_acceptor tmp(ASIO_MOVE_CAST2(basic_socket_acceptor<
254             Protocol1, SocketAcceptorService1>)(other));
255     basic_io_object<SocketAcceptorService>::operator=(
256         ASIO_MOVE_CAST(basic_socket_acceptor)(tmp));
257     return *this;
258   }
259 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
260 
261   /// Open the acceptor using the specified protocol.
262   /**
263    * This function opens the socket acceptor so that it will use the specified
264    * protocol.
265    *
266    * @param protocol An object specifying which protocol is to be used.
267    *
268    * @throws asio::system_error Thrown on failure.
269    *
270    * @par Example
271    * @code
272    * asio::ip::tcp::acceptor acceptor(io_context);
273    * acceptor.open(asio::ip::tcp::v4());
274    * @endcode
275    */
open(const protocol_type & protocol=protocol_type ())276   void open(const protocol_type& protocol = protocol_type())
277   {
278     asio::error_code ec;
279     this->get_service().open(this->get_implementation(), protocol, ec);
280     asio::detail::throw_error(ec, "open");
281   }
282 
283   /// Open the acceptor using the specified protocol.
284   /**
285    * This function opens the socket acceptor so that it will use the specified
286    * protocol.
287    *
288    * @param protocol An object specifying which protocol is to be used.
289    *
290    * @param ec Set to indicate what error occurred, if any.
291    *
292    * @par Example
293    * @code
294    * asio::ip::tcp::acceptor acceptor(io_context);
295    * asio::error_code ec;
296    * acceptor.open(asio::ip::tcp::v4(), ec);
297    * if (ec)
298    * {
299    *   // An error occurred.
300    * }
301    * @endcode
302    */
open(const protocol_type & protocol,asio::error_code & ec)303   asio::error_code open(const protocol_type& protocol,
304       asio::error_code& ec)
305   {
306     return this->get_service().open(this->get_implementation(), protocol, ec);
307   }
308 
309   /// Assigns an existing native acceptor to the acceptor.
310   /*
311    * This function opens the acceptor to hold an existing native acceptor.
312    *
313    * @param protocol An object specifying which protocol is to be used.
314    *
315    * @param native_acceptor A native acceptor.
316    *
317    * @throws asio::system_error Thrown on failure.
318    */
assign(const protocol_type & protocol,const native_handle_type & native_acceptor)319   void assign(const protocol_type& protocol,
320       const native_handle_type& native_acceptor)
321   {
322     asio::error_code ec;
323     this->get_service().assign(this->get_implementation(),
324         protocol, native_acceptor, ec);
325     asio::detail::throw_error(ec, "assign");
326   }
327 
328   /// Assigns an existing native acceptor to the acceptor.
329   /*
330    * This function opens the acceptor to hold an existing native acceptor.
331    *
332    * @param protocol An object specifying which protocol is to be used.
333    *
334    * @param native_acceptor A native acceptor.
335    *
336    * @param ec Set to indicate what error occurred, if any.
337    */
assign(const protocol_type & protocol,const native_handle_type & native_acceptor,asio::error_code & ec)338   asio::error_code assign(const protocol_type& protocol,
339       const native_handle_type& native_acceptor, asio::error_code& ec)
340   {
341     return this->get_service().assign(this->get_implementation(),
342         protocol, native_acceptor, ec);
343   }
344 
345   /// Determine whether the acceptor is open.
is_open() const346   bool is_open() const
347   {
348     return this->get_service().is_open(this->get_implementation());
349   }
350 
351   /// Bind the acceptor to the given local endpoint.
352   /**
353    * This function binds the socket acceptor to the specified endpoint on the
354    * local machine.
355    *
356    * @param endpoint An endpoint on the local machine to which the socket
357    * acceptor will be bound.
358    *
359    * @throws asio::system_error Thrown on failure.
360    *
361    * @par Example
362    * @code
363    * asio::ip::tcp::acceptor acceptor(io_context);
364    * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), 12345);
365    * acceptor.open(endpoint.protocol());
366    * acceptor.bind(endpoint);
367    * @endcode
368    */
bind(const endpoint_type & endpoint)369   void bind(const endpoint_type& endpoint)
370   {
371     asio::error_code ec;
372     this->get_service().bind(this->get_implementation(), endpoint, ec);
373     asio::detail::throw_error(ec, "bind");
374   }
375 
376   /// Bind the acceptor to the given local endpoint.
377   /**
378    * This function binds the socket acceptor to the specified endpoint on the
379    * local machine.
380    *
381    * @param endpoint An endpoint on the local machine to which the socket
382    * acceptor will be bound.
383    *
384    * @param ec Set to indicate what error occurred, if any.
385    *
386    * @par Example
387    * @code
388    * asio::ip::tcp::acceptor acceptor(io_context);
389    * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), 12345);
390    * acceptor.open(endpoint.protocol());
391    * asio::error_code ec;
392    * acceptor.bind(endpoint, ec);
393    * if (ec)
394    * {
395    *   // An error occurred.
396    * }
397    * @endcode
398    */
bind(const endpoint_type & endpoint,asio::error_code & ec)399   asio::error_code bind(const endpoint_type& endpoint,
400       asio::error_code& ec)
401   {
402     return this->get_service().bind(this->get_implementation(), endpoint, ec);
403   }
404 
405   /// Place the acceptor into the state where it will listen for new
406   /// connections.
407   /**
408    * This function puts the socket acceptor into the state where it may accept
409    * new connections.
410    *
411    * @param backlog The maximum length of the queue of pending connections.
412    *
413    * @throws asio::system_error Thrown on failure.
414    */
listen(int backlog=socket_base::max_connections)415   void listen(int backlog = socket_base::max_connections)
416   {
417     asio::error_code ec;
418     this->get_service().listen(this->get_implementation(), backlog, ec);
419     asio::detail::throw_error(ec, "listen");
420   }
421 
422   /// Place the acceptor into the state where it will listen for new
423   /// connections.
424   /**
425    * This function puts the socket acceptor into the state where it may accept
426    * new connections.
427    *
428    * @param backlog The maximum length of the queue of pending connections.
429    *
430    * @param ec Set to indicate what error occurred, if any.
431    *
432    * @par Example
433    * @code
434    * asio::ip::tcp::acceptor acceptor(io_context);
435    * ...
436    * asio::error_code ec;
437    * acceptor.listen(asio::socket_base::max_connections, ec);
438    * if (ec)
439    * {
440    *   // An error occurred.
441    * }
442    * @endcode
443    */
listen(int backlog,asio::error_code & ec)444   asio::error_code listen(int backlog, asio::error_code& ec)
445   {
446     return this->get_service().listen(this->get_implementation(), backlog, ec);
447   }
448 
449   /// Close the acceptor.
450   /**
451    * This function is used to close the acceptor. Any asynchronous accept
452    * operations will be cancelled immediately.
453    *
454    * A subsequent call to open() is required before the acceptor can again be
455    * used to again perform socket accept operations.
456    *
457    * @throws asio::system_error Thrown on failure.
458    */
close()459   void close()
460   {
461     asio::error_code ec;
462     this->get_service().close(this->get_implementation(), ec);
463     asio::detail::throw_error(ec, "close");
464   }
465 
466   /// Close the acceptor.
467   /**
468    * This function is used to close the acceptor. Any asynchronous accept
469    * operations will be cancelled immediately.
470    *
471    * A subsequent call to open() is required before the acceptor can again be
472    * used to again perform socket accept operations.
473    *
474    * @param ec Set to indicate what error occurred, if any.
475    *
476    * @par Example
477    * @code
478    * asio::ip::tcp::acceptor acceptor(io_context);
479    * ...
480    * asio::error_code ec;
481    * acceptor.close(ec);
482    * if (ec)
483    * {
484    *   // An error occurred.
485    * }
486    * @endcode
487    */
close(asio::error_code & ec)488   asio::error_code close(asio::error_code& ec)
489   {
490     return this->get_service().close(this->get_implementation(), ec);
491   }
492 
493   /// Get the native acceptor representation.
494   /**
495    * This function may be used to obtain the underlying representation of the
496    * acceptor. This is intended to allow access to native acceptor functionality
497    * that is not otherwise provided.
498    */
native_handle()499   native_handle_type native_handle()
500   {
501     return this->get_service().native_handle(this->get_implementation());
502   }
503 
504   /// Cancel all asynchronous operations associated with the acceptor.
505   /**
506    * This function causes all outstanding asynchronous connect, send and receive
507    * operations to finish immediately, and the handlers for cancelled operations
508    * will be passed the asio::error::operation_aborted error.
509    *
510    * @throws asio::system_error Thrown on failure.
511    */
cancel()512   void cancel()
513   {
514     asio::error_code ec;
515     this->get_service().cancel(this->get_implementation(), ec);
516     asio::detail::throw_error(ec, "cancel");
517   }
518 
519   /// Cancel all asynchronous operations associated with the acceptor.
520   /**
521    * This function causes all outstanding asynchronous connect, send and receive
522    * operations to finish immediately, and the handlers for cancelled operations
523    * will be passed the asio::error::operation_aborted error.
524    *
525    * @param ec Set to indicate what error occurred, if any.
526    */
cancel(asio::error_code & ec)527   asio::error_code cancel(asio::error_code& ec)
528   {
529     return this->get_service().cancel(this->get_implementation(), ec);
530   }
531 
532   /// Set an option on the acceptor.
533   /**
534    * This function is used to set an option on the acceptor.
535    *
536    * @param option The new option value to be set on the acceptor.
537    *
538    * @throws asio::system_error Thrown on failure.
539    *
540    * @sa SettableSocketOption @n
541    * asio::socket_base::reuse_address
542    * asio::socket_base::enable_connection_aborted
543    *
544    * @par Example
545    * Setting the SOL_SOCKET/SO_REUSEADDR option:
546    * @code
547    * asio::ip::tcp::acceptor acceptor(io_context);
548    * ...
549    * asio::ip::tcp::acceptor::reuse_address option(true);
550    * acceptor.set_option(option);
551    * @endcode
552    */
553   template <typename SettableSocketOption>
set_option(const SettableSocketOption & option)554   void set_option(const SettableSocketOption& option)
555   {
556     asio::error_code ec;
557     this->get_service().set_option(this->get_implementation(), option, ec);
558     asio::detail::throw_error(ec, "set_option");
559   }
560 
561   /// Set an option on the acceptor.
562   /**
563    * This function is used to set an option on the acceptor.
564    *
565    * @param option The new option value to be set on the acceptor.
566    *
567    * @param ec Set to indicate what error occurred, if any.
568    *
569    * @sa SettableSocketOption @n
570    * asio::socket_base::reuse_address
571    * asio::socket_base::enable_connection_aborted
572    *
573    * @par Example
574    * Setting the SOL_SOCKET/SO_REUSEADDR option:
575    * @code
576    * asio::ip::tcp::acceptor acceptor(io_context);
577    * ...
578    * asio::ip::tcp::acceptor::reuse_address option(true);
579    * asio::error_code ec;
580    * acceptor.set_option(option, ec);
581    * if (ec)
582    * {
583    *   // An error occurred.
584    * }
585    * @endcode
586    */
587   template <typename SettableSocketOption>
set_option(const SettableSocketOption & option,asio::error_code & ec)588   asio::error_code set_option(const SettableSocketOption& option,
589       asio::error_code& ec)
590   {
591     return this->get_service().set_option(
592         this->get_implementation(), option, ec);
593   }
594 
595   /// Get an option from the acceptor.
596   /**
597    * This function is used to get the current value of an option on the
598    * acceptor.
599    *
600    * @param option The option value to be obtained from the acceptor.
601    *
602    * @throws asio::system_error Thrown on failure.
603    *
604    * @sa GettableSocketOption @n
605    * asio::socket_base::reuse_address
606    *
607    * @par Example
608    * Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
609    * @code
610    * asio::ip::tcp::acceptor acceptor(io_context);
611    * ...
612    * asio::ip::tcp::acceptor::reuse_address option;
613    * acceptor.get_option(option);
614    * bool is_set = option.get();
615    * @endcode
616    */
617   template <typename GettableSocketOption>
get_option(GettableSocketOption & option)618   void get_option(GettableSocketOption& option)
619   {
620     asio::error_code ec;
621     this->get_service().get_option(this->get_implementation(), option, ec);
622     asio::detail::throw_error(ec, "get_option");
623   }
624 
625   /// Get an option from the acceptor.
626   /**
627    * This function is used to get the current value of an option on the
628    * acceptor.
629    *
630    * @param option The option value to be obtained from the acceptor.
631    *
632    * @param ec Set to indicate what error occurred, if any.
633    *
634    * @sa GettableSocketOption @n
635    * asio::socket_base::reuse_address
636    *
637    * @par Example
638    * Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
639    * @code
640    * asio::ip::tcp::acceptor acceptor(io_context);
641    * ...
642    * asio::ip::tcp::acceptor::reuse_address option;
643    * asio::error_code ec;
644    * acceptor.get_option(option, ec);
645    * if (ec)
646    * {
647    *   // An error occurred.
648    * }
649    * bool is_set = option.get();
650    * @endcode
651    */
652   template <typename GettableSocketOption>
get_option(GettableSocketOption & option,asio::error_code & ec)653   asio::error_code get_option(GettableSocketOption& option,
654       asio::error_code& ec)
655   {
656     return this->get_service().get_option(
657         this->get_implementation(), option, ec);
658   }
659 
660   /// Perform an IO control command on the acceptor.
661   /**
662    * This function is used to execute an IO control command on the acceptor.
663    *
664    * @param command The IO control command to be performed on the acceptor.
665    *
666    * @throws asio::system_error Thrown on failure.
667    *
668    * @sa IoControlCommand @n
669    * asio::socket_base::non_blocking_io
670    *
671    * @par Example
672    * Getting the number of bytes ready to read:
673    * @code
674    * asio::ip::tcp::acceptor acceptor(io_context);
675    * ...
676    * asio::ip::tcp::acceptor::non_blocking_io command(true);
677    * socket.io_control(command);
678    * @endcode
679    */
680   template <typename IoControlCommand>
io_control(IoControlCommand & command)681   void io_control(IoControlCommand& command)
682   {
683     asio::error_code ec;
684     this->get_service().io_control(this->get_implementation(), command, ec);
685     asio::detail::throw_error(ec, "io_control");
686   }
687 
688   /// Perform an IO control command on the acceptor.
689   /**
690    * This function is used to execute an IO control command on the acceptor.
691    *
692    * @param command The IO control command to be performed on the acceptor.
693    *
694    * @param ec Set to indicate what error occurred, if any.
695    *
696    * @sa IoControlCommand @n
697    * asio::socket_base::non_blocking_io
698    *
699    * @par Example
700    * Getting the number of bytes ready to read:
701    * @code
702    * asio::ip::tcp::acceptor acceptor(io_context);
703    * ...
704    * asio::ip::tcp::acceptor::non_blocking_io command(true);
705    * asio::error_code ec;
706    * socket.io_control(command, ec);
707    * if (ec)
708    * {
709    *   // An error occurred.
710    * }
711    * @endcode
712    */
713   template <typename IoControlCommand>
io_control(IoControlCommand & command,asio::error_code & ec)714   asio::error_code io_control(IoControlCommand& command,
715       asio::error_code& ec)
716   {
717     return this->get_service().io_control(
718         this->get_implementation(), command, ec);
719   }
720 
721   /// Gets the non-blocking mode of the acceptor.
722   /**
723    * @returns @c true if the acceptor's synchronous operations will fail with
724    * asio::error::would_block if they are unable to perform the requested
725    * operation immediately. If @c false, synchronous operations will block
726    * until complete.
727    *
728    * @note The non-blocking mode has no effect on the behaviour of asynchronous
729    * operations. Asynchronous operations will never fail with the error
730    * asio::error::would_block.
731    */
non_blocking() const732   bool non_blocking() const
733   {
734     return this->get_service().non_blocking(this->get_implementation());
735   }
736 
737   /// Sets the non-blocking mode of the acceptor.
738   /**
739    * @param mode If @c true, the acceptor's synchronous operations will fail
740    * with asio::error::would_block if they are unable to perform the
741    * requested operation immediately. If @c false, synchronous operations will
742    * block until complete.
743    *
744    * @throws asio::system_error Thrown on failure.
745    *
746    * @note The non-blocking mode has no effect on the behaviour of asynchronous
747    * operations. Asynchronous operations will never fail with the error
748    * asio::error::would_block.
749    */
non_blocking(bool mode)750   void non_blocking(bool mode)
751   {
752     asio::error_code ec;
753     this->get_service().non_blocking(this->get_implementation(), mode, ec);
754     asio::detail::throw_error(ec, "non_blocking");
755   }
756 
757   /// Sets the non-blocking mode of the acceptor.
758   /**
759    * @param mode If @c true, the acceptor's synchronous operations will fail
760    * with asio::error::would_block if they are unable to perform the
761    * requested operation immediately. If @c false, synchronous operations will
762    * block until complete.
763    *
764    * @param ec Set to indicate what error occurred, if any.
765    *
766    * @note The non-blocking mode has no effect on the behaviour of asynchronous
767    * operations. Asynchronous operations will never fail with the error
768    * asio::error::would_block.
769    */
non_blocking(bool mode,asio::error_code & ec)770   asio::error_code non_blocking(
771       bool mode, asio::error_code& ec)
772   {
773     return this->get_service().non_blocking(
774         this->get_implementation(), mode, ec);
775   }
776 
777   /// Gets the non-blocking mode of the native acceptor implementation.
778   /**
779    * This function is used to retrieve the non-blocking mode of the underlying
780    * native acceptor. This mode has no effect on the behaviour of the acceptor
781    * object's synchronous operations.
782    *
783    * @returns @c true if the underlying acceptor is in non-blocking mode and
784    * direct system calls may fail with asio::error::would_block (or the
785    * equivalent system error).
786    *
787    * @note The current non-blocking mode is cached by the acceptor object.
788    * Consequently, the return value may be incorrect if the non-blocking mode
789    * was set directly on the native acceptor.
790    */
native_non_blocking() const791   bool native_non_blocking() const
792   {
793     return this->get_service().native_non_blocking(this->get_implementation());
794   }
795 
796   /// Sets the non-blocking mode of the native acceptor implementation.
797   /**
798    * This function is used to modify the non-blocking mode of the underlying
799    * native acceptor. It has no effect on the behaviour of the acceptor object's
800    * synchronous operations.
801    *
802    * @param mode If @c true, the underlying acceptor is put into non-blocking
803    * mode and direct system calls may fail with asio::error::would_block
804    * (or the equivalent system error).
805    *
806    * @throws asio::system_error Thrown on failure. If the @c mode is
807    * @c false, but the current value of @c non_blocking() is @c true, this
808    * function fails with asio::error::invalid_argument, as the
809    * combination does not make sense.
810    */
native_non_blocking(bool mode)811   void native_non_blocking(bool mode)
812   {
813     asio::error_code ec;
814     this->get_service().native_non_blocking(
815         this->get_implementation(), mode, ec);
816     asio::detail::throw_error(ec, "native_non_blocking");
817   }
818 
819   /// Sets the non-blocking mode of the native acceptor implementation.
820   /**
821    * This function is used to modify the non-blocking mode of the underlying
822    * native acceptor. It has no effect on the behaviour of the acceptor object's
823    * synchronous operations.
824    *
825    * @param mode If @c true, the underlying acceptor is put into non-blocking
826    * mode and direct system calls may fail with asio::error::would_block
827    * (or the equivalent system error).
828    *
829    * @param ec Set to indicate what error occurred, if any. If the @c mode is
830    * @c false, but the current value of @c non_blocking() is @c true, this
831    * function fails with asio::error::invalid_argument, as the
832    * combination does not make sense.
833    */
native_non_blocking(bool mode,asio::error_code & ec)834   asio::error_code native_non_blocking(
835       bool mode, asio::error_code& ec)
836   {
837     return this->get_service().native_non_blocking(
838         this->get_implementation(), mode, ec);
839   }
840 
841   /// Get the local endpoint of the acceptor.
842   /**
843    * This function is used to obtain the locally bound endpoint of the acceptor.
844    *
845    * @returns An object that represents the local endpoint of the acceptor.
846    *
847    * @throws asio::system_error Thrown on failure.
848    *
849    * @par Example
850    * @code
851    * asio::ip::tcp::acceptor acceptor(io_context);
852    * ...
853    * asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint();
854    * @endcode
855    */
local_endpoint() const856   endpoint_type local_endpoint() const
857   {
858     asio::error_code ec;
859     endpoint_type ep = this->get_service().local_endpoint(
860         this->get_implementation(), ec);
861     asio::detail::throw_error(ec, "local_endpoint");
862     return ep;
863   }
864 
865   /// Get the local endpoint of the acceptor.
866   /**
867    * This function is used to obtain the locally bound endpoint of the acceptor.
868    *
869    * @param ec Set to indicate what error occurred, if any.
870    *
871    * @returns An object that represents the local endpoint of the acceptor.
872    * Returns a default-constructed endpoint object if an error occurred and the
873    * error handler did not throw an exception.
874    *
875    * @par Example
876    * @code
877    * asio::ip::tcp::acceptor acceptor(io_context);
878    * ...
879    * asio::error_code ec;
880    * asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec);
881    * if (ec)
882    * {
883    *   // An error occurred.
884    * }
885    * @endcode
886    */
local_endpoint(asio::error_code & ec) const887   endpoint_type local_endpoint(asio::error_code& ec) const
888   {
889     return this->get_service().local_endpoint(this->get_implementation(), ec);
890   }
891 
892   /// Wait for the acceptor to become ready to read, ready to write, or to have
893   /// pending error conditions.
894   /**
895    * This function is used to perform a blocking wait for an acceptor to enter
896    * a ready to read, write or error condition state.
897    *
898    * @param w Specifies the desired acceptor state.
899    *
900    * @par Example
901    * Waiting for an acceptor to become readable.
902    * @code
903    * asio::ip::tcp::acceptor acceptor(io_context);
904    * ...
905    * acceptor.wait(asio::ip::tcp::acceptor::wait_read);
906    * @endcode
907    */
wait(wait_type w)908   void wait(wait_type w)
909   {
910     asio::error_code ec;
911     this->get_service().wait(this->get_implementation(), w, ec);
912     asio::detail::throw_error(ec, "wait");
913   }
914 
915   /// Wait for the acceptor to become ready to read, ready to write, or to have
916   /// pending error conditions.
917   /**
918    * This function is used to perform a blocking wait for an acceptor to enter
919    * a ready to read, write or error condition state.
920    *
921    * @param w Specifies the desired acceptor state.
922    *
923    * @param ec Set to indicate what error occurred, if any.
924    *
925    * @par Example
926    * Waiting for an acceptor to become readable.
927    * @code
928    * asio::ip::tcp::acceptor acceptor(io_context);
929    * ...
930    * asio::error_code ec;
931    * acceptor.wait(asio::ip::tcp::acceptor::wait_read, ec);
932    * @endcode
933    */
wait(wait_type w,asio::error_code & ec)934   asio::error_code wait(wait_type w, asio::error_code& ec)
935   {
936     return this->get_service().wait(this->get_implementation(), w, ec);
937   }
938 
939   /// Asynchronously wait for the acceptor to become ready to read, ready to
940   /// write, or to have pending error conditions.
941   /**
942    * This function is used to perform an asynchronous wait for an acceptor to
943    * enter a ready to read, write or error condition state.
944    *
945    * @param w Specifies the desired acceptor state.
946    *
947    * @param handler The handler to be called when the wait operation completes.
948    * Copies will be made of the handler as required. The function signature of
949    * the handler must be:
950    * @code void handler(
951    *   const asio::error_code& error // Result of operation
952    * ); @endcode
953    * Regardless of whether the asynchronous operation completes immediately or
954    * not, the handler will not be invoked from within this function. Invocation
955    * of the handler will be performed in a manner equivalent to using
956    * asio::io_context::post().
957    *
958    * @par Example
959    * @code
960    * void wait_handler(const asio::error_code& error)
961    * {
962    *   if (!error)
963    *   {
964    *     // Wait succeeded.
965    *   }
966    * }
967    *
968    * ...
969    *
970    * asio::ip::tcp::acceptor acceptor(io_context);
971    * ...
972    * acceptor.async_wait(
973    *     asio::ip::tcp::acceptor::wait_read,
974    *     wait_handler);
975    * @endcode
976    */
977   template <typename WaitHandler>
ASIO_INITFN_RESULT_TYPE(WaitHandler,void (asio::error_code))978   ASIO_INITFN_RESULT_TYPE(WaitHandler,
979       void (asio::error_code))
980   async_wait(wait_type w, ASIO_MOVE_ARG(WaitHandler) handler)
981   {
982     // If you get an error on the following line it means that your handler does
983     // not meet the documented type requirements for a WaitHandler.
984     ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
985 
986     return this->get_service().async_wait(this->get_implementation(),
987         w, ASIO_MOVE_CAST(WaitHandler)(handler));
988   }
989 
990   /// Accept a new connection.
991   /**
992    * This function is used to accept a new connection from a peer into the
993    * given socket. The function call will block until a new connection has been
994    * accepted successfully or an error occurs.
995    *
996    * @param peer The socket into which the new connection will be accepted.
997    *
998    * @throws asio::system_error Thrown on failure.
999    *
1000    * @par Example
1001    * @code
1002    * asio::ip::tcp::acceptor acceptor(io_context);
1003    * ...
1004    * asio::ip::tcp::socket socket(io_context);
1005    * acceptor.accept(socket);
1006    * @endcode
1007    */
1008   template <typename Protocol1, typename SocketService>
accept(basic_socket<Protocol1,SocketService> & peer,typename enable_if<is_convertible<Protocol,Protocol1>::value>::type * =0)1009   void accept(basic_socket<Protocol1, SocketService>& peer,
1010       typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
1011   {
1012     asio::error_code ec;
1013     this->get_service().accept(this->get_implementation(),
1014         peer, static_cast<endpoint_type*>(0), ec);
1015     asio::detail::throw_error(ec, "accept");
1016   }
1017 
1018   /// Accept a new connection.
1019   /**
1020    * This function is used to accept a new connection from a peer into the
1021    * given socket. The function call will block until a new connection has been
1022    * accepted successfully or an error occurs.
1023    *
1024    * @param peer The socket into which the new connection will be accepted.
1025    *
1026    * @param ec Set to indicate what error occurred, if any.
1027    *
1028    * @par Example
1029    * @code
1030    * asio::ip::tcp::acceptor acceptor(io_context);
1031    * ...
1032    * asio::ip::tcp::socket socket(io_context);
1033    * asio::error_code ec;
1034    * acceptor.accept(socket, ec);
1035    * if (ec)
1036    * {
1037    *   // An error occurred.
1038    * }
1039    * @endcode
1040    */
1041   template <typename Protocol1, typename SocketService>
accept(basic_socket<Protocol1,SocketService> & peer,asio::error_code & ec,typename enable_if<is_convertible<Protocol,Protocol1>::value>::type * =0)1042   asio::error_code accept(
1043       basic_socket<Protocol1, SocketService>& peer,
1044       asio::error_code& ec,
1045       typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
1046   {
1047     return this->get_service().accept(this->get_implementation(),
1048         peer, static_cast<endpoint_type*>(0), ec);
1049   }
1050 
1051   /// Start an asynchronous accept.
1052   /**
1053    * This function is used to asynchronously accept a new connection into a
1054    * socket. The function call always returns immediately.
1055    *
1056    * @param peer The socket into which the new connection will be accepted.
1057    * Ownership of the peer object is retained by the caller, which must
1058    * guarantee that it is valid until the handler is called.
1059    *
1060    * @param handler The handler to be called when the accept operation
1061    * completes. Copies will be made of the handler as required. The function
1062    * signature of the handler must be:
1063    * @code void handler(
1064    *   const asio::error_code& error // Result of operation.
1065    * ); @endcode
1066    * Regardless of whether the asynchronous operation completes immediately or
1067    * not, the handler will not be invoked from within this function. Invocation
1068    * of the handler will be performed in a manner equivalent to using
1069    * asio::io_context::post().
1070    *
1071    * @par Example
1072    * @code
1073    * void accept_handler(const asio::error_code& error)
1074    * {
1075    *   if (!error)
1076    *   {
1077    *     // Accept succeeded.
1078    *   }
1079    * }
1080    *
1081    * ...
1082    *
1083    * asio::ip::tcp::acceptor acceptor(io_context);
1084    * ...
1085    * asio::ip::tcp::socket socket(io_context);
1086    * acceptor.async_accept(socket, accept_handler);
1087    * @endcode
1088    */
1089   template <typename Protocol1, typename SocketService, typename AcceptHandler>
ASIO_INITFN_RESULT_TYPE(AcceptHandler,void (asio::error_code))1090   ASIO_INITFN_RESULT_TYPE(AcceptHandler,
1091       void (asio::error_code))
1092   async_accept(basic_socket<Protocol1, SocketService>& peer,
1093       ASIO_MOVE_ARG(AcceptHandler) handler,
1094       typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
1095   {
1096     // If you get an error on the following line it means that your handler does
1097     // not meet the documented type requirements for a AcceptHandler.
1098     ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check;
1099 
1100     return this->get_service().async_accept(this->get_implementation(),
1101         peer, static_cast<endpoint_type*>(0),
1102         ASIO_MOVE_CAST(AcceptHandler)(handler));
1103   }
1104 
1105   /// Accept a new connection and obtain the endpoint of the peer
1106   /**
1107    * This function is used to accept a new connection from a peer into the
1108    * given socket, and additionally provide the endpoint of the remote peer.
1109    * The function call will block until a new connection has been accepted
1110    * successfully or an error occurs.
1111    *
1112    * @param peer The socket into which the new connection will be accepted.
1113    *
1114    * @param peer_endpoint An endpoint object which will receive the endpoint of
1115    * the remote peer.
1116    *
1117    * @throws asio::system_error Thrown on failure.
1118    *
1119    * @par Example
1120    * @code
1121    * asio::ip::tcp::acceptor acceptor(io_context);
1122    * ...
1123    * asio::ip::tcp::socket socket(io_context);
1124    * asio::ip::tcp::endpoint endpoint;
1125    * acceptor.accept(socket, endpoint);
1126    * @endcode
1127    */
1128   template <typename SocketService>
accept(basic_socket<protocol_type,SocketService> & peer,endpoint_type & peer_endpoint)1129   void accept(basic_socket<protocol_type, SocketService>& peer,
1130       endpoint_type& peer_endpoint)
1131   {
1132     asio::error_code ec;
1133     this->get_service().accept(this->get_implementation(),
1134         peer, &peer_endpoint, ec);
1135     asio::detail::throw_error(ec, "accept");
1136   }
1137 
1138   /// Accept a new connection and obtain the endpoint of the peer
1139   /**
1140    * This function is used to accept a new connection from a peer into the
1141    * given socket, and additionally provide the endpoint of the remote peer.
1142    * The function call will block until a new connection has been accepted
1143    * successfully or an error occurs.
1144    *
1145    * @param peer The socket into which the new connection will be accepted.
1146    *
1147    * @param peer_endpoint An endpoint object which will receive the endpoint of
1148    * the remote peer.
1149    *
1150    * @param ec Set to indicate what error occurred, if any.
1151    *
1152    * @par Example
1153    * @code
1154    * asio::ip::tcp::acceptor acceptor(io_context);
1155    * ...
1156    * asio::ip::tcp::socket socket(io_context);
1157    * asio::ip::tcp::endpoint endpoint;
1158    * asio::error_code ec;
1159    * acceptor.accept(socket, endpoint, ec);
1160    * if (ec)
1161    * {
1162    *   // An error occurred.
1163    * }
1164    * @endcode
1165    */
1166   template <typename SocketService>
accept(basic_socket<protocol_type,SocketService> & peer,endpoint_type & peer_endpoint,asio::error_code & ec)1167   asio::error_code accept(
1168       basic_socket<protocol_type, SocketService>& peer,
1169       endpoint_type& peer_endpoint, asio::error_code& ec)
1170   {
1171     return this->get_service().accept(
1172         this->get_implementation(), peer, &peer_endpoint, ec);
1173   }
1174 
1175   /// Start an asynchronous accept.
1176   /**
1177    * This function is used to asynchronously accept a new connection into a
1178    * socket, and additionally obtain the endpoint of the remote peer. The
1179    * function call always returns immediately.
1180    *
1181    * @param peer The socket into which the new connection will be accepted.
1182    * Ownership of the peer object is retained by the caller, which must
1183    * guarantee that it is valid until the handler is called.
1184    *
1185    * @param peer_endpoint An endpoint object into which the endpoint of the
1186    * remote peer will be written. Ownership of the peer_endpoint object is
1187    * retained by the caller, which must guarantee that it is valid until the
1188    * handler is called.
1189    *
1190    * @param handler The handler to be called when the accept operation
1191    * completes. Copies will be made of the handler as required. The function
1192    * signature of the handler must be:
1193    * @code void handler(
1194    *   const asio::error_code& error // Result of operation.
1195    * ); @endcode
1196    * Regardless of whether the asynchronous operation completes immediately or
1197    * not, the handler will not be invoked from within this function. Invocation
1198    * of the handler will be performed in a manner equivalent to using
1199    * asio::io_context::post().
1200    */
1201   template <typename SocketService, typename AcceptHandler>
ASIO_INITFN_RESULT_TYPE(AcceptHandler,void (asio::error_code))1202   ASIO_INITFN_RESULT_TYPE(AcceptHandler,
1203       void (asio::error_code))
1204   async_accept(basic_socket<protocol_type, SocketService>& peer,
1205       endpoint_type& peer_endpoint, ASIO_MOVE_ARG(AcceptHandler) handler)
1206   {
1207     // If you get an error on the following line it means that your handler does
1208     // not meet the documented type requirements for a AcceptHandler.
1209     ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check;
1210 
1211     return this->get_service().async_accept(this->get_implementation(), peer,
1212         &peer_endpoint, ASIO_MOVE_CAST(AcceptHandler)(handler));
1213   }
1214 
1215 #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
1216   /// Accept a new connection.
1217   /**
1218    * This function is used to accept a new connection from a peer. The function
1219    * call will block until a new connection has been accepted successfully or
1220    * an error occurs.
1221    *
1222    * This overload requires that the Protocol template parameter satisfy the
1223    * AcceptableProtocol type requirements.
1224    *
1225    * @returns A socket object representing the newly accepted connection.
1226    *
1227    * @throws asio::system_error Thrown on failure.
1228    *
1229    * @par Example
1230    * @code
1231    * asio::ip::tcp::acceptor acceptor(io_context);
1232    * ...
1233    * asio::ip::tcp::socket socket(acceptor.accept());
1234    * @endcode
1235    */
accept()1236   typename Protocol::socket accept()
1237   {
1238     asio::error_code ec;
1239     typename Protocol::socket peer(
1240         this->get_service().accept(
1241           this->get_implementation(), 0, 0, ec));
1242     asio::detail::throw_error(ec, "accept");
1243     return peer;
1244   }
1245 
1246   /// Accept a new connection.
1247   /**
1248    * This function is used to accept a new connection from a peer. The function
1249    * call will block until a new connection has been accepted successfully or
1250    * an error occurs.
1251    *
1252    * This overload requires that the Protocol template parameter satisfy the
1253    * AcceptableProtocol type requirements.
1254    *
1255    * @param ec Set to indicate what error occurred, if any.
1256    *
1257    * @returns On success, a socket object representing the newly accepted
1258    * connection. On error, a socket object where is_open() is false.
1259    *
1260    * @par Example
1261    * @code
1262    * asio::ip::tcp::acceptor acceptor(io_context);
1263    * ...
1264    * asio::ip::tcp::socket socket(acceptor.accept(ec));
1265    * if (ec)
1266    * {
1267    *   // An error occurred.
1268    * }
1269    * @endcode
1270    */
accept(asio::error_code & ec)1271   typename Protocol::socket accept(asio::error_code& ec)
1272   {
1273     return this->get_service().accept(this->get_implementation(), 0, 0, ec);
1274   }
1275 
1276   /// Start an asynchronous accept.
1277   /**
1278    * This function is used to asynchronously accept a new connection. The
1279    * function call always returns immediately.
1280    *
1281    * This overload requires that the Protocol template parameter satisfy the
1282    * AcceptableProtocol type requirements.
1283    *
1284    * @param handler The handler to be called when the accept operation
1285    * completes. Copies will be made of the handler as required. The function
1286    * signature of the handler must be:
1287    * @code void handler(
1288    *   const asio::error_code& error, // Result of operation.
1289    *   typename Protocol::socket peer // On success, the newly accepted socket.
1290    * ); @endcode
1291    * Regardless of whether the asynchronous operation completes immediately or
1292    * not, the handler will not be invoked from within this function. Invocation
1293    * of the handler will be performed in a manner equivalent to using
1294    * asio::io_context::post().
1295    *
1296    * @par Example
1297    * @code
1298    * void accept_handler(const asio::error_code& error,
1299    *     asio::ip::tcp::socket peer)
1300    * {
1301    *   if (!error)
1302    *   {
1303    *     // Accept succeeded.
1304    *   }
1305    * }
1306    *
1307    * ...
1308    *
1309    * asio::ip::tcp::acceptor acceptor(io_context);
1310    * ...
1311    * acceptor.async_accept(accept_handler);
1312    * @endcode
1313    */
1314   template <typename MoveAcceptHandler>
ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,void (asio::error_code,typename Protocol::socket))1315   ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
1316       void (asio::error_code, typename Protocol::socket))
1317   async_accept(ASIO_MOVE_ARG(MoveAcceptHandler) handler)
1318   {
1319     // If you get an error on the following line it means that your handler does
1320     // not meet the documented type requirements for a MoveAcceptHandler.
1321     ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
1322         handler, typename Protocol::socket) type_check;
1323 
1324     return this->get_service().async_accept(
1325         this->get_implementation(), static_cast<asio::io_context*>(0),
1326         static_cast<endpoint_type*>(0),
1327         ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
1328   }
1329 
1330   /// Accept a new connection.
1331   /**
1332    * This function is used to accept a new connection from a peer. The function
1333    * call will block until a new connection has been accepted successfully or
1334    * an error occurs.
1335    *
1336    * This overload requires that the Protocol template parameter satisfy the
1337    * AcceptableProtocol type requirements.
1338    *
1339    * @param io_context The io_context object to be used for the newly accepted
1340    * socket.
1341    *
1342    * @returns A socket object representing the newly accepted connection.
1343    *
1344    * @throws asio::system_error Thrown on failure.
1345    *
1346    * @par Example
1347    * @code
1348    * asio::ip::tcp::acceptor acceptor(io_context);
1349    * ...
1350    * asio::ip::tcp::socket socket(acceptor.accept());
1351    * @endcode
1352    */
accept(asio::io_context & io_context)1353   typename Protocol::socket accept(asio::io_context& io_context)
1354   {
1355     asio::error_code ec;
1356     typename Protocol::socket peer(
1357         this->get_service().accept(this->get_implementation(),
1358           &io_context, static_cast<endpoint_type*>(0), ec));
1359     asio::detail::throw_error(ec, "accept");
1360     return peer;
1361   }
1362 
1363   /// Accept a new connection.
1364   /**
1365    * This function is used to accept a new connection from a peer. The function
1366    * call will block until a new connection has been accepted successfully or
1367    * an error occurs.
1368    *
1369    * This overload requires that the Protocol template parameter satisfy the
1370    * AcceptableProtocol type requirements.
1371    *
1372    * @param io_context The io_context object to be used for the newly accepted
1373    * socket.
1374    *
1375    * @param ec Set to indicate what error occurred, if any.
1376    *
1377    * @returns On success, a socket object representing the newly accepted
1378    * connection. On error, a socket object where is_open() is false.
1379    *
1380    * @par Example
1381    * @code
1382    * asio::ip::tcp::acceptor acceptor(io_context);
1383    * ...
1384    * asio::ip::tcp::socket socket(acceptor.accept(io_context2, ec));
1385    * if (ec)
1386    * {
1387    *   // An error occurred.
1388    * }
1389    * @endcode
1390    */
accept(asio::io_context & io_context,asio::error_code & ec)1391   typename Protocol::socket accept(
1392       asio::io_context& io_context, asio::error_code& ec)
1393   {
1394     return this->get_service().accept(this->get_implementation(),
1395         &io_context, static_cast<endpoint_type*>(0), ec);
1396   }
1397 
1398   /// Start an asynchronous accept.
1399   /**
1400    * This function is used to asynchronously accept a new connection. The
1401    * function call always returns immediately.
1402    *
1403    * This overload requires that the Protocol template parameter satisfy the
1404    * AcceptableProtocol type requirements.
1405    *
1406    * @param io_context The io_context object to be used for the newly accepted
1407    * socket.
1408    *
1409    * @param handler The handler to be called when the accept operation
1410    * completes. Copies will be made of the handler as required. The function
1411    * signature of the handler must be:
1412    * @code void handler(
1413    *   const asio::error_code& error, // Result of operation.
1414    *   typename Protocol::socket peer // On success, the newly accepted socket.
1415    * ); @endcode
1416    * Regardless of whether the asynchronous operation completes immediately or
1417    * not, the handler will not be invoked from within this function. Invocation
1418    * of the handler will be performed in a manner equivalent to using
1419    * asio::io_context::post().
1420    *
1421    * @par Example
1422    * @code
1423    * void accept_handler(const asio::error_code& error,
1424    *     asio::ip::tcp::socket peer)
1425    * {
1426    *   if (!error)
1427    *   {
1428    *     // Accept succeeded.
1429    *   }
1430    * }
1431    *
1432    * ...
1433    *
1434    * asio::ip::tcp::acceptor acceptor(io_context);
1435    * ...
1436    * acceptor.async_accept(io_context2, accept_handler);
1437    * @endcode
1438    */
1439   template <typename MoveAcceptHandler>
ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,void (asio::error_code,typename Protocol::socket))1440   ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
1441       void (asio::error_code, typename Protocol::socket))
1442   async_accept(asio::io_context& io_context,
1443       ASIO_MOVE_ARG(MoveAcceptHandler) handler)
1444   {
1445     // If you get an error on the following line it means that your handler does
1446     // not meet the documented type requirements for a MoveAcceptHandler.
1447     ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
1448         handler, typename Protocol::socket) type_check;
1449 
1450     return this->get_service().async_accept(this->get_implementation(),
1451         &io_context, static_cast<endpoint_type*>(0),
1452         ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
1453   }
1454 
1455   /// Accept a new connection.
1456   /**
1457    * This function is used to accept a new connection from a peer. The function
1458    * call will block until a new connection has been accepted successfully or
1459    * an error occurs.
1460    *
1461    * This overload requires that the Protocol template parameter satisfy the
1462    * AcceptableProtocol type requirements.
1463    *
1464    * @param peer_endpoint An endpoint object into which the endpoint of the
1465    * remote peer will be written.
1466    *
1467    * @returns A socket object representing the newly accepted connection.
1468    *
1469    * @throws asio::system_error Thrown on failure.
1470    *
1471    * @par Example
1472    * @code
1473    * asio::ip::tcp::acceptor acceptor(io_context);
1474    * ...
1475    * asio::ip::tcp::endpoint endpoint;
1476    * asio::ip::tcp::socket socket(acceptor.accept(endpoint));
1477    * @endcode
1478    */
accept(endpoint_type & peer_endpoint)1479   typename Protocol::socket accept(endpoint_type& peer_endpoint)
1480   {
1481     asio::error_code ec;
1482     typename Protocol::socket peer(
1483         this->get_service().accept(this->get_implementation(),
1484           static_cast<asio::io_context*>(0), &peer_endpoint, ec));
1485     asio::detail::throw_error(ec, "accept");
1486     return peer;
1487   }
1488 
1489   /// Accept a new connection.
1490   /**
1491    * This function is used to accept a new connection from a peer. The function
1492    * call will block until a new connection has been accepted successfully or
1493    * an error occurs.
1494    *
1495    * This overload requires that the Protocol template parameter satisfy the
1496    * AcceptableProtocol type requirements.
1497    *
1498    * @param peer_endpoint An endpoint object into which the endpoint of the
1499    * remote peer will be written.
1500    *
1501    * @param ec Set to indicate what error occurred, if any.
1502    *
1503    * @returns On success, a socket object representing the newly accepted
1504    * connection. On error, a socket object where is_open() is false.
1505    *
1506    * @par Example
1507    * @code
1508    * asio::ip::tcp::acceptor acceptor(io_context);
1509    * ...
1510    * asio::ip::tcp::endpoint endpoint;
1511    * asio::ip::tcp::socket socket(acceptor.accept(endpoint, ec));
1512    * if (ec)
1513    * {
1514    *   // An error occurred.
1515    * }
1516    * @endcode
1517    */
accept(endpoint_type & peer_endpoint,asio::error_code & ec)1518   typename Protocol::socket accept(
1519       endpoint_type& peer_endpoint, asio::error_code& ec)
1520   {
1521     return this->get_service().accept(this->get_implementation(),
1522         static_cast<asio::io_context*>(0), &peer_endpoint, ec);
1523   }
1524 
1525   /// Start an asynchronous accept.
1526   /**
1527    * This function is used to asynchronously accept a new connection. The
1528    * function call always returns immediately.
1529    *
1530    * This overload requires that the Protocol template parameter satisfy the
1531    * AcceptableProtocol type requirements.
1532    *
1533    * @param peer_endpoint An endpoint object into which the endpoint of the
1534    * remote peer will be written. Ownership of the peer_endpoint object is
1535    * retained by the caller, which must guarantee that it is valid until the
1536    * handler is called.
1537    *
1538    * @param handler The handler to be called when the accept operation
1539    * completes. Copies will be made of the handler as required. The function
1540    * signature of the handler must be:
1541    * @code void handler(
1542    *   const asio::error_code& error, // Result of operation.
1543    *   typename Protocol::socket peer // On success, the newly accepted socket.
1544    * ); @endcode
1545    * Regardless of whether the asynchronous operation completes immediately or
1546    * not, the handler will not be invoked from within this function. Invocation
1547    * of the handler will be performed in a manner equivalent to using
1548    * asio::io_context::post().
1549    *
1550    * @par Example
1551    * @code
1552    * void accept_handler(const asio::error_code& error,
1553    *     asio::ip::tcp::socket peer)
1554    * {
1555    *   if (!error)
1556    *   {
1557    *     // Accept succeeded.
1558    *   }
1559    * }
1560    *
1561    * ...
1562    *
1563    * asio::ip::tcp::acceptor acceptor(io_context);
1564    * ...
1565    * asio::ip::tcp::endpoint endpoint;
1566    * acceptor.async_accept(endpoint, accept_handler);
1567    * @endcode
1568    */
1569   template <typename MoveAcceptHandler>
ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,void (asio::error_code,typename Protocol::socket))1570   ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
1571       void (asio::error_code, typename Protocol::socket))
1572   async_accept(endpoint_type& peer_endpoint,
1573       ASIO_MOVE_ARG(MoveAcceptHandler) handler)
1574   {
1575     // If you get an error on the following line it means that your handler does
1576     // not meet the documented type requirements for a MoveAcceptHandler.
1577     ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
1578         handler, typename Protocol::socket) type_check;
1579 
1580     return this->get_service().async_accept(this->get_implementation(),
1581         static_cast<asio::io_context*>(0), &peer_endpoint,
1582         ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
1583   }
1584 
1585   /// Accept a new connection.
1586   /**
1587    * This function is used to accept a new connection from a peer. The function
1588    * call will block until a new connection has been accepted successfully or
1589    * an error occurs.
1590    *
1591    * This overload requires that the Protocol template parameter satisfy the
1592    * AcceptableProtocol type requirements.
1593    *
1594    * @param io_context The io_context object to be used for the newly accepted
1595    * socket.
1596    *
1597    * @param peer_endpoint An endpoint object into which the endpoint of the
1598    * remote peer will be written.
1599    *
1600    * @returns A socket object representing the newly accepted connection.
1601    *
1602    * @throws asio::system_error Thrown on failure.
1603    *
1604    * @par Example
1605    * @code
1606    * asio::ip::tcp::acceptor acceptor(io_context);
1607    * ...
1608    * asio::ip::tcp::endpoint endpoint;
1609    * asio::ip::tcp::socket socket(
1610    *     acceptor.accept(io_context2, endpoint));
1611    * @endcode
1612    */
accept(asio::io_context & io_context,endpoint_type & peer_endpoint)1613   typename Protocol::socket accept(
1614       asio::io_context& io_context, endpoint_type& peer_endpoint)
1615   {
1616     asio::error_code ec;
1617     typename Protocol::socket peer(
1618         this->get_service().accept(this->get_implementation(),
1619           &io_context, &peer_endpoint, ec));
1620     asio::detail::throw_error(ec, "accept");
1621     return peer;
1622   }
1623 
1624   /// Accept a new connection.
1625   /**
1626    * This function is used to accept a new connection from a peer. The function
1627    * call will block until a new connection has been accepted successfully or
1628    * an error occurs.
1629    *
1630    * This overload requires that the Protocol template parameter satisfy the
1631    * AcceptableProtocol type requirements.
1632    *
1633    * @param io_context The io_context object to be used for the newly accepted
1634    * socket.
1635    *
1636    * @param peer_endpoint An endpoint object into which the endpoint of the
1637    * remote peer will be written.
1638    *
1639    * @param ec Set to indicate what error occurred, if any.
1640    *
1641    * @returns On success, a socket object representing the newly accepted
1642    * connection. On error, a socket object where is_open() is false.
1643    *
1644    * @par Example
1645    * @code
1646    * asio::ip::tcp::acceptor acceptor(io_context);
1647    * ...
1648    * asio::ip::tcp::endpoint endpoint;
1649    * asio::ip::tcp::socket socket(
1650    *     acceptor.accept(io_context2, endpoint, ec));
1651    * if (ec)
1652    * {
1653    *   // An error occurred.
1654    * }
1655    * @endcode
1656    */
accept(asio::io_context & io_context,endpoint_type & peer_endpoint,asio::error_code & ec)1657   typename Protocol::socket accept(asio::io_context& io_context,
1658       endpoint_type& peer_endpoint, asio::error_code& ec)
1659   {
1660     return this->get_service().accept(this->get_implementation(),
1661         &io_context, &peer_endpoint, ec);
1662   }
1663 
1664   /// Start an asynchronous accept.
1665   /**
1666    * This function is used to asynchronously accept a new connection. The
1667    * function call always returns immediately.
1668    *
1669    * This overload requires that the Protocol template parameter satisfy the
1670    * AcceptableProtocol type requirements.
1671    *
1672    * @param io_context The io_context object to be used for the newly accepted
1673    * socket.
1674    *
1675    * @param peer_endpoint An endpoint object into which the endpoint of the
1676    * remote peer will be written. Ownership of the peer_endpoint object is
1677    * retained by the caller, which must guarantee that it is valid until the
1678    * handler is called.
1679    *
1680    * @param handler The handler to be called when the accept operation
1681    * completes. Copies will be made of the handler as required. The function
1682    * signature of the handler must be:
1683    * @code void handler(
1684    *   const asio::error_code& error, // Result of operation.
1685    *   typename Protocol::socket peer // On success, the newly accepted socket.
1686    * ); @endcode
1687    * Regardless of whether the asynchronous operation completes immediately or
1688    * not, the handler will not be invoked from within this function. Invocation
1689    * of the handler will be performed in a manner equivalent to using
1690    * asio::io_context::post().
1691    *
1692    * @par Example
1693    * @code
1694    * void accept_handler(const asio::error_code& error,
1695    *     asio::ip::tcp::socket peer)
1696    * {
1697    *   if (!error)
1698    *   {
1699    *     // Accept succeeded.
1700    *   }
1701    * }
1702    *
1703    * ...
1704    *
1705    * asio::ip::tcp::acceptor acceptor(io_context);
1706    * ...
1707    * asio::ip::tcp::endpoint endpoint;
1708    * acceptor.async_accept(io_context2, endpoint, accept_handler);
1709    * @endcode
1710    */
1711   template <typename MoveAcceptHandler>
ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,void (asio::error_code,typename Protocol::socket))1712   ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
1713       void (asio::error_code, typename Protocol::socket))
1714   async_accept(asio::io_context& io_context,
1715       endpoint_type& peer_endpoint,
1716       ASIO_MOVE_ARG(MoveAcceptHandler) handler)
1717   {
1718     // If you get an error on the following line it means that your handler does
1719     // not meet the documented type requirements for a MoveAcceptHandler.
1720     ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
1721         handler, typename Protocol::socket) type_check;
1722 
1723     return this->get_service().async_accept(
1724         this->get_implementation(), &io_context, &peer_endpoint,
1725         ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
1726   }
1727 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
1728 };
1729 
1730 } // namespace asio
1731 
1732 #include "asio/detail/pop_options.hpp"
1733 
1734 #endif // ASIO_BASIC_SOCKET_ACCEPTOR_HPP
1735