1//
2// connect.hpp
3// ~~~~~~~~~~~
4//
5// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6//
7// Distributed under the Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9//
10
11#ifndef ASIO_CONNECT_HPP
12#define ASIO_CONNECT_HPP
13
14
15#include "asio/detail/config.hpp"
16#include "asio/async_result.hpp"
17#include "asio/basic_socket.hpp"
18#include "asio/error.hpp"
19
20#include "asio/detail/push_options.hpp"
21
22namespace asio {
23
24/**
25 * @defgroup connect asio::connect
26 *
27 * @brief Establishes a socket connection by trying each endpoint in a sequence.
28 */
29/*@{*/
30
31/// Establishes a socket connection by trying each endpoint in a sequence.
32/**
33 * This function attempts to connect a socket to one of a sequence of
34 * endpoints. It does this by repeated calls to the socket's @c connect member
35 * function, once for each endpoint in the sequence, until a connection is
36 * successfully established.
37 *
38 * @param s The socket to be connected. If the socket is already open, it will
39 * be closed.
40 *
41 * @param begin An iterator pointing to the start of a sequence of endpoints.
42 *
43 * @returns On success, an iterator denoting the successfully connected
44 * endpoint. Otherwise, the end iterator.
45 *
46 * @throws asio::system_error Thrown on failure. If the sequence is
47 * empty, the associated @c error_code is asio::error::not_found.
48 * Otherwise, contains the error from the last connection attempt.
49 *
50 * @note This overload assumes that a default constructed object of type @c
51 * Iterator represents the end of the sequence. This is a valid assumption for
52 * iterator types such as @c asio::ip::tcp::resolver::iterator.
53 *
54 * @par Example
55 * @code tcp::resolver r(io_service);
56 * tcp::resolver::query q("host", "service");
57 * tcp::socket s(io_service);
58 * asio::connect(s, r.resolve(q)); @endcode
59 */
60template <typename Protocol, typename SocketService, typename Iterator>
61Iterator connect(basic_socket<Protocol, SocketService>& s, Iterator begin);
62
63/// Establishes a socket connection by trying each endpoint in a sequence.
64/**
65 * This function attempts to connect a socket to one of a sequence of
66 * endpoints. It does this by repeated calls to the socket's @c connect member
67 * function, once for each endpoint in the sequence, until a connection is
68 * successfully established.
69 *
70 * @param s The socket to be connected. If the socket is already open, it will
71 * be closed.
72 *
73 * @param begin An iterator pointing to the start of a sequence of endpoints.
74 *
75 * @param ec Set to indicate what error occurred, if any. If the sequence is
76 * empty, set to asio::error::not_found. Otherwise, contains the error
77 * from the last connection attempt.
78 *
79 * @returns On success, an iterator denoting the successfully connected
80 * endpoint. Otherwise, the end iterator.
81 *
82 * @note This overload assumes that a default constructed object of type @c
83 * Iterator represents the end of the sequence. This is a valid assumption for
84 * iterator types such as @c asio::ip::tcp::resolver::iterator.
85 *
86 * @par Example
87 * @code tcp::resolver r(io_service);
88 * tcp::resolver::query q("host", "service");
89 * tcp::socket s(io_service);
90 * asio::error_code ec;
91 * asio::connect(s, r.resolve(q), ec);
92 * if (ec)
93 * {
94 *   // An error occurred.
95 * } @endcode
96 */
97template <typename Protocol, typename SocketService, typename Iterator>
98Iterator connect(basic_socket<Protocol, SocketService>& s,
99    Iterator begin, asio::error_code& ec);
100
101/// Establishes a socket connection by trying each endpoint in a sequence.
102/**
103 * This function attempts to connect a socket to one of a sequence of
104 * endpoints. It does this by repeated calls to the socket's @c connect member
105 * function, once for each endpoint in the sequence, until a connection is
106 * successfully established.
107 *
108 * @param s The socket to be connected. If the socket is already open, it will
109 * be closed.
110 *
111 * @param begin An iterator pointing to the start of a sequence of endpoints.
112 *
113 * @param end An iterator pointing to the end of a sequence of endpoints.
114 *
115 * @returns On success, an iterator denoting the successfully connected
116 * endpoint. Otherwise, the end iterator.
117 *
118 * @throws asio::system_error Thrown on failure. If the sequence is
119 * empty, the associated @c error_code is asio::error::not_found.
120 * Otherwise, contains the error from the last connection attempt.
121 *
122 * @par Example
123 * @code tcp::resolver r(io_service);
124 * tcp::resolver::query q("host", "service");
125 * tcp::resolver::iterator i = r.resolve(q), end;
126 * tcp::socket s(io_service);
127 * asio::connect(s, i, end); @endcode
128 */
129template <typename Protocol, typename SocketService, typename Iterator>
130Iterator connect(basic_socket<Protocol, SocketService>& s,
131    Iterator begin, Iterator end);
132
133/// Establishes a socket connection by trying each endpoint in a sequence.
134/**
135 * This function attempts to connect a socket to one of a sequence of
136 * endpoints. It does this by repeated calls to the socket's @c connect member
137 * function, once for each endpoint in the sequence, until a connection is
138 * successfully established.
139 *
140 * @param s The socket to be connected. If the socket is already open, it will
141 * be closed.
142 *
143 * @param begin An iterator pointing to the start of a sequence of endpoints.
144 *
145 * @param end An iterator pointing to the end of a sequence of endpoints.
146 *
147 * @param ec Set to indicate what error occurred, if any. If the sequence is
148 * empty, set to asio::error::not_found. Otherwise, contains the error
149 * from the last connection attempt.
150 *
151 * @returns On success, an iterator denoting the successfully connected
152 * endpoint. Otherwise, the end iterator.
153 *
154 * @par Example
155 * @code tcp::resolver r(io_service);
156 * tcp::resolver::query q("host", "service");
157 * tcp::resolver::iterator i = r.resolve(q), end;
158 * tcp::socket s(io_service);
159 * asio::error_code ec;
160 * asio::connect(s, i, end, ec);
161 * if (ec)
162 * {
163 *   // An error occurred.
164 * } @endcode
165 */
166template <typename Protocol, typename SocketService, typename Iterator>
167Iterator connect(basic_socket<Protocol, SocketService>& s,
168    Iterator begin, Iterator end, asio::error_code& ec);
169
170/// Establishes a socket connection by trying each endpoint in a sequence.
171/**
172 * This function attempts to connect a socket to one of a sequence of
173 * endpoints. It does this by repeated calls to the socket's @c connect member
174 * function, once for each endpoint in the sequence, until a connection is
175 * successfully established.
176 *
177 * @param s The socket to be connected. If the socket is already open, it will
178 * be closed.
179 *
180 * @param begin An iterator pointing to the start of a sequence of endpoints.
181 *
182 * @param connect_condition A function object that is called prior to each
183 * connection attempt. The signature of the function object must be:
184 * @code Iterator connect_condition(
185 *     const asio::error_code& ec,
186 *     Iterator next); @endcode
187 * The @c ec parameter contains the result from the most recent connect
188 * operation. Before the first connection attempt, @c ec is always set to
189 * indicate success. The @c next parameter is an iterator pointing to the next
190 * endpoint to be tried. The function object should return the next iterator,
191 * but is permitted to return a different iterator so that endpoints may be
192 * skipped. The implementation guarantees that the function object will never
193 * be called with the end iterator.
194 *
195 * @returns On success, an iterator denoting the successfully connected
196 * endpoint. Otherwise, the end iterator.
197 *
198 * @throws asio::system_error Thrown on failure. If the sequence is
199 * empty, the associated @c error_code is asio::error::not_found.
200 * Otherwise, contains the error from the last connection attempt.
201 *
202 * @note This overload assumes that a default constructed object of type @c
203 * Iterator represents the end of the sequence. This is a valid assumption for
204 * iterator types such as @c asio::ip::tcp::resolver::iterator.
205 *
206 * @par Example
207 * The following connect condition function object can be used to output
208 * information about the individual connection attempts:
209 * @code struct my_connect_condition
210 * {
211 *   template <typename Iterator>
212 *   Iterator operator()(
213 *       const asio::error_code& ec,
214 *       Iterator next)
215 *   {
216 *     if (ec) std::cout << "Error: " << ec.message() << std::endl;
217 *     std::cout << "Trying: " << next->endpoint() << std::endl;
218 *     return next;
219 *   }
220 * }; @endcode
221 * It would be used with the asio::connect function as follows:
222 * @code tcp::resolver r(io_service);
223 * tcp::resolver::query q("host", "service");
224 * tcp::socket s(io_service);
225 * tcp::resolver::iterator i = asio::connect(
226 *     s, r.resolve(q), my_connect_condition());
227 * std::cout << "Connected to: " << i->endpoint() << std::endl; @endcode
228 */
229template <typename Protocol, typename SocketService,
230    typename Iterator, typename ConnectCondition>
231Iterator connect(basic_socket<Protocol, SocketService>& s,
232    Iterator begin, ConnectCondition connect_condition);
233
234/// Establishes a socket connection by trying each endpoint in a sequence.
235/**
236 * This function attempts to connect a socket to one of a sequence of
237 * endpoints. It does this by repeated calls to the socket's @c connect member
238 * function, once for each endpoint in the sequence, until a connection is
239 * successfully established.
240 *
241 * @param s The socket to be connected. If the socket is already open, it will
242 * be closed.
243 *
244 * @param begin An iterator pointing to the start of a sequence of endpoints.
245 *
246 * @param connect_condition A function object that is called prior to each
247 * connection attempt. The signature of the function object must be:
248 * @code Iterator connect_condition(
249 *     const asio::error_code& ec,
250 *     Iterator next); @endcode
251 * The @c ec parameter contains the result from the most recent connect
252 * operation. Before the first connection attempt, @c ec is always set to
253 * indicate success. The @c next parameter is an iterator pointing to the next
254 * endpoint to be tried. The function object should return the next iterator,
255 * but is permitted to return a different iterator so that endpoints may be
256 * skipped. The implementation guarantees that the function object will never
257 * be called with the end iterator.
258 *
259 * @param ec Set to indicate what error occurred, if any. If the sequence is
260 * empty, set to asio::error::not_found. Otherwise, contains the error
261 * from the last connection attempt.
262 *
263 * @returns On success, an iterator denoting the successfully connected
264 * endpoint. Otherwise, the end iterator.
265 *
266 * @note This overload assumes that a default constructed object of type @c
267 * Iterator represents the end of the sequence. This is a valid assumption for
268 * iterator types such as @c asio::ip::tcp::resolver::iterator.
269 *
270 * @par Example
271 * The following connect condition function object can be used to output
272 * information about the individual connection attempts:
273 * @code struct my_connect_condition
274 * {
275 *   template <typename Iterator>
276 *   Iterator operator()(
277 *       const asio::error_code& ec,
278 *       Iterator next)
279 *   {
280 *     if (ec) std::cout << "Error: " << ec.message() << std::endl;
281 *     std::cout << "Trying: " << next->endpoint() << std::endl;
282 *     return next;
283 *   }
284 * }; @endcode
285 * It would be used with the asio::connect function as follows:
286 * @code tcp::resolver r(io_service);
287 * tcp::resolver::query q("host", "service");
288 * tcp::socket s(io_service);
289 * asio::error_code ec;
290 * tcp::resolver::iterator i = asio::connect(
291 *     s, r.resolve(q), my_connect_condition(), ec);
292 * if (ec)
293 * {
294 *   // An error occurred.
295 * }
296 * else
297 * {
298 *   std::cout << "Connected to: " << i->endpoint() << std::endl;
299 * } @endcode
300 */
301template <typename Protocol, typename SocketService,
302    typename Iterator, typename ConnectCondition>
303Iterator connect(basic_socket<Protocol, SocketService>& s, Iterator begin,
304    ConnectCondition connect_condition, asio::error_code& ec);
305
306/// Establishes a socket connection by trying each endpoint in a sequence.
307/**
308 * This function attempts to connect a socket to one of a sequence of
309 * endpoints. It does this by repeated calls to the socket's @c connect member
310 * function, once for each endpoint in the sequence, until a connection is
311 * successfully established.
312 *
313 * @param s The socket to be connected. If the socket is already open, it will
314 * be closed.
315 *
316 * @param begin An iterator pointing to the start of a sequence of endpoints.
317 *
318 * @param end An iterator pointing to the end of a sequence of endpoints.
319 *
320 * @param connect_condition A function object that is called prior to each
321 * connection attempt. The signature of the function object must be:
322 * @code Iterator connect_condition(
323 *     const asio::error_code& ec,
324 *     Iterator next); @endcode
325 * The @c ec parameter contains the result from the most recent connect
326 * operation. Before the first connection attempt, @c ec is always set to
327 * indicate success. The @c next parameter is an iterator pointing to the next
328 * endpoint to be tried. The function object should return the next iterator,
329 * but is permitted to return a different iterator so that endpoints may be
330 * skipped. The implementation guarantees that the function object will never
331 * be called with the end iterator.
332 *
333 * @returns On success, an iterator denoting the successfully connected
334 * endpoint. Otherwise, the end iterator.
335 *
336 * @throws asio::system_error Thrown on failure. If the sequence is
337 * empty, the associated @c error_code is asio::error::not_found.
338 * Otherwise, contains the error from the last connection attempt.
339 *
340 * @par Example
341 * The following connect condition function object can be used to output
342 * information about the individual connection attempts:
343 * @code struct my_connect_condition
344 * {
345 *   template <typename Iterator>
346 *   Iterator operator()(
347 *       const asio::error_code& ec,
348 *       Iterator next)
349 *   {
350 *     if (ec) std::cout << "Error: " << ec.message() << std::endl;
351 *     std::cout << "Trying: " << next->endpoint() << std::endl;
352 *     return next;
353 *   }
354 * }; @endcode
355 * It would be used with the asio::connect function as follows:
356 * @code tcp::resolver r(io_service);
357 * tcp::resolver::query q("host", "service");
358 * tcp::resolver::iterator i = r.resolve(q), end;
359 * tcp::socket s(io_service);
360 * i = asio::connect(s, i, end, my_connect_condition());
361 * std::cout << "Connected to: " << i->endpoint() << std::endl; @endcode
362 */
363template <typename Protocol, typename SocketService,
364    typename Iterator, typename ConnectCondition>
365Iterator connect(basic_socket<Protocol, SocketService>& s, Iterator begin,
366    Iterator end, ConnectCondition connect_condition);
367
368/// Establishes a socket connection by trying each endpoint in a sequence.
369/**
370 * This function attempts to connect a socket to one of a sequence of
371 * endpoints. It does this by repeated calls to the socket's @c connect member
372 * function, once for each endpoint in the sequence, until a connection is
373 * successfully established.
374 *
375 * @param s The socket to be connected. If the socket is already open, it will
376 * be closed.
377 *
378 * @param begin An iterator pointing to the start of a sequence of endpoints.
379 *
380 * @param end An iterator pointing to the end of a sequence of endpoints.
381 *
382 * @param connect_condition A function object that is called prior to each
383 * connection attempt. The signature of the function object must be:
384 * @code Iterator connect_condition(
385 *     const asio::error_code& ec,
386 *     Iterator next); @endcode
387 * The @c ec parameter contains the result from the most recent connect
388 * operation. Before the first connection attempt, @c ec is always set to
389 * indicate success. The @c next parameter is an iterator pointing to the next
390 * endpoint to be tried. The function object should return the next iterator,
391 * but is permitted to return a different iterator so that endpoints may be
392 * skipped. The implementation guarantees that the function object will never
393 * be called with the end iterator.
394 *
395 * @param ec Set to indicate what error occurred, if any. If the sequence is
396 * empty, set to asio::error::not_found. Otherwise, contains the error
397 * from the last connection attempt.
398 *
399 * @returns On success, an iterator denoting the successfully connected
400 * endpoint. Otherwise, the end iterator.
401 *
402 * @par Example
403 * The following connect condition function object can be used to output
404 * information about the individual connection attempts:
405 * @code struct my_connect_condition
406 * {
407 *   template <typename Iterator>
408 *   Iterator operator()(
409 *       const asio::error_code& ec,
410 *       Iterator next)
411 *   {
412 *     if (ec) std::cout << "Error: " << ec.message() << std::endl;
413 *     std::cout << "Trying: " << next->endpoint() << std::endl;
414 *     return next;
415 *   }
416 * }; @endcode
417 * It would be used with the asio::connect function as follows:
418 * @code tcp::resolver r(io_service);
419 * tcp::resolver::query q("host", "service");
420 * tcp::resolver::iterator i = r.resolve(q), end;
421 * tcp::socket s(io_service);
422 * asio::error_code ec;
423 * i = asio::connect(s, i, end, my_connect_condition(), ec);
424 * if (ec)
425 * {
426 *   // An error occurred.
427 * }
428 * else
429 * {
430 *   std::cout << "Connected to: " << i->endpoint() << std::endl;
431 * } @endcode
432 */
433template <typename Protocol, typename SocketService,
434    typename Iterator, typename ConnectCondition>
435Iterator connect(basic_socket<Protocol, SocketService>& s,
436    Iterator begin, Iterator end, ConnectCondition connect_condition,
437    asio::error_code& ec);
438
439/*@}*/
440
441/**
442 * @defgroup async_connect asio::async_connect
443 *
444 * @brief Asynchronously establishes a socket connection by trying each
445 * endpoint in a sequence.
446 */
447/*@{*/
448
449/// Asynchronously establishes a socket connection by trying each endpoint in a
450/// sequence.
451/**
452 * This function attempts to connect a socket to one of a sequence of
453 * endpoints. It does this by repeated calls to the socket's @c async_connect
454 * member function, once for each endpoint in the sequence, until a connection
455 * is successfully established.
456 *
457 * @param s The socket to be connected. If the socket is already open, it will
458 * be closed.
459 *
460 * @param begin An iterator pointing to the start of a sequence of endpoints.
461 *
462 * @param handler The handler to be called when the connect operation
463 * completes. Copies will be made of the handler as required. The function
464 * signature of the handler must be:
465 * @code void handler(
466 *   // Result of operation. if the sequence is empty, set to
467 *   // asio::error::not_found. Otherwise, contains the
468 *   // error from the last connection attempt.
469 *   const asio::error_code& error,
470 *
471 *   // On success, an iterator denoting the successfully
472 *   // connected endpoint. Otherwise, the end iterator.
473 *   Iterator iterator
474 * ); @endcode
475 * Regardless of whether the asynchronous operation completes immediately or
476 * not, the handler will not be invoked from within this function. Invocation
477 * of the handler will be performed in a manner equivalent to using
478 * asio::io_service::post().
479 *
480 * @note This overload assumes that a default constructed object of type @c
481 * Iterator represents the end of the sequence. This is a valid assumption for
482 * iterator types such as @c asio::ip::tcp::resolver::iterator.
483 *
484 * @par Example
485 * @code tcp::resolver r(io_service);
486 * tcp::resolver::query q("host", "service");
487 * tcp::socket s(io_service);
488 *
489 * // ...
490 *
491 * r.async_resolve(q, resolve_handler);
492 *
493 * // ...
494 *
495 * void resolve_handler(
496 *     const asio::error_code& ec,
497 *     tcp::resolver::iterator i)
498 * {
499 *   if (!ec)
500 *   {
501 *     asio::async_connect(s, i, connect_handler);
502 *   }
503 * }
504 *
505 * // ...
506 *
507 * void connect_handler(
508 *     const asio::error_code& ec,
509 *     tcp::resolver::iterator i)
510 * {
511 *   // ...
512 * } @endcode
513 */
514template <typename Protocol, typename SocketService,
515    typename Iterator, typename ComposedConnectHandler>
516ASIO_INITFN_RESULT_TYPE(ComposedConnectHandler,
517    void (asio::error_code, Iterator))
518async_connect(basic_socket<Protocol, SocketService>& s,
519    Iterator begin, ASIO_MOVE_ARG(ComposedConnectHandler) handler);
520
521/// Asynchronously establishes a socket connection by trying each endpoint in a
522/// sequence.
523/**
524 * This function attempts to connect a socket to one of a sequence of
525 * endpoints. It does this by repeated calls to the socket's @c async_connect
526 * member function, once for each endpoint in the sequence, until a connection
527 * is successfully established.
528 *
529 * @param s The socket to be connected. If the socket is already open, it will
530 * be closed.
531 *
532 * @param begin An iterator pointing to the start of a sequence of endpoints.
533 *
534 * @param end An iterator pointing to the end of a sequence of endpoints.
535 *
536 * @param handler The handler to be called when the connect operation
537 * completes. Copies will be made of the handler as required. The function
538 * signature of the handler must be:
539 * @code void handler(
540 *   // Result of operation. if the sequence is empty, set to
541 *   // asio::error::not_found. Otherwise, contains the
542 *   // error from the last connection attempt.
543 *   const asio::error_code& error,
544 *
545 *   // On success, an iterator denoting the successfully
546 *   // connected endpoint. Otherwise, the end iterator.
547 *   Iterator iterator
548 * ); @endcode
549 * Regardless of whether the asynchronous operation completes immediately or
550 * not, the handler will not be invoked from within this function. Invocation
551 * of the handler will be performed in a manner equivalent to using
552 * asio::io_service::post().
553 *
554 * @par Example
555 * @code tcp::resolver r(io_service);
556 * tcp::resolver::query q("host", "service");
557 * tcp::socket s(io_service);
558 *
559 * // ...
560 *
561 * r.async_resolve(q, resolve_handler);
562 *
563 * // ...
564 *
565 * void resolve_handler(
566 *     const asio::error_code& ec,
567 *     tcp::resolver::iterator i)
568 * {
569 *   if (!ec)
570 *   {
571 *     tcp::resolver::iterator end;
572 *     asio::async_connect(s, i, end, connect_handler);
573 *   }
574 * }
575 *
576 * // ...
577 *
578 * void connect_handler(
579 *     const asio::error_code& ec,
580 *     tcp::resolver::iterator i)
581 * {
582 *   // ...
583 * } @endcode
584 */
585template <typename Protocol, typename SocketService,
586    typename Iterator, typename ComposedConnectHandler>
587ASIO_INITFN_RESULT_TYPE(ComposedConnectHandler,
588    void (asio::error_code, Iterator))
589async_connect(basic_socket<Protocol, SocketService>& s,
590    Iterator begin, Iterator end,
591    ASIO_MOVE_ARG(ComposedConnectHandler) handler);
592
593/// Asynchronously establishes a socket connection by trying each endpoint in a
594/// sequence.
595/**
596 * This function attempts to connect a socket to one of a sequence of
597 * endpoints. It does this by repeated calls to the socket's @c async_connect
598 * member function, once for each endpoint in the sequence, until a connection
599 * is successfully established.
600 *
601 * @param s The socket to be connected. If the socket is already open, it will
602 * be closed.
603 *
604 * @param begin An iterator pointing to the start of a sequence of endpoints.
605 *
606 * @param connect_condition A function object that is called prior to each
607 * connection attempt. The signature of the function object must be:
608 * @code Iterator connect_condition(
609 *     const asio::error_code& ec,
610 *     Iterator next); @endcode
611 * The @c ec parameter contains the result from the most recent connect
612 * operation. Before the first connection attempt, @c ec is always set to
613 * indicate success. The @c next parameter is an iterator pointing to the next
614 * endpoint to be tried. The function object should return the next iterator,
615 * but is permitted to return a different iterator so that endpoints may be
616 * skipped. The implementation guarantees that the function object will never
617 * be called with the end iterator.
618 *
619 * @param handler The handler to be called when the connect operation
620 * completes. Copies will be made of the handler as required. The function
621 * signature of the handler must be:
622 * @code void handler(
623 *   // Result of operation. if the sequence is empty, set to
624 *   // asio::error::not_found. Otherwise, contains the
625 *   // error from the last connection attempt.
626 *   const asio::error_code& error,
627 *
628 *   // On success, an iterator denoting the successfully
629 *   // connected endpoint. Otherwise, the end iterator.
630 *   Iterator iterator
631 * ); @endcode
632 * Regardless of whether the asynchronous operation completes immediately or
633 * not, the handler will not be invoked from within this function. Invocation
634 * of the handler will be performed in a manner equivalent to using
635 * asio::io_service::post().
636 *
637 * @note This overload assumes that a default constructed object of type @c
638 * Iterator represents the end of the sequence. This is a valid assumption for
639 * iterator types such as @c asio::ip::tcp::resolver::iterator.
640 *
641 * @par Example
642 * The following connect condition function object can be used to output
643 * information about the individual connection attempts:
644 * @code struct my_connect_condition
645 * {
646 *   template <typename Iterator>
647 *   Iterator operator()(
648 *       const asio::error_code& ec,
649 *       Iterator next)
650 *   {
651 *     if (ec) std::cout << "Error: " << ec.message() << std::endl;
652 *     std::cout << "Trying: " << next->endpoint() << std::endl;
653 *     return next;
654 *   }
655 * }; @endcode
656 * It would be used with the asio::connect function as follows:
657 * @code tcp::resolver r(io_service);
658 * tcp::resolver::query q("host", "service");
659 * tcp::socket s(io_service);
660 *
661 * // ...
662 *
663 * r.async_resolve(q, resolve_handler);
664 *
665 * // ...
666 *
667 * void resolve_handler(
668 *     const asio::error_code& ec,
669 *     tcp::resolver::iterator i)
670 * {
671 *   if (!ec)
672 *   {
673 *     asio::async_connect(s, i,
674 *         my_connect_condition(),
675 *         connect_handler);
676 *   }
677 * }
678 *
679 * // ...
680 *
681 * void connect_handler(
682 *     const asio::error_code& ec,
683 *     tcp::resolver::iterator i)
684 * {
685 *   if (ec)
686 *   {
687 *     // An error occurred.
688 *   }
689 *   else
690 *   {
691 *     std::cout << "Connected to: " << i->endpoint() << std::endl;
692 *   }
693 * } @endcode
694 */
695template <typename Protocol, typename SocketService, typename Iterator,
696    typename ConnectCondition, typename ComposedConnectHandler>
697ASIO_INITFN_RESULT_TYPE(ComposedConnectHandler,
698    void (asio::error_code, Iterator))
699async_connect(basic_socket<Protocol, SocketService>& s, Iterator begin,
700    ConnectCondition connect_condition,
701    ASIO_MOVE_ARG(ComposedConnectHandler) handler);
702
703/// Asynchronously establishes a socket connection by trying each endpoint in a
704/// sequence.
705/**
706 * This function attempts to connect a socket to one of a sequence of
707 * endpoints. It does this by repeated calls to the socket's @c async_connect
708 * member function, once for each endpoint in the sequence, until a connection
709 * is successfully established.
710 *
711 * @param s The socket to be connected. If the socket is already open, it will
712 * be closed.
713 *
714 * @param begin An iterator pointing to the start of a sequence of endpoints.
715 *
716 * @param end An iterator pointing to the end of a sequence of endpoints.
717 *
718 * @param connect_condition A function object that is called prior to each
719 * connection attempt. The signature of the function object must be:
720 * @code Iterator connect_condition(
721 *     const asio::error_code& ec,
722 *     Iterator next); @endcode
723 * The @c ec parameter contains the result from the most recent connect
724 * operation. Before the first connection attempt, @c ec is always set to
725 * indicate success. The @c next parameter is an iterator pointing to the next
726 * endpoint to be tried. The function object should return the next iterator,
727 * but is permitted to return a different iterator so that endpoints may be
728 * skipped. The implementation guarantees that the function object will never
729 * be called with the end iterator.
730 *
731 * @param handler The handler to be called when the connect operation
732 * completes. Copies will be made of the handler as required. The function
733 * signature of the handler must be:
734 * @code void handler(
735 *   // Result of operation. if the sequence is empty, set to
736 *   // asio::error::not_found. Otherwise, contains the
737 *   // error from the last connection attempt.
738 *   const asio::error_code& error,
739 *
740 *   // On success, an iterator denoting the successfully
741 *   // connected endpoint. Otherwise, the end iterator.
742 *   Iterator iterator
743 * ); @endcode
744 * Regardless of whether the asynchronous operation completes immediately or
745 * not, the handler will not be invoked from within this function. Invocation
746 * of the handler will be performed in a manner equivalent to using
747 * asio::io_service::post().
748 *
749 * @par Example
750 * The following connect condition function object can be used to output
751 * information about the individual connection attempts:
752 * @code struct my_connect_condition
753 * {
754 *   template <typename Iterator>
755 *   Iterator operator()(
756 *       const asio::error_code& ec,
757 *       Iterator next)
758 *   {
759 *     if (ec) std::cout << "Error: " << ec.message() << std::endl;
760 *     std::cout << "Trying: " << next->endpoint() << std::endl;
761 *     return next;
762 *   }
763 * }; @endcode
764 * It would be used with the asio::connect function as follows:
765 * @code tcp::resolver r(io_service);
766 * tcp::resolver::query q("host", "service");
767 * tcp::socket s(io_service);
768 *
769 * // ...
770 *
771 * r.async_resolve(q, resolve_handler);
772 *
773 * // ...
774 *
775 * void resolve_handler(
776 *     const asio::error_code& ec,
777 *     tcp::resolver::iterator i)
778 * {
779 *   if (!ec)
780 *   {
781 *     tcp::resolver::iterator end;
782 *     asio::async_connect(s, i, end,
783 *         my_connect_condition(),
784 *         connect_handler);
785 *   }
786 * }
787 *
788 * // ...
789 *
790 * void connect_handler(
791 *     const asio::error_code& ec,
792 *     tcp::resolver::iterator i)
793 * {
794 *   if (ec)
795 *   {
796 *     // An error occurred.
797 *   }
798 *   else
799 *   {
800 *     std::cout << "Connected to: " << i->endpoint() << std::endl;
801 *   }
802 * } @endcode
803 */
804template <typename Protocol, typename SocketService, typename Iterator,
805    typename ConnectCondition, typename ComposedConnectHandler>
806ASIO_INITFN_RESULT_TYPE(ComposedConnectHandler,
807    void (asio::error_code, Iterator))
808async_connect(basic_socket<Protocol, SocketService>& s,
809    Iterator begin, Iterator end, ConnectCondition connect_condition,
810    ASIO_MOVE_ARG(ComposedConnectHandler) handler);
811
812/*@}*/
813
814} // namespace asio
815
816#include "asio/detail/pop_options.hpp"
817
818#include "asio/impl/connect.hpp"
819
820#endif
821