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 
15 #include "asio/detail/config.hpp"
16 #include "asio/basic_io_object.hpp"
17 #include "asio/basic_socket.hpp"
18 #include "asio/detail/handler_type_requirements.hpp"
19 #include "asio/detail/throw_error.hpp"
20 #include "asio/detail/type_traits.hpp"
21 #include "asio/error.hpp"
22 #include "asio/socket_acceptor_service.hpp"
23 #include "asio/socket_base.hpp"
24 
25 #include "asio/detail/push_options.hpp"
26 
27 namespace asio {
28 
29 /// Provides the ability to accept new connections.
30 /**
31  * The basic_socket_acceptor class template is used for accepting new socket
32  * connections.
33  *
34  * @par Thread Safety
35  * @e Distinct @e objects: Safe.@n
36  * @e Shared @e objects: Unsafe.
37  *
38  * @par Example
39  * Opening a socket acceptor with the SO_REUSEADDR option enabled:
40  * @code
41  * asio::ip::tcp::acceptor acceptor(io_service);
42  * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), port);
43  * acceptor.open(endpoint.protocol());
44  * acceptor.set_option(asio::ip::tcp::acceptor::reuse_address(true));
45  * acceptor.bind(endpoint);
46  * acceptor.listen();
47  * @endcode
48  */
49 template <typename Protocol,
50     typename SocketAcceptorService = socket_acceptor_service<Protocol> >
51 class basic_socket_acceptor
52   : public basic_io_object<SocketAcceptorService>,
53     public socket_base
54 {
55 public:
56   /// (Deprecated: Use native_handle_type.) The native representation of an
57   /// acceptor.
58   typedef typename SocketAcceptorService::native_handle_type native_type;
59 
60   /// The native representation of an acceptor.
61   typedef typename SocketAcceptorService::native_handle_type native_handle_type;
62 
63   /// The protocol type.
64   typedef Protocol protocol_type;
65 
66   /// The endpoint type.
67   typedef typename Protocol::endpoint endpoint_type;
68 
69   /// Construct an acceptor without opening it.
70   /**
71    * This constructor creates an acceptor without opening it to listen for new
72    * connections. The open() function must be called before the acceptor can
73    * accept new socket connections.
74    *
75    * @param io_service The io_service object that the acceptor will use to
76    * dispatch handlers for any asynchronous operations performed on the
77    * acceptor.
78    */
basic_socket_acceptor(asio::io_service & io_service)79   explicit basic_socket_acceptor(asio::io_service& io_service)
80     : basic_io_object<SocketAcceptorService>(io_service)
81   {
82   }
83 
84   /// Construct an open acceptor.
85   /**
86    * This constructor creates an acceptor and automatically opens it.
87    *
88    * @param io_service The io_service object that the acceptor will use to
89    * dispatch handlers for any asynchronous operations performed on the
90    * acceptor.
91    *
92    * @param protocol An object specifying protocol parameters to be used.
93    *
94    * @throws asio::system_error Thrown on failure.
95    */
basic_socket_acceptor(asio::io_service & io_service,const protocol_type & protocol)96   basic_socket_acceptor(asio::io_service& io_service,
97       const protocol_type& protocol)
98     : basic_io_object<SocketAcceptorService>(io_service)
99   {
100     asio::error_code ec;
101     this->get_service().open(this->get_implementation(), protocol, ec);
102     asio::detail::throw_error(ec, "open");
103   }
104 
105   /// Construct an acceptor opened on the given endpoint.
106   /**
107    * This constructor creates an acceptor and automatically opens it to listen
108    * for new connections on the specified endpoint.
109    *
110    * @param io_service The io_service object that the acceptor will use to
111    * dispatch handlers for any asynchronous operations performed on the
112    * acceptor.
113    *
114    * @param endpoint An endpoint on the local machine on which the acceptor
115    * will listen for new connections.
116    *
117    * @param reuse_addr Whether the constructor should set the socket option
118    * socket_base::reuse_address.
119    *
120    * @throws asio::system_error Thrown on failure.
121    *
122    * @note This constructor is equivalent to the following code:
123    * @code
124    * basic_socket_acceptor<Protocol> acceptor(io_service);
125    * acceptor.open(endpoint.protocol());
126    * if (reuse_addr)
127    *   acceptor.set_option(socket_base::reuse_address(true));
128    * acceptor.bind(endpoint);
129    * acceptor.listen(listen_backlog);
130    * @endcode
131    */
basic_socket_acceptor(asio::io_service & io_service,const endpoint_type & endpoint,bool reuse_addr=true)132   basic_socket_acceptor(asio::io_service& io_service,
133       const endpoint_type& endpoint, bool reuse_addr = true)
134     : basic_io_object<SocketAcceptorService>(io_service)
135   {
136     asio::error_code ec;
137     const protocol_type protocol = endpoint.protocol();
138     this->get_service().open(this->get_implementation(), protocol, ec);
139     asio::detail::throw_error(ec, "open");
140     if (reuse_addr)
141     {
142       this->get_service().set_option(this->get_implementation(),
143           socket_base::reuse_address(true), ec);
144       asio::detail::throw_error(ec, "set_option");
145     }
146     this->get_service().bind(this->get_implementation(), endpoint, ec);
147     asio::detail::throw_error(ec, "bind");
148     this->get_service().listen(this->get_implementation(),
149         socket_base::max_connections, ec);
150     asio::detail::throw_error(ec, "listen");
151   }
152 
153   /// Construct a basic_socket_acceptor on an existing native acceptor.
154   /**
155    * This constructor creates an acceptor object to hold an existing native
156    * acceptor.
157    *
158    * @param io_service The io_service object that the acceptor will use to
159    * dispatch handlers for any asynchronous operations performed on the
160    * acceptor.
161    *
162    * @param protocol An object specifying protocol parameters to be used.
163    *
164    * @param native_acceptor A native acceptor.
165    *
166    * @throws asio::system_error Thrown on failure.
167    */
basic_socket_acceptor(asio::io_service & io_service,const protocol_type & protocol,const native_handle_type & native_acceptor)168   basic_socket_acceptor(asio::io_service& io_service,
169       const protocol_type& protocol, const native_handle_type& native_acceptor)
170     : basic_io_object<SocketAcceptorService>(io_service)
171   {
172     asio::error_code ec;
173     this->get_service().assign(this->get_implementation(),
174         protocol, native_acceptor, ec);
175     asio::detail::throw_error(ec, "assign");
176   }
177 
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_service&) 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_service&) 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_service&) 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>(other.get_io_service())
231   {
232     this->get_service().template converting_move_construct<Protocol1>(
233         this->get_implementation(), other.get_implementation());
234   }
235 
236   /// Move-assign a basic_socket_acceptor from an acceptor of another protocol
237   /// type.
238   /**
239    * This assignment operator moves an acceptor from one object to another.
240    *
241    * @param other The other basic_socket_acceptor object from which the move
242    * will occur.
243    *
244    * @note Following the move, the moved-from object is in the same state as if
245    * constructed using the @c basic_socket(io_service&) constructor.
246    */
247   template <typename Protocol1, typename SocketAcceptorService1>
248   typename enable_if<is_convertible<Protocol1, Protocol>::value,
operator =(basic_socket_acceptor<Protocol1,SocketAcceptorService1> && other)249       basic_socket_acceptor>::type& operator=(
250         basic_socket_acceptor<Protocol1, SocketAcceptorService1>&& other)
251   {
252     basic_socket_acceptor tmp(ASIO_MOVE_CAST2(basic_socket_acceptor<
253             Protocol1, SocketAcceptorService1>)(other));
254     basic_io_object<SocketAcceptorService>::operator=(
255         ASIO_MOVE_CAST(basic_socket_acceptor)(tmp));
256     return *this;
257   }
258 
259   /// Open the acceptor using the specified protocol.
260   /**
261    * This function opens the socket acceptor so that it will use the specified
262    * protocol.
263    *
264    * @param protocol An object specifying which protocol is to be used.
265    *
266    * @throws asio::system_error Thrown on failure.
267    *
268    * @par Example
269    * @code
270    * asio::ip::tcp::acceptor acceptor(io_service);
271    * acceptor.open(asio::ip::tcp::v4());
272    * @endcode
273    */
open(const protocol_type & protocol=protocol_type ())274   void open(const protocol_type& protocol = protocol_type())
275   {
276     asio::error_code ec;
277     this->get_service().open(this->get_implementation(), protocol, ec);
278     asio::detail::throw_error(ec, "open");
279   }
280 
281   /// Open the acceptor using the specified protocol.
282   /**
283    * This function opens the socket acceptor so that it will use the specified
284    * protocol.
285    *
286    * @param protocol An object specifying which protocol is to be used.
287    *
288    * @param ec Set to indicate what error occurred, if any.
289    *
290    * @par Example
291    * @code
292    * asio::ip::tcp::acceptor acceptor(io_service);
293    * asio::error_code ec;
294    * acceptor.open(asio::ip::tcp::v4(), ec);
295    * if (ec)
296    * {
297    *   // An error occurred.
298    * }
299    * @endcode
300    */
open(const protocol_type & protocol,asio::error_code & ec)301   asio::error_code open(const protocol_type& protocol,
302       asio::error_code& ec)
303   {
304     return this->get_service().open(this->get_implementation(), protocol, ec);
305   }
306 
307   /// Assigns an existing native acceptor to the acceptor.
308   /*
309    * This function opens the acceptor to hold an existing native acceptor.
310    *
311    * @param protocol An object specifying which protocol is to be used.
312    *
313    * @param native_acceptor A native acceptor.
314    *
315    * @throws asio::system_error Thrown on failure.
316    */
assign(const protocol_type & protocol,const native_handle_type & native_acceptor)317   void assign(const protocol_type& protocol,
318       const native_handle_type& native_acceptor)
319   {
320     asio::error_code ec;
321     this->get_service().assign(this->get_implementation(),
322         protocol, native_acceptor, ec);
323     asio::detail::throw_error(ec, "assign");
324   }
325 
326   /// Assigns an existing native acceptor to the acceptor.
327   /*
328    * This function opens the acceptor to hold an existing native acceptor.
329    *
330    * @param protocol An object specifying which protocol is to be used.
331    *
332    * @param native_acceptor A native acceptor.
333    *
334    * @param ec Set to indicate what error occurred, if any.
335    */
assign(const protocol_type & protocol,const native_handle_type & native_acceptor,asio::error_code & ec)336   asio::error_code assign(const protocol_type& protocol,
337       const native_handle_type& native_acceptor, asio::error_code& ec)
338   {
339     return this->get_service().assign(this->get_implementation(),
340         protocol, native_acceptor, ec);
341   }
342 
343   /// Determine whether the acceptor is open.
is_open() const344   bool is_open() const
345   {
346     return this->get_service().is_open(this->get_implementation());
347   }
348 
349   /// Bind the acceptor to the given local endpoint.
350   /**
351    * This function binds the socket acceptor to the specified endpoint on the
352    * local machine.
353    *
354    * @param endpoint An endpoint on the local machine to which the socket
355    * acceptor will be bound.
356    *
357    * @throws asio::system_error Thrown on failure.
358    *
359    * @par Example
360    * @code
361    * asio::ip::tcp::acceptor acceptor(io_service);
362    * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), 12345);
363    * acceptor.open(endpoint.protocol());
364    * acceptor.bind(endpoint);
365    * @endcode
366    */
bind(const endpoint_type & endpoint)367   void bind(const endpoint_type& endpoint)
368   {
369     asio::error_code ec;
370     this->get_service().bind(this->get_implementation(), endpoint, ec);
371     asio::detail::throw_error(ec, "bind");
372   }
373 
374   /// Bind the acceptor to the given local endpoint.
375   /**
376    * This function binds the socket acceptor to the specified endpoint on the
377    * local machine.
378    *
379    * @param endpoint An endpoint on the local machine to which the socket
380    * acceptor will be bound.
381    *
382    * @param ec Set to indicate what error occurred, if any.
383    *
384    * @par Example
385    * @code
386    * asio::ip::tcp::acceptor acceptor(io_service);
387    * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), 12345);
388    * acceptor.open(endpoint.protocol());
389    * asio::error_code ec;
390    * acceptor.bind(endpoint, ec);
391    * if (ec)
392    * {
393    *   // An error occurred.
394    * }
395    * @endcode
396    */
bind(const endpoint_type & endpoint,asio::error_code & ec)397   asio::error_code bind(const endpoint_type& endpoint,
398       asio::error_code& ec)
399   {
400     return this->get_service().bind(this->get_implementation(), endpoint, ec);
401   }
402 
403   /// Place the acceptor into the state where it will listen for new
404   /// connections.
405   /**
406    * This function puts the socket acceptor into the state where it may accept
407    * new connections.
408    *
409    * @param backlog The maximum length of the queue of pending connections.
410    *
411    * @throws asio::system_error Thrown on failure.
412    */
listen(int backlog=socket_base::max_connections)413   void listen(int backlog = socket_base::max_connections)
414   {
415     asio::error_code ec;
416     this->get_service().listen(this->get_implementation(), backlog, ec);
417     asio::detail::throw_error(ec, "listen");
418   }
419 
420   /// Place the acceptor into the state where it will listen for new
421   /// connections.
422   /**
423    * This function puts the socket acceptor into the state where it may accept
424    * new connections.
425    *
426    * @param backlog The maximum length of the queue of pending connections.
427    *
428    * @param ec Set to indicate what error occurred, if any.
429    *
430    * @par Example
431    * @code
432    * asio::ip::tcp::acceptor acceptor(io_service);
433    * ...
434    * asio::error_code ec;
435    * acceptor.listen(asio::socket_base::max_connections, ec);
436    * if (ec)
437    * {
438    *   // An error occurred.
439    * }
440    * @endcode
441    */
listen(int backlog,asio::error_code & ec)442   asio::error_code listen(int backlog, asio::error_code& ec)
443   {
444     return this->get_service().listen(this->get_implementation(), backlog, ec);
445   }
446 
447   /// Close the acceptor.
448   /**
449    * This function is used to close the acceptor. Any asynchronous accept
450    * operations will be cancelled immediately.
451    *
452    * A subsequent call to open() is required before the acceptor can again be
453    * used to again perform socket accept operations.
454    *
455    * @throws asio::system_error Thrown on failure.
456    */
close()457   void close()
458   {
459     asio::error_code ec;
460     this->get_service().close(this->get_implementation(), ec);
461     asio::detail::throw_error(ec, "close");
462   }
463 
464   /// Close the acceptor.
465   /**
466    * This function is used to close the acceptor. Any asynchronous accept
467    * operations will be cancelled immediately.
468    *
469    * A subsequent call to open() is required before the acceptor can again be
470    * used to again perform socket accept operations.
471    *
472    * @param ec Set to indicate what error occurred, if any.
473    *
474    * @par Example
475    * @code
476    * asio::ip::tcp::acceptor acceptor(io_service);
477    * ...
478    * asio::error_code ec;
479    * acceptor.close(ec);
480    * if (ec)
481    * {
482    *   // An error occurred.
483    * }
484    * @endcode
485    */
close(asio::error_code & ec)486   asio::error_code close(asio::error_code& ec)
487   {
488     return this->get_service().close(this->get_implementation(), ec);
489   }
490 
491   /// (Deprecated: Use native_handle().) Get the native acceptor representation.
492   /**
493    * This function may be used to obtain the underlying representation of the
494    * acceptor. This is intended to allow access to native acceptor functionality
495    * that is not otherwise provided.
496    */
native()497   native_type native()
498   {
499     return this->get_service().native_handle(this->get_implementation());
500   }
501 
502   /// Get the native acceptor representation.
503   /**
504    * This function may be used to obtain the underlying representation of the
505    * acceptor. This is intended to allow access to native acceptor functionality
506    * that is not otherwise provided.
507    */
native_handle()508   native_handle_type native_handle()
509   {
510     return this->get_service().native_handle(this->get_implementation());
511   }
512 
513   /// Cancel all asynchronous operations associated with the acceptor.
514   /**
515    * This function causes all outstanding asynchronous connect, send and receive
516    * operations to finish immediately, and the handlers for cancelled operations
517    * will be passed the asio::error::operation_aborted error.
518    *
519    * @throws asio::system_error Thrown on failure.
520    */
cancel()521   void cancel()
522   {
523     asio::error_code ec;
524     this->get_service().cancel(this->get_implementation(), ec);
525     asio::detail::throw_error(ec, "cancel");
526   }
527 
528   /// Cancel all asynchronous operations associated with the acceptor.
529   /**
530    * This function causes all outstanding asynchronous connect, send and receive
531    * operations to finish immediately, and the handlers for cancelled operations
532    * will be passed the asio::error::operation_aborted error.
533    *
534    * @param ec Set to indicate what error occurred, if any.
535    */
cancel(asio::error_code & ec)536   asio::error_code cancel(asio::error_code& ec)
537   {
538     return this->get_service().cancel(this->get_implementation(), ec);
539   }
540 
541   /// Set an option on the acceptor.
542   /**
543    * This function is used to set an option on the acceptor.
544    *
545    * @param option The new option value to be set on the acceptor.
546    *
547    * @throws asio::system_error Thrown on failure.
548    *
549    * @sa SettableSocketOption @n
550    * asio::socket_base::reuse_address
551    * asio::socket_base::enable_connection_aborted
552    *
553    * @par Example
554    * Setting the SOL_SOCKET/SO_REUSEADDR option:
555    * @code
556    * asio::ip::tcp::acceptor acceptor(io_service);
557    * ...
558    * asio::ip::tcp::acceptor::reuse_address option(true);
559    * acceptor.set_option(option);
560    * @endcode
561    */
562   template <typename SettableSocketOption>
set_option(const SettableSocketOption & option)563   void set_option(const SettableSocketOption& option)
564   {
565     asio::error_code ec;
566     this->get_service().set_option(this->get_implementation(), option, ec);
567     asio::detail::throw_error(ec, "set_option");
568   }
569 
570   /// Set an option on the acceptor.
571   /**
572    * This function is used to set an option on the acceptor.
573    *
574    * @param option The new option value to be set on the acceptor.
575    *
576    * @param ec Set to indicate what error occurred, if any.
577    *
578    * @sa SettableSocketOption @n
579    * asio::socket_base::reuse_address
580    * asio::socket_base::enable_connection_aborted
581    *
582    * @par Example
583    * Setting the SOL_SOCKET/SO_REUSEADDR option:
584    * @code
585    * asio::ip::tcp::acceptor acceptor(io_service);
586    * ...
587    * asio::ip::tcp::acceptor::reuse_address option(true);
588    * asio::error_code ec;
589    * acceptor.set_option(option, ec);
590    * if (ec)
591    * {
592    *   // An error occurred.
593    * }
594    * @endcode
595    */
596   template <typename SettableSocketOption>
set_option(const SettableSocketOption & option,asio::error_code & ec)597   asio::error_code set_option(const SettableSocketOption& option,
598       asio::error_code& ec)
599   {
600     return this->get_service().set_option(
601         this->get_implementation(), option, ec);
602   }
603 
604   /// Get an option from the acceptor.
605   /**
606    * This function is used to get the current value of an option on the
607    * acceptor.
608    *
609    * @param option The option value to be obtained from the acceptor.
610    *
611    * @throws asio::system_error Thrown on failure.
612    *
613    * @sa GettableSocketOption @n
614    * asio::socket_base::reuse_address
615    *
616    * @par Example
617    * Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
618    * @code
619    * asio::ip::tcp::acceptor acceptor(io_service);
620    * ...
621    * asio::ip::tcp::acceptor::reuse_address option;
622    * acceptor.get_option(option);
623    * bool is_set = option.get();
624    * @endcode
625    */
626   template <typename GettableSocketOption>
get_option(GettableSocketOption & option)627   void get_option(GettableSocketOption& option)
628   {
629     asio::error_code ec;
630     this->get_service().get_option(this->get_implementation(), option, ec);
631     asio::detail::throw_error(ec, "get_option");
632   }
633 
634   /// Get an option from the acceptor.
635   /**
636    * This function is used to get the current value of an option on the
637    * acceptor.
638    *
639    * @param option The option value to be obtained from the acceptor.
640    *
641    * @param ec Set to indicate what error occurred, if any.
642    *
643    * @sa GettableSocketOption @n
644    * asio::socket_base::reuse_address
645    *
646    * @par Example
647    * Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
648    * @code
649    * asio::ip::tcp::acceptor acceptor(io_service);
650    * ...
651    * asio::ip::tcp::acceptor::reuse_address option;
652    * asio::error_code ec;
653    * acceptor.get_option(option, ec);
654    * if (ec)
655    * {
656    *   // An error occurred.
657    * }
658    * bool is_set = option.get();
659    * @endcode
660    */
661   template <typename GettableSocketOption>
get_option(GettableSocketOption & option,asio::error_code & ec)662   asio::error_code get_option(GettableSocketOption& option,
663       asio::error_code& ec)
664   {
665     return this->get_service().get_option(
666         this->get_implementation(), option, ec);
667   }
668 
669   /// Perform an IO control command on the acceptor.
670   /**
671    * This function is used to execute an IO control command on the acceptor.
672    *
673    * @param command The IO control command to be performed on the acceptor.
674    *
675    * @throws asio::system_error Thrown on failure.
676    *
677    * @sa IoControlCommand @n
678    * asio::socket_base::non_blocking_io
679    *
680    * @par Example
681    * Getting the number of bytes ready to read:
682    * @code
683    * asio::ip::tcp::acceptor acceptor(io_service);
684    * ...
685    * asio::ip::tcp::acceptor::non_blocking_io command(true);
686    * socket.io_control(command);
687    * @endcode
688    */
689   template <typename IoControlCommand>
io_control(IoControlCommand & command)690   void io_control(IoControlCommand& command)
691   {
692     asio::error_code ec;
693     this->get_service().io_control(this->get_implementation(), command, ec);
694     asio::detail::throw_error(ec, "io_control");
695   }
696 
697   /// Perform an IO control command on the acceptor.
698   /**
699    * This function is used to execute an IO control command on the acceptor.
700    *
701    * @param command The IO control command to be performed on the acceptor.
702    *
703    * @param ec Set to indicate what error occurred, if any.
704    *
705    * @sa IoControlCommand @n
706    * asio::socket_base::non_blocking_io
707    *
708    * @par Example
709    * Getting the number of bytes ready to read:
710    * @code
711    * asio::ip::tcp::acceptor acceptor(io_service);
712    * ...
713    * asio::ip::tcp::acceptor::non_blocking_io command(true);
714    * asio::error_code ec;
715    * socket.io_control(command, ec);
716    * if (ec)
717    * {
718    *   // An error occurred.
719    * }
720    * @endcode
721    */
722   template <typename IoControlCommand>
io_control(IoControlCommand & command,asio::error_code & ec)723   asio::error_code io_control(IoControlCommand& command,
724       asio::error_code& ec)
725   {
726     return this->get_service().io_control(
727         this->get_implementation(), command, ec);
728   }
729 
730   /// Gets the non-blocking mode of the acceptor.
731   /**
732    * @returns @c true if the acceptor's synchronous operations will fail with
733    * asio::error::would_block if they are unable to perform the requested
734    * operation immediately. If @c false, synchronous operations will block
735    * until complete.
736    *
737    * @note The non-blocking mode has no effect on the behaviour of asynchronous
738    * operations. Asynchronous operations will never fail with the error
739    * asio::error::would_block.
740    */
non_blocking() const741   bool non_blocking() const
742   {
743     return this->get_service().non_blocking(this->get_implementation());
744   }
745 
746   /// Sets the non-blocking mode of the acceptor.
747   /**
748    * @param mode If @c true, the acceptor's synchronous operations will fail
749    * with asio::error::would_block if they are unable to perform the
750    * requested operation immediately. If @c false, synchronous operations will
751    * block until complete.
752    *
753    * @throws asio::system_error Thrown on failure.
754    *
755    * @note The non-blocking mode has no effect on the behaviour of asynchronous
756    * operations. Asynchronous operations will never fail with the error
757    * asio::error::would_block.
758    */
non_blocking(bool mode)759   void non_blocking(bool mode)
760   {
761     asio::error_code ec;
762     this->get_service().non_blocking(this->get_implementation(), mode, ec);
763     asio::detail::throw_error(ec, "non_blocking");
764   }
765 
766   /// Sets the non-blocking mode of the acceptor.
767   /**
768    * @param mode If @c true, the acceptor's synchronous operations will fail
769    * with asio::error::would_block if they are unable to perform the
770    * requested operation immediately. If @c false, synchronous operations will
771    * block until complete.
772    *
773    * @param ec Set to indicate what error occurred, if any.
774    *
775    * @note The non-blocking mode has no effect on the behaviour of asynchronous
776    * operations. Asynchronous operations will never fail with the error
777    * asio::error::would_block.
778    */
non_blocking(bool mode,asio::error_code & ec)779   asio::error_code non_blocking(
780       bool mode, asio::error_code& ec)
781   {
782     return this->get_service().non_blocking(
783         this->get_implementation(), mode, ec);
784   }
785 
786   /// Gets the non-blocking mode of the native acceptor implementation.
787   /**
788    * This function is used to retrieve the non-blocking mode of the underlying
789    * native acceptor. This mode has no effect on the behaviour of the acceptor
790    * object's synchronous operations.
791    *
792    * @returns @c true if the underlying acceptor is in non-blocking mode and
793    * direct system calls may fail with asio::error::would_block (or the
794    * equivalent system error).
795    *
796    * @note The current non-blocking mode is cached by the acceptor object.
797    * Consequently, the return value may be incorrect if the non-blocking mode
798    * was set directly on the native acceptor.
799    */
native_non_blocking() const800   bool native_non_blocking() const
801   {
802     return this->get_service().native_non_blocking(this->get_implementation());
803   }
804 
805   /// Sets the non-blocking mode of the native acceptor implementation.
806   /**
807    * This function is used to modify the non-blocking mode of the underlying
808    * native acceptor. It has no effect on the behaviour of the acceptor object's
809    * synchronous operations.
810    *
811    * @param mode If @c true, the underlying acceptor is put into non-blocking
812    * mode and direct system calls may fail with asio::error::would_block
813    * (or the equivalent system error).
814    *
815    * @throws asio::system_error Thrown on failure. If the @c mode is
816    * @c false, but the current value of @c non_blocking() is @c true, this
817    * function fails with asio::error::invalid_argument, as the
818    * combination does not make sense.
819    */
native_non_blocking(bool mode)820   void native_non_blocking(bool mode)
821   {
822     asio::error_code ec;
823     this->get_service().native_non_blocking(
824         this->get_implementation(), mode, ec);
825     asio::detail::throw_error(ec, "native_non_blocking");
826   }
827 
828   /// Sets the non-blocking mode of the native acceptor implementation.
829   /**
830    * This function is used to modify the non-blocking mode of the underlying
831    * native acceptor. It has no effect on the behaviour of the acceptor object's
832    * synchronous operations.
833    *
834    * @param mode If @c true, the underlying acceptor is put into non-blocking
835    * mode and direct system calls may fail with asio::error::would_block
836    * (or the equivalent system error).
837    *
838    * @param ec Set to indicate what error occurred, if any. If the @c mode is
839    * @c false, but the current value of @c non_blocking() is @c true, this
840    * function fails with asio::error::invalid_argument, as the
841    * combination does not make sense.
842    */
native_non_blocking(bool mode,asio::error_code & ec)843   asio::error_code native_non_blocking(
844       bool mode, asio::error_code& ec)
845   {
846     return this->get_service().native_non_blocking(
847         this->get_implementation(), mode, ec);
848   }
849 
850   /// Get the local endpoint of the acceptor.
851   /**
852    * This function is used to obtain the locally bound endpoint of the acceptor.
853    *
854    * @returns An object that represents the local endpoint of the acceptor.
855    *
856    * @throws asio::system_error Thrown on failure.
857    *
858    * @par Example
859    * @code
860    * asio::ip::tcp::acceptor acceptor(io_service);
861    * ...
862    * asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint();
863    * @endcode
864    */
local_endpoint() const865   endpoint_type local_endpoint() const
866   {
867     asio::error_code ec;
868     endpoint_type ep = this->get_service().local_endpoint(
869         this->get_implementation(), ec);
870     asio::detail::throw_error(ec, "local_endpoint");
871     return ep;
872   }
873 
874   /// Get the local endpoint of the acceptor.
875   /**
876    * This function is used to obtain the locally bound endpoint of the acceptor.
877    *
878    * @param ec Set to indicate what error occurred, if any.
879    *
880    * @returns An object that represents the local endpoint of the acceptor.
881    * Returns a default-constructed endpoint object if an error occurred and the
882    * error handler did not throw an exception.
883    *
884    * @par Example
885    * @code
886    * asio::ip::tcp::acceptor acceptor(io_service);
887    * ...
888    * asio::error_code ec;
889    * asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec);
890    * if (ec)
891    * {
892    *   // An error occurred.
893    * }
894    * @endcode
895    */
local_endpoint(asio::error_code & ec) const896   endpoint_type local_endpoint(asio::error_code& ec) const
897   {
898     return this->get_service().local_endpoint(this->get_implementation(), ec);
899   }
900 
901   /// Accept a new connection.
902   /**
903    * This function is used to accept a new connection from a peer into the
904    * given socket. The function call will block until a new connection has been
905    * accepted successfully or an error occurs.
906    *
907    * @param peer The socket into which the new connection will be accepted.
908    *
909    * @throws asio::system_error Thrown on failure.
910    *
911    * @par Example
912    * @code
913    * asio::ip::tcp::acceptor acceptor(io_service);
914    * ...
915    * asio::ip::tcp::socket socket(io_service);
916    * acceptor.accept(socket);
917    * @endcode
918    */
919   template <typename Protocol1, typename SocketService>
accept(basic_socket<Protocol1,SocketService> & peer,typename enable_if<is_convertible<Protocol,Protocol1>::value>::type * =0)920   void accept(basic_socket<Protocol1, SocketService>& peer,
921       typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
922   {
923     asio::error_code ec;
924     this->get_service().accept(this->get_implementation(),
925         peer, static_cast<endpoint_type*>(0), ec);
926     asio::detail::throw_error(ec, "accept");
927   }
928 
929   /// Accept a new connection.
930   /**
931    * This function is used to accept a new connection from a peer into the
932    * given socket. The function call will block until a new connection has been
933    * accepted successfully or an error occurs.
934    *
935    * @param peer The socket into which the new connection will be accepted.
936    *
937    * @param ec Set to indicate what error occurred, if any.
938    *
939    * @par Example
940    * @code
941    * asio::ip::tcp::acceptor acceptor(io_service);
942    * ...
943    * asio::ip::tcp::soocket socket(io_service);
944    * asio::error_code ec;
945    * acceptor.accept(socket, ec);
946    * if (ec)
947    * {
948    *   // An error occurred.
949    * }
950    * @endcode
951    */
952   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)953   asio::error_code accept(
954       basic_socket<Protocol1, SocketService>& peer,
955       asio::error_code& ec,
956       typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
957   {
958     return this->get_service().accept(this->get_implementation(),
959         peer, static_cast<endpoint_type*>(0), ec);
960   }
961 
962   /// Start an asynchronous accept.
963   /**
964    * This function is used to asynchronously accept a new connection into a
965    * socket. The function call always returns immediately.
966    *
967    * @param peer The socket into which the new connection will be accepted.
968    * Ownership of the peer object is retained by the caller, which must
969    * guarantee that it is valid until the handler is called.
970    *
971    * @param handler The handler to be called when the accept operation
972    * completes. Copies will be made of the handler as required. The function
973    * signature of the handler must be:
974    * @code void handler(
975    *   const asio::error_code& error // Result of operation.
976    * ); @endcode
977    * Regardless of whether the asynchronous operation completes immediately or
978    * not, the handler will not be invoked from within this function. Invocation
979    * of the handler will be performed in a manner equivalent to using
980    * asio::io_service::post().
981    *
982    * @par Example
983    * @code
984    * void accept_handler(const asio::error_code& error)
985    * {
986    *   if (!error)
987    *   {
988    *     // Accept succeeded.
989    *   }
990    * }
991    *
992    * ...
993    *
994    * asio::ip::tcp::acceptor acceptor(io_service);
995    * ...
996    * asio::ip::tcp::socket socket(io_service);
997    * acceptor.async_accept(socket, accept_handler);
998    * @endcode
999    */
1000   template <typename Protocol1, typename SocketService, typename AcceptHandler>
ASIO_INITFN_RESULT_TYPE(AcceptHandler,void (asio::error_code))1001   ASIO_INITFN_RESULT_TYPE(AcceptHandler,
1002       void (asio::error_code))
1003   async_accept(basic_socket<Protocol1, SocketService>& peer,
1004       ASIO_MOVE_ARG(AcceptHandler) handler,
1005       typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
1006   {
1007     // If you get an error on the following line it means that your handler does
1008     // not meet the documented type requirements for a AcceptHandler.
1009     ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check;
1010 
1011     return this->get_service().async_accept(this->get_implementation(),
1012         peer, static_cast<endpoint_type*>(0),
1013         ASIO_MOVE_CAST(AcceptHandler)(handler));
1014   }
1015 
1016   /// Accept a new connection and obtain the endpoint of the peer
1017   /**
1018    * This function is used to accept a new connection from a peer into the
1019    * given socket, and additionally provide the endpoint of the remote peer.
1020    * The function call will block until a new connection has been accepted
1021    * successfully or an error occurs.
1022    *
1023    * @param peer The socket into which the new connection will be accepted.
1024    *
1025    * @param peer_endpoint An endpoint object which will receive the endpoint of
1026    * the remote peer.
1027    *
1028    * @throws asio::system_error Thrown on failure.
1029    *
1030    * @par Example
1031    * @code
1032    * asio::ip::tcp::acceptor acceptor(io_service);
1033    * ...
1034    * asio::ip::tcp::socket socket(io_service);
1035    * asio::ip::tcp::endpoint endpoint;
1036    * acceptor.accept(socket, endpoint);
1037    * @endcode
1038    */
1039   template <typename SocketService>
accept(basic_socket<protocol_type,SocketService> & peer,endpoint_type & peer_endpoint)1040   void accept(basic_socket<protocol_type, SocketService>& peer,
1041       endpoint_type& peer_endpoint)
1042   {
1043     asio::error_code ec;
1044     this->get_service().accept(this->get_implementation(),
1045         peer, &peer_endpoint, ec);
1046     asio::detail::throw_error(ec, "accept");
1047   }
1048 
1049   /// Accept a new connection and obtain the endpoint of the peer
1050   /**
1051    * This function is used to accept a new connection from a peer into the
1052    * given socket, and additionally provide the endpoint of the remote peer.
1053    * The function call will block until a new connection has been accepted
1054    * successfully or an error occurs.
1055    *
1056    * @param peer The socket into which the new connection will be accepted.
1057    *
1058    * @param peer_endpoint An endpoint object which will receive the endpoint of
1059    * the remote peer.
1060    *
1061    * @param ec Set to indicate what error occurred, if any.
1062    *
1063    * @par Example
1064    * @code
1065    * asio::ip::tcp::acceptor acceptor(io_service);
1066    * ...
1067    * asio::ip::tcp::socket socket(io_service);
1068    * asio::ip::tcp::endpoint endpoint;
1069    * asio::error_code ec;
1070    * acceptor.accept(socket, endpoint, ec);
1071    * if (ec)
1072    * {
1073    *   // An error occurred.
1074    * }
1075    * @endcode
1076    */
1077   template <typename SocketService>
accept(basic_socket<protocol_type,SocketService> & peer,endpoint_type & peer_endpoint,asio::error_code & ec)1078   asio::error_code accept(
1079       basic_socket<protocol_type, SocketService>& peer,
1080       endpoint_type& peer_endpoint, asio::error_code& ec)
1081   {
1082     return this->get_service().accept(
1083         this->get_implementation(), peer, &peer_endpoint, ec);
1084   }
1085 
1086   /// Start an asynchronous accept.
1087   /**
1088    * This function is used to asynchronously accept a new connection into a
1089    * socket, and additionally obtain the endpoint of the remote peer. The
1090    * function call always returns immediately.
1091    *
1092    * @param peer The socket into which the new connection will be accepted.
1093    * Ownership of the peer object is retained by the caller, which must
1094    * guarantee that it is valid until the handler is called.
1095    *
1096    * @param peer_endpoint An endpoint object into which the endpoint of the
1097    * remote peer will be written. Ownership of the peer_endpoint object is
1098    * retained by the caller, which must guarantee that it is valid until the
1099    * handler is called.
1100    *
1101    * @param handler The handler to be called when the accept operation
1102    * completes. Copies will be made of the handler as required. The function
1103    * signature of the handler must be:
1104    * @code void handler(
1105    *   const asio::error_code& error // Result of operation.
1106    * ); @endcode
1107    * Regardless of whether the asynchronous operation completes immediately or
1108    * not, the handler will not be invoked from within this function. Invocation
1109    * of the handler will be performed in a manner equivalent to using
1110    * asio::io_service::post().
1111    */
1112   template <typename SocketService, typename AcceptHandler>
ASIO_INITFN_RESULT_TYPE(AcceptHandler,void (asio::error_code))1113   ASIO_INITFN_RESULT_TYPE(AcceptHandler,
1114       void (asio::error_code))
1115   async_accept(basic_socket<protocol_type, SocketService>& peer,
1116       endpoint_type& peer_endpoint, ASIO_MOVE_ARG(AcceptHandler) handler)
1117   {
1118     // If you get an error on the following line it means that your handler does
1119     // not meet the documented type requirements for a AcceptHandler.
1120     ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check;
1121 
1122     return this->get_service().async_accept(this->get_implementation(), peer,
1123         &peer_endpoint, ASIO_MOVE_CAST(AcceptHandler)(handler));
1124   }
1125 };
1126 
1127 } // namespace asio
1128 
1129 #include "asio/detail/pop_options.hpp"
1130 
1131 #endif // ASIO_BASIC_SOCKET_ACCEPTOR_HPP
1132