2 // basic_socket_acceptor.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~
5 // Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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)
11 #ifndef BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_HPP
12 #define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_HPP
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18 #include <boost/asio/detail/push_options.hpp>
20 #include <boost/asio/basic_io_object.hpp>
21 #include <boost/asio/basic_socket.hpp>
22 #include <boost/asio/error.hpp>
23 #include <boost/asio/socket_acceptor_service.hpp>
24 #include <boost/asio/socket_base.hpp>
25 #include <boost/asio/detail/throw_error.hpp>
30 /// Provides the ability to accept new connections.
32 * The basic_socket_acceptor class template is used for accepting new socket
36 * @e Distinct @e objects: Safe.@n
37 * @e Shared @e objects: Unsafe.
40 * Opening a socket acceptor with the SO_REUSEADDR option enabled:
42 * boost::asio::ip::tcp::acceptor acceptor(io_service);
43 * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port);
44 * acceptor.open(endpoint.protocol());
45 * acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
46 * acceptor.bind(endpoint);
50 template <typename Protocol
,
51 typename SocketAcceptorService
= socket_acceptor_service
<Protocol
> >
52 class basic_socket_acceptor
53 : public basic_io_object
<SocketAcceptorService
>,
57 /// The native representation of an acceptor.
58 typedef typename
SocketAcceptorService::native_type native_type
;
60 /// The protocol type.
61 typedef Protocol protocol_type
;
63 /// The endpoint type.
64 typedef typename
Protocol::endpoint endpoint_type
;
66 /// Construct an acceptor without opening it.
68 * This constructor creates an acceptor without opening it to listen for new
69 * connections. The open() function must be called before the acceptor can
70 * accept new socket connections.
72 * @param io_service The io_service object that the acceptor will use to
73 * dispatch handlers for any asynchronous operations performed on the
76 explicit basic_socket_acceptor(boost::asio::io_service
& io_service
)
77 : basic_io_object
<SocketAcceptorService
>(io_service
)
81 /// Construct an open acceptor.
83 * This constructor creates an acceptor and automatically opens it.
85 * @param io_service The io_service object that the acceptor will use to
86 * dispatch handlers for any asynchronous operations performed on the
89 * @param protocol An object specifying protocol parameters to be used.
91 * @throws boost::system::system_error Thrown on failure.
93 basic_socket_acceptor(boost::asio::io_service
& io_service
,
94 const protocol_type
& protocol
)
95 : basic_io_object
<SocketAcceptorService
>(io_service
)
97 boost::system::error_code ec
;
98 this->service
.open(this->implementation
, protocol
, ec
);
99 boost::asio::detail::throw_error(ec
);
102 /// Construct an acceptor opened on the given endpoint.
104 * This constructor creates an acceptor and automatically opens it to listen
105 * for new connections on the specified endpoint.
107 * @param io_service The io_service object that the acceptor will use to
108 * dispatch handlers for any asynchronous operations performed on the
111 * @param endpoint An endpoint on the local machine on which the acceptor
112 * will listen for new connections.
114 * @param reuse_addr Whether the constructor should set the socket option
115 * socket_base::reuse_address.
117 * @throws boost::system::system_error Thrown on failure.
119 * @note This constructor is equivalent to the following code:
121 * basic_socket_acceptor<Protocol> acceptor(io_service);
122 * acceptor.open(endpoint.protocol());
124 * acceptor.set_option(socket_base::reuse_address(true));
125 * acceptor.bind(endpoint);
126 * acceptor.listen(listen_backlog);
129 basic_socket_acceptor(boost::asio::io_service
& io_service
,
130 const endpoint_type
& endpoint
, bool reuse_addr
= true)
131 : basic_io_object
<SocketAcceptorService
>(io_service
)
133 boost::system::error_code ec
;
134 this->service
.open(this->implementation
, endpoint
.protocol(), ec
);
135 boost::asio::detail::throw_error(ec
);
138 this->service
.set_option(this->implementation
,
139 socket_base::reuse_address(true), ec
);
140 boost::asio::detail::throw_error(ec
);
142 this->service
.bind(this->implementation
, endpoint
, ec
);
143 boost::asio::detail::throw_error(ec
);
144 this->service
.listen(this->implementation
,
145 socket_base::max_connections
, ec
);
146 boost::asio::detail::throw_error(ec
);
149 /// Construct a basic_socket_acceptor on an existing native acceptor.
151 * This constructor creates an acceptor object to hold an existing native
154 * @param io_service The io_service object that the acceptor will use to
155 * dispatch handlers for any asynchronous operations performed on the
158 * @param protocol An object specifying protocol parameters to be used.
160 * @param native_acceptor A native acceptor.
162 * @throws boost::system::system_error Thrown on failure.
164 basic_socket_acceptor(boost::asio::io_service
& io_service
,
165 const protocol_type
& protocol
, const native_type
& native_acceptor
)
166 : basic_io_object
<SocketAcceptorService
>(io_service
)
168 boost::system::error_code ec
;
169 this->service
.assign(this->implementation
, protocol
, native_acceptor
, ec
);
170 boost::asio::detail::throw_error(ec
);
173 /// Open the acceptor using the specified protocol.
175 * This function opens the socket acceptor so that it will use the specified
178 * @param protocol An object specifying which protocol is to be used.
180 * @throws boost::system::system_error Thrown on failure.
184 * boost::asio::ip::tcp::acceptor acceptor(io_service);
185 * acceptor.open(boost::asio::ip::tcp::v4());
188 void open(const protocol_type
& protocol
= protocol_type())
190 boost::system::error_code ec
;
191 this->service
.open(this->implementation
, protocol
, ec
);
192 boost::asio::detail::throw_error(ec
);
195 /// Open the acceptor using the specified protocol.
197 * This function opens the socket acceptor so that it will use the specified
200 * @param protocol An object specifying which protocol is to be used.
202 * @param ec Set to indicate what error occurred, if any.
206 * boost::asio::ip::tcp::acceptor acceptor(io_service);
207 * boost::system::error_code ec;
208 * acceptor.open(boost::asio::ip::tcp::v4(), ec);
211 * // An error occurred.
215 boost::system::error_code
open(const protocol_type
& protocol
,
216 boost::system::error_code
& ec
)
218 return this->service
.open(this->implementation
, protocol
, ec
);
221 /// Assigns an existing native acceptor to the acceptor.
223 * This function opens the acceptor to hold an existing native acceptor.
225 * @param protocol An object specifying which protocol is to be used.
227 * @param native_acceptor A native acceptor.
229 * @throws boost::system::system_error Thrown on failure.
231 void assign(const protocol_type
& protocol
, const native_type
& native_acceptor
)
233 boost::system::error_code ec
;
234 this->service
.assign(this->implementation
, protocol
, native_acceptor
, ec
);
235 boost::asio::detail::throw_error(ec
);
238 /// Assigns an existing native acceptor to the acceptor.
240 * This function opens the acceptor to hold an existing native acceptor.
242 * @param protocol An object specifying which protocol is to be used.
244 * @param native_acceptor A native acceptor.
246 * @param ec Set to indicate what error occurred, if any.
248 boost::system::error_code
assign(const protocol_type
& protocol
,
249 const native_type
& native_acceptor
, boost::system::error_code
& ec
)
251 return this->service
.assign(this->implementation
,
252 protocol
, native_acceptor
, ec
);
255 /// Determine whether the acceptor is open.
258 return this->service
.is_open(this->implementation
);
261 /// Bind the acceptor to the given local endpoint.
263 * This function binds the socket acceptor to the specified endpoint on the
266 * @param endpoint An endpoint on the local machine to which the socket
267 * acceptor will be bound.
269 * @throws boost::system::system_error Thrown on failure.
273 * boost::asio::ip::tcp::acceptor acceptor(io_service);
274 * acceptor.open(boost::asio::ip::tcp::v4());
275 * acceptor.bind(boost::asio::ip::tcp::endpoint(12345));
278 void bind(const endpoint_type
& endpoint
)
280 boost::system::error_code ec
;
281 this->service
.bind(this->implementation
, endpoint
, ec
);
282 boost::asio::detail::throw_error(ec
);
285 /// Bind the acceptor to the given local endpoint.
287 * This function binds the socket acceptor to the specified endpoint on the
290 * @param endpoint An endpoint on the local machine to which the socket
291 * acceptor will be bound.
293 * @param ec Set to indicate what error occurred, if any.
297 * boost::asio::ip::tcp::acceptor acceptor(io_service);
298 * acceptor.open(boost::asio::ip::tcp::v4());
299 * boost::system::error_code ec;
300 * acceptor.bind(boost::asio::ip::tcp::endpoint(12345), ec);
303 * // An error occurred.
307 boost::system::error_code
bind(const endpoint_type
& endpoint
,
308 boost::system::error_code
& ec
)
310 return this->service
.bind(this->implementation
, endpoint
, ec
);
313 /// Place the acceptor into the state where it will listen for new
316 * This function puts the socket acceptor into the state where it may accept
319 * @param backlog The maximum length of the queue of pending connections.
321 * @throws boost::system::system_error Thrown on failure.
323 void listen(int backlog
= socket_base::max_connections
)
325 boost::system::error_code ec
;
326 this->service
.listen(this->implementation
, backlog
, ec
);
327 boost::asio::detail::throw_error(ec
);
330 /// Place the acceptor into the state where it will listen for new
333 * This function puts the socket acceptor into the state where it may accept
336 * @param backlog The maximum length of the queue of pending connections.
338 * @param ec Set to indicate what error occurred, if any.
342 * boost::asio::ip::tcp::acceptor acceptor(io_service);
344 * boost::system::error_code ec;
345 * acceptor.listen(boost::asio::socket_base::max_connections, ec);
348 * // An error occurred.
352 boost::system::error_code
listen(int backlog
, boost::system::error_code
& ec
)
354 return this->service
.listen(this->implementation
, backlog
, ec
);
357 /// Close the acceptor.
359 * This function is used to close the acceptor. Any asynchronous accept
360 * operations will be cancelled immediately.
362 * A subsequent call to open() is required before the acceptor can again be
363 * used to again perform socket accept operations.
365 * @throws boost::system::system_error Thrown on failure.
369 boost::system::error_code ec
;
370 this->service
.close(this->implementation
, ec
);
371 boost::asio::detail::throw_error(ec
);
374 /// Close the acceptor.
376 * This function is used to close the acceptor. Any asynchronous accept
377 * operations will be cancelled immediately.
379 * A subsequent call to open() is required before the acceptor can again be
380 * used to again perform socket accept operations.
382 * @param ec Set to indicate what error occurred, if any.
386 * boost::asio::ip::tcp::acceptor acceptor(io_service);
388 * boost::system::error_code ec;
389 * acceptor.close(ec);
392 * // An error occurred.
396 boost::system::error_code
close(boost::system::error_code
& ec
)
398 return this->service
.close(this->implementation
, ec
);
401 /// Get the native acceptor representation.
403 * This function may be used to obtain the underlying representation of the
404 * acceptor. This is intended to allow access to native acceptor functionality
405 * that is not otherwise provided.
409 return this->service
.native(this->implementation
);
412 /// Cancel all asynchronous operations associated with the acceptor.
414 * This function causes all outstanding asynchronous connect, send and receive
415 * operations to finish immediately, and the handlers for cancelled operations
416 * will be passed the boost::asio::error::operation_aborted error.
418 * @throws boost::system::system_error Thrown on failure.
422 boost::system::error_code ec
;
423 this->service
.cancel(this->implementation
, ec
);
424 boost::asio::detail::throw_error(ec
);
427 /// Cancel all asynchronous operations associated with the acceptor.
429 * This function causes all outstanding asynchronous connect, send and receive
430 * operations to finish immediately, and the handlers for cancelled operations
431 * will be passed the boost::asio::error::operation_aborted error.
433 * @param ec Set to indicate what error occurred, if any.
435 boost::system::error_code
cancel(boost::system::error_code
& ec
)
437 return this->service
.cancel(this->implementation
, ec
);
440 /// Set an option on the acceptor.
442 * This function is used to set an option on the acceptor.
444 * @param option The new option value to be set on the acceptor.
446 * @throws boost::system::system_error Thrown on failure.
448 * @sa SettableSocketOption @n
449 * boost::asio::socket_base::reuse_address
450 * boost::asio::socket_base::enable_connection_aborted
453 * Setting the SOL_SOCKET/SO_REUSEADDR option:
455 * boost::asio::ip::tcp::acceptor acceptor(io_service);
457 * boost::asio::ip::tcp::acceptor::reuse_address option(true);
458 * acceptor.set_option(option);
461 template <typename SettableSocketOption
>
462 void set_option(const SettableSocketOption
& option
)
464 boost::system::error_code ec
;
465 this->service
.set_option(this->implementation
, option
, ec
);
466 boost::asio::detail::throw_error(ec
);
469 /// Set an option on the acceptor.
471 * This function is used to set an option on the acceptor.
473 * @param option The new option value to be set on the acceptor.
475 * @param ec Set to indicate what error occurred, if any.
477 * @sa SettableSocketOption @n
478 * boost::asio::socket_base::reuse_address
479 * boost::asio::socket_base::enable_connection_aborted
482 * Setting the SOL_SOCKET/SO_REUSEADDR option:
484 * boost::asio::ip::tcp::acceptor acceptor(io_service);
486 * boost::asio::ip::tcp::acceptor::reuse_address option(true);
487 * boost::system::error_code ec;
488 * acceptor.set_option(option, ec);
491 * // An error occurred.
495 template <typename SettableSocketOption
>
496 boost::system::error_code
set_option(const SettableSocketOption
& option
,
497 boost::system::error_code
& ec
)
499 return this->service
.set_option(this->implementation
, option
, ec
);
502 /// Get an option from the acceptor.
504 * This function is used to get the current value of an option on the
507 * @param option The option value to be obtained from the acceptor.
509 * @throws boost::system::system_error Thrown on failure.
511 * @sa GettableSocketOption @n
512 * boost::asio::socket_base::reuse_address
515 * Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
517 * boost::asio::ip::tcp::acceptor acceptor(io_service);
519 * boost::asio::ip::tcp::acceptor::reuse_address option;
520 * acceptor.get_option(option);
521 * bool is_set = option.get();
524 template <typename GettableSocketOption
>
525 void get_option(GettableSocketOption
& option
)
527 boost::system::error_code ec
;
528 this->service
.get_option(this->implementation
, option
, ec
);
529 boost::asio::detail::throw_error(ec
);
532 /// Get an option from the acceptor.
534 * This function is used to get the current value of an option on the
537 * @param option The option value to be obtained from the acceptor.
539 * @param ec Set to indicate what error occurred, if any.
541 * @sa GettableSocketOption @n
542 * boost::asio::socket_base::reuse_address
545 * Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
547 * boost::asio::ip::tcp::acceptor acceptor(io_service);
549 * boost::asio::ip::tcp::acceptor::reuse_address option;
550 * boost::system::error_code ec;
551 * acceptor.get_option(option, ec);
554 * // An error occurred.
556 * bool is_set = option.get();
559 template <typename GettableSocketOption
>
560 boost::system::error_code
get_option(GettableSocketOption
& option
,
561 boost::system::error_code
& ec
)
563 return this->service
.get_option(this->implementation
, option
, ec
);
566 /// Get the local endpoint of the acceptor.
568 * This function is used to obtain the locally bound endpoint of the acceptor.
570 * @returns An object that represents the local endpoint of the acceptor.
572 * @throws boost::system::system_error Thrown on failure.
576 * boost::asio::ip::tcp::acceptor acceptor(io_service);
578 * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint();
581 endpoint_type
local_endpoint() const
583 boost::system::error_code ec
;
584 endpoint_type ep
= this->service
.local_endpoint(this->implementation
, ec
);
585 boost::asio::detail::throw_error(ec
);
589 /// Get the local endpoint of the acceptor.
591 * This function is used to obtain the locally bound endpoint of the acceptor.
593 * @param ec Set to indicate what error occurred, if any.
595 * @returns An object that represents the local endpoint of the acceptor.
596 * Returns a default-constructed endpoint object if an error occurred and the
597 * error handler did not throw an exception.
601 * boost::asio::ip::tcp::acceptor acceptor(io_service);
603 * boost::system::error_code ec;
604 * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec);
607 * // An error occurred.
611 endpoint_type
local_endpoint(boost::system::error_code
& ec
) const
613 return this->service
.local_endpoint(this->implementation
, ec
);
616 /// Accept a new connection.
618 * This function is used to accept a new connection from a peer into the
619 * given socket. The function call will block until a new connection has been
620 * accepted successfully or an error occurs.
622 * @param peer The socket into which the new connection will be accepted.
624 * @throws boost::system::system_error Thrown on failure.
628 * boost::asio::ip::tcp::acceptor acceptor(io_service);
630 * boost::asio::ip::tcp::socket socket(io_service);
631 * acceptor.accept(socket);
634 template <typename SocketService
>
635 void accept(basic_socket
<protocol_type
, SocketService
>& peer
)
637 boost::system::error_code ec
;
638 this->service
.accept(this->implementation
, peer
, 0, ec
);
639 boost::asio::detail::throw_error(ec
);
642 /// Accept a new connection.
644 * This function is used to accept a new connection from a peer into the
645 * given socket. The function call will block until a new connection has been
646 * accepted successfully or an error occurs.
648 * @param peer The socket into which the new connection will be accepted.
650 * @param ec Set to indicate what error occurred, if any.
654 * boost::asio::ip::tcp::acceptor acceptor(io_service);
656 * boost::asio::ip::tcp::soocket socket(io_service);
657 * boost::system::error_code ec;
658 * acceptor.accept(socket, ec);
661 * // An error occurred.
665 template <typename SocketService
>
666 boost::system::error_code
accept(
667 basic_socket
<protocol_type
, SocketService
>& peer
,
668 boost::system::error_code
& ec
)
670 return this->service
.accept(this->implementation
, peer
, 0, ec
);
673 /// Start an asynchronous accept.
675 * This function is used to asynchronously accept a new connection into a
676 * socket. The function call always returns immediately.
678 * @param peer The socket into which the new connection will be accepted.
679 * Ownership of the peer object is retained by the caller, which must
680 * guarantee that it is valid until the handler is called.
682 * @param handler The handler to be called when the accept operation
683 * completes. Copies will be made of the handler as required. The function
684 * signature of the handler must be:
685 * @code void handler(
686 * const boost::system::error_code& error // Result of operation.
688 * Regardless of whether the asynchronous operation completes immediately or
689 * not, the handler will not be invoked from within this function. Invocation
690 * of the handler will be performed in a manner equivalent to using
691 * boost::asio::io_service::post().
695 * void accept_handler(const boost::system::error_code& error)
699 * // Accept succeeded.
705 * boost::asio::ip::tcp::acceptor acceptor(io_service);
707 * boost::asio::ip::tcp::socket socket(io_service);
708 * acceptor.async_accept(socket, accept_handler);
711 template <typename SocketService
, typename AcceptHandler
>
712 void async_accept(basic_socket
<protocol_type
, SocketService
>& peer
,
713 AcceptHandler handler
)
715 this->service
.async_accept(this->implementation
, peer
, 0, handler
);
718 /// Accept a new connection and obtain the endpoint of the peer
720 * This function is used to accept a new connection from a peer into the
721 * given socket, and additionally provide the endpoint of the remote peer.
722 * The function call will block until a new connection has been accepted
723 * successfully or an error occurs.
725 * @param peer The socket into which the new connection will be accepted.
727 * @param peer_endpoint An endpoint object which will receive the endpoint of
730 * @throws boost::system::system_error Thrown on failure.
734 * boost::asio::ip::tcp::acceptor acceptor(io_service);
736 * boost::asio::ip::tcp::socket socket(io_service);
737 * boost::asio::ip::tcp::endpoint endpoint;
738 * acceptor.accept(socket, endpoint);
741 template <typename SocketService
>
742 void accept(basic_socket
<protocol_type
, SocketService
>& peer
,
743 endpoint_type
& peer_endpoint
)
745 boost::system::error_code ec
;
746 this->service
.accept(this->implementation
, peer
, &peer_endpoint
, ec
);
747 boost::asio::detail::throw_error(ec
);
750 /// Accept a new connection and obtain the endpoint of the peer
752 * This function is used to accept a new connection from a peer into the
753 * given socket, and additionally provide the endpoint of the remote peer.
754 * The function call will block until a new connection has been accepted
755 * successfully or an error occurs.
757 * @param peer The socket into which the new connection will be accepted.
759 * @param peer_endpoint An endpoint object which will receive the endpoint of
762 * @param ec Set to indicate what error occurred, if any.
766 * boost::asio::ip::tcp::acceptor acceptor(io_service);
768 * boost::asio::ip::tcp::socket socket(io_service);
769 * boost::asio::ip::tcp::endpoint endpoint;
770 * boost::system::error_code ec;
771 * acceptor.accept(socket, endpoint, ec);
774 * // An error occurred.
778 template <typename SocketService
>
779 boost::system::error_code
accept(
780 basic_socket
<protocol_type
, SocketService
>& peer
,
781 endpoint_type
& peer_endpoint
, boost::system::error_code
& ec
)
783 return this->service
.accept(this->implementation
, peer
, &peer_endpoint
, ec
);
786 /// Start an asynchronous accept.
788 * This function is used to asynchronously accept a new connection into a
789 * socket, and additionally obtain the endpoint of the remote peer. The
790 * function call always returns immediately.
792 * @param peer The socket into which the new connection will be accepted.
793 * Ownership of the peer object is retained by the caller, which must
794 * guarantee that it is valid until the handler is called.
796 * @param peer_endpoint An endpoint object into which the endpoint of the
797 * remote peer will be written. Ownership of the peer_endpoint object is
798 * retained by the caller, which must guarantee that it is valid until the
801 * @param handler The handler to be called when the accept operation
802 * completes. Copies will be made of the handler as required. The function
803 * signature of the handler must be:
804 * @code void handler(
805 * const boost::system::error_code& error // Result of operation.
807 * Regardless of whether the asynchronous operation completes immediately or
808 * not, the handler will not be invoked from within this function. Invocation
809 * of the handler will be performed in a manner equivalent to using
810 * boost::asio::io_service::post().
812 template <typename SocketService
, typename AcceptHandler
>
813 void async_accept(basic_socket
<protocol_type
, SocketService
>& peer
,
814 endpoint_type
& peer_endpoint
, AcceptHandler handler
)
816 this->service
.async_accept(this->implementation
,
817 peer
, &peer_endpoint
, handler
);
824 #include <boost/asio/detail/pop_options.hpp>
826 #endif // BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_HPP