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