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 | |
30 | namespace boost { |
31 | namespace 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 | */ |
53 | template <typename Protocol, |
54 | typename SocketAcceptorService = socket_acceptor_service<Protocol> > |
55 | class basic_socket_acceptor |
56 | : public basic_io_object<SocketAcceptorService>, |
57 | public socket_base |
58 | { |
59 | public: |
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(err: ec, location: "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(err: ec, location: "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(err: ec, location: "set_option" ); |
149 | } |
150 | this->get_service().bind(this->get_implementation(), endpoint, ec); |
151 | boost::asio::detail::throw_error(err: ec, location: "bind" ); |
152 | this->get_service().listen(this->get_implementation(), |
153 | socket_base::max_connections, ec); |
154 | boost::asio::detail::throw_error(err: ec, location: "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(err: ec, location: "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(err: ec, location: "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(err: ec, location: "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(err: ec, location: "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(err: ec, location: "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(err: ec, location: "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(err: ec, location: "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(err: ec, location: "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(err: ec, location: "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(err: ec, location: "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(err: ec, location: "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(err: ec, location: "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(err: ec, location: "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(err: ec, location: "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(err: ec, location: "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 | |