connect.hpp 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023
  1. //
  2. // connect.hpp
  3. // ~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2025 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. #ifndef BOOST_ASIO_CONNECT_HPP
  11. #define BOOST_ASIO_CONNECT_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <boost/asio/detail/config.hpp>
  16. #include <boost/asio/async_result.hpp>
  17. #include <boost/asio/basic_socket.hpp>
  18. #include <boost/asio/detail/type_traits.hpp>
  19. #include <boost/asio/error.hpp>
  20. #include <boost/asio/detail/push_options.hpp>
  21. namespace boost {
  22. namespace asio {
  23. namespace detail
  24. {
  25. struct default_connect_condition;
  26. template <typename, typename> class initiate_async_range_connect;
  27. template <typename, typename> class initiate_async_iterator_connect;
  28. template <typename T, typename = void, typename = void>
  29. struct is_endpoint_sequence_helper : false_type
  30. {
  31. };
  32. template <typename T>
  33. struct is_endpoint_sequence_helper<T,
  34. void_t<
  35. decltype(declval<T>().begin())
  36. >,
  37. void_t<
  38. decltype(declval<T>().end())
  39. >
  40. > : true_type
  41. {
  42. };
  43. template <typename T, typename Iterator, typename = void>
  44. struct is_connect_condition_helper : false_type
  45. {
  46. };
  47. template <typename T, typename Iterator>
  48. struct is_connect_condition_helper<T, Iterator,
  49. enable_if_t<
  50. is_same<
  51. result_of_t<T(boost::system::error_code, Iterator)>,
  52. Iterator
  53. >::value
  54. >
  55. > : true_type
  56. {
  57. };
  58. template <typename T, typename Iterator>
  59. struct is_connect_condition_helper<T, Iterator,
  60. enable_if_t<
  61. is_same<
  62. result_of_t<T(boost::system::error_code,
  63. decltype(*declval<Iterator>()))>,
  64. bool
  65. >::value
  66. >
  67. > : true_type
  68. {
  69. };
  70. struct default_connect_condition
  71. {
  72. template <typename Endpoint>
  73. bool operator()(const boost::system::error_code&, const Endpoint&)
  74. {
  75. return true;
  76. }
  77. };
  78. } // namespace detail
  79. #if defined(GENERATING_DOCUMENTATION)
  80. /// Type trait used to determine whether a type is an endpoint sequence that can
  81. /// be used with with @c connect and @c async_connect.
  82. template <typename T>
  83. struct is_endpoint_sequence
  84. {
  85. /// The value member is true if the type may be used as an endpoint sequence.
  86. static const bool value = automatically_determined;
  87. };
  88. /// Trait for determining whether a function object is a connect condition that
  89. /// can be used with @c connect and @c async_connect.
  90. template <typename T, typename Iterator>
  91. struct is_connect_condition
  92. {
  93. /// The value member is true if the type may be used as a connect condition.
  94. static constexpr bool value = automatically_determined;
  95. };
  96. #else // defined(GENERATING_DOCUMENTATION)
  97. template <typename T>
  98. struct is_endpoint_sequence : detail::is_endpoint_sequence_helper<T>
  99. {
  100. };
  101. template <typename T, typename Iterator>
  102. struct is_connect_condition : detail::is_connect_condition_helper<T, Iterator>
  103. {
  104. };
  105. #endif // defined(GENERATING_DOCUMENTATION)
  106. /**
  107. * @defgroup connect boost::asio::connect
  108. *
  109. * @brief The @c connect function is a composed operation that establishes a
  110. * socket connection by trying each endpoint in a sequence.
  111. */
  112. /*@{*/
  113. /// Establishes a socket connection by trying each endpoint in a sequence.
  114. /**
  115. * This function attempts to connect a socket to one of a sequence of
  116. * endpoints. It does this by repeated calls to the socket's @c connect member
  117. * function, once for each endpoint in the sequence, until a connection is
  118. * successfully established.
  119. *
  120. * @param s The socket to be connected. If the socket is already open, it will
  121. * be closed.
  122. *
  123. * @param endpoints A sequence of endpoints.
  124. *
  125. * @returns The successfully connected endpoint.
  126. *
  127. * @throws boost::system::system_error Thrown on failure. If the sequence is
  128. * empty, the associated @c error_code is boost::asio::error::not_found.
  129. * Otherwise, contains the error from the last connection attempt.
  130. *
  131. * @par Example
  132. * @code tcp::resolver r(my_context);
  133. * tcp::resolver::query q("host", "service");
  134. * tcp::socket s(my_context);
  135. * boost::asio::connect(s, r.resolve(q)); @endcode
  136. */
  137. template <typename Protocol, typename Executor, typename EndpointSequence>
  138. typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
  139. const EndpointSequence& endpoints,
  140. constraint_t<
  141. is_endpoint_sequence<EndpointSequence>::value
  142. > = 0);
  143. /// Establishes a socket connection by trying each endpoint in a sequence.
  144. /**
  145. * This function attempts to connect a socket to one of a sequence of
  146. * endpoints. It does this by repeated calls to the socket's @c connect member
  147. * function, once for each endpoint in the sequence, until a connection is
  148. * successfully established.
  149. *
  150. * @param s The socket to be connected. If the socket is already open, it will
  151. * be closed.
  152. *
  153. * @param endpoints A sequence of endpoints.
  154. *
  155. * @param ec Set to indicate what error occurred, if any. If the sequence is
  156. * empty, set to boost::asio::error::not_found. Otherwise, contains the error
  157. * from the last connection attempt.
  158. *
  159. * @returns On success, the successfully connected endpoint. Otherwise, a
  160. * default-constructed endpoint.
  161. *
  162. * @par Example
  163. * @code tcp::resolver r(my_context);
  164. * tcp::resolver::query q("host", "service");
  165. * tcp::socket s(my_context);
  166. * boost::system::error_code ec;
  167. * boost::asio::connect(s, r.resolve(q), ec);
  168. * if (ec)
  169. * {
  170. * // An error occurred.
  171. * } @endcode
  172. */
  173. template <typename Protocol, typename Executor, typename EndpointSequence>
  174. typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
  175. const EndpointSequence& endpoints, boost::system::error_code& ec,
  176. constraint_t<
  177. is_endpoint_sequence<EndpointSequence>::value
  178. > = 0);
  179. /// Establishes a socket connection by trying each endpoint in a sequence.
  180. /**
  181. * This function attempts to connect a socket to one of a sequence of
  182. * endpoints. It does this by repeated calls to the socket's @c connect member
  183. * function, once for each endpoint in the sequence, until a connection is
  184. * successfully established.
  185. *
  186. * @param s The socket to be connected. If the socket is already open, it will
  187. * be closed.
  188. *
  189. * @param begin An iterator pointing to the start of a sequence of endpoints.
  190. *
  191. * @param end An iterator pointing to the end of a sequence of endpoints.
  192. *
  193. * @returns An iterator denoting the successfully connected endpoint.
  194. *
  195. * @throws boost::system::system_error Thrown on failure. If the sequence is
  196. * empty, the associated @c error_code is boost::asio::error::not_found.
  197. * Otherwise, contains the error from the last connection attempt.
  198. *
  199. * @par Example
  200. * @code tcp::resolver r(my_context);
  201. * tcp::resolver::query q("host", "service");
  202. * tcp::resolver::results_type e = r.resolve(q);
  203. * tcp::socket s(my_context);
  204. * boost::asio::connect(s, e.begin(), e.end()); @endcode
  205. */
  206. template <typename Protocol, typename Executor, typename Iterator>
  207. Iterator connect(basic_socket<Protocol, Executor>& s,
  208. Iterator begin, Iterator end);
  209. /// Establishes a socket connection by trying each endpoint in a sequence.
  210. /**
  211. * This function attempts to connect a socket to one of a sequence of
  212. * endpoints. It does this by repeated calls to the socket's @c connect member
  213. * function, once for each endpoint in the sequence, until a connection is
  214. * successfully established.
  215. *
  216. * @param s The socket to be connected. If the socket is already open, it will
  217. * be closed.
  218. *
  219. * @param begin An iterator pointing to the start of a sequence of endpoints.
  220. *
  221. * @param end An iterator pointing to the end of a sequence of endpoints.
  222. *
  223. * @param ec Set to indicate what error occurred, if any. If the sequence is
  224. * empty, set to boost::asio::error::not_found. Otherwise, contains the error
  225. * from the last connection attempt.
  226. *
  227. * @returns On success, an iterator denoting the successfully connected
  228. * endpoint. Otherwise, the end iterator.
  229. *
  230. * @par Example
  231. * @code tcp::resolver r(my_context);
  232. * tcp::resolver::query q("host", "service");
  233. * tcp::resolver::results_type e = r.resolve(q);
  234. * tcp::socket s(my_context);
  235. * boost::system::error_code ec;
  236. * boost::asio::connect(s, e.begin(), e.end(), ec);
  237. * if (ec)
  238. * {
  239. * // An error occurred.
  240. * } @endcode
  241. */
  242. template <typename Protocol, typename Executor, typename Iterator>
  243. Iterator connect(basic_socket<Protocol, Executor>& s,
  244. Iterator begin, Iterator end, boost::system::error_code& ec);
  245. /// Establishes a socket connection by trying each endpoint in a sequence.
  246. /**
  247. * This function attempts to connect a socket to one of a sequence of
  248. * endpoints. It does this by repeated calls to the socket's @c connect member
  249. * function, once for each endpoint in the sequence, until a connection is
  250. * successfully established.
  251. *
  252. * @param s The socket to be connected. If the socket is already open, it will
  253. * be closed.
  254. *
  255. * @param endpoints A sequence of endpoints.
  256. *
  257. * @param connect_condition A function object that is called prior to each
  258. * connection attempt. The signature of the function object must be:
  259. * @code bool connect_condition(
  260. * const boost::system::error_code& ec,
  261. * const typename Protocol::endpoint& next); @endcode
  262. * The @c ec parameter contains the result from the most recent connect
  263. * operation. Before the first connection attempt, @c ec is always set to
  264. * indicate success. The @c next parameter is the next endpoint to be tried.
  265. * The function object should return true if the next endpoint should be tried,
  266. * and false if it should be skipped.
  267. *
  268. * @returns The successfully connected endpoint.
  269. *
  270. * @throws boost::system::system_error Thrown on failure. If the sequence is
  271. * empty, the associated @c error_code is boost::asio::error::not_found.
  272. * Otherwise, contains the error from the last connection attempt.
  273. *
  274. * @par Example
  275. * The following connect condition function object can be used to output
  276. * information about the individual connection attempts:
  277. * @code struct my_connect_condition
  278. * {
  279. * bool operator()(
  280. * const boost::system::error_code& ec,
  281. * const::tcp::endpoint& next)
  282. * {
  283. * if (ec) std::cout << "Error: " << ec.message() << std::endl;
  284. * std::cout << "Trying: " << next << std::endl;
  285. * return true;
  286. * }
  287. * }; @endcode
  288. * It would be used with the boost::asio::connect function as follows:
  289. * @code tcp::resolver r(my_context);
  290. * tcp::resolver::query q("host", "service");
  291. * tcp::socket s(my_context);
  292. * tcp::endpoint e = boost::asio::connect(s,
  293. * r.resolve(q), my_connect_condition());
  294. * std::cout << "Connected to: " << e << std::endl; @endcode
  295. */
  296. template <typename Protocol, typename Executor,
  297. typename EndpointSequence, typename ConnectCondition>
  298. typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
  299. const EndpointSequence& endpoints, ConnectCondition connect_condition,
  300. constraint_t<
  301. is_endpoint_sequence<EndpointSequence>::value
  302. > = 0,
  303. constraint_t<
  304. is_connect_condition<ConnectCondition,
  305. decltype(declval<const EndpointSequence&>().begin())>::value
  306. > = 0);
  307. /// Establishes a socket connection by trying each endpoint in a sequence.
  308. /**
  309. * This function attempts to connect a socket to one of a sequence of
  310. * endpoints. It does this by repeated calls to the socket's @c connect member
  311. * function, once for each endpoint in the sequence, until a connection is
  312. * successfully established.
  313. *
  314. * @param s The socket to be connected. If the socket is already open, it will
  315. * be closed.
  316. *
  317. * @param endpoints A sequence of endpoints.
  318. *
  319. * @param connect_condition A function object that is called prior to each
  320. * connection attempt. The signature of the function object must be:
  321. * @code bool connect_condition(
  322. * const boost::system::error_code& ec,
  323. * const typename Protocol::endpoint& next); @endcode
  324. * The @c ec parameter contains the result from the most recent connect
  325. * operation. Before the first connection attempt, @c ec is always set to
  326. * indicate success. The @c next parameter is the next endpoint to be tried.
  327. * The function object should return true if the next endpoint should be tried,
  328. * and false if it should be skipped.
  329. *
  330. * @param ec Set to indicate what error occurred, if any. If the sequence is
  331. * empty, set to boost::asio::error::not_found. Otherwise, contains the error
  332. * from the last connection attempt.
  333. *
  334. * @returns On success, the successfully connected endpoint. Otherwise, a
  335. * default-constructed endpoint.
  336. *
  337. * @par Example
  338. * The following connect condition function object can be used to output
  339. * information about the individual connection attempts:
  340. * @code struct my_connect_condition
  341. * {
  342. * bool operator()(
  343. * const boost::system::error_code& ec,
  344. * const::tcp::endpoint& next)
  345. * {
  346. * if (ec) std::cout << "Error: " << ec.message() << std::endl;
  347. * std::cout << "Trying: " << next << std::endl;
  348. * return true;
  349. * }
  350. * }; @endcode
  351. * It would be used with the boost::asio::connect function as follows:
  352. * @code tcp::resolver r(my_context);
  353. * tcp::resolver::query q("host", "service");
  354. * tcp::socket s(my_context);
  355. * boost::system::error_code ec;
  356. * tcp::endpoint e = boost::asio::connect(s,
  357. * r.resolve(q), my_connect_condition(), ec);
  358. * if (ec)
  359. * {
  360. * // An error occurred.
  361. * }
  362. * else
  363. * {
  364. * std::cout << "Connected to: " << e << std::endl;
  365. * } @endcode
  366. */
  367. template <typename Protocol, typename Executor,
  368. typename EndpointSequence, typename ConnectCondition>
  369. typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
  370. const EndpointSequence& endpoints, ConnectCondition connect_condition,
  371. boost::system::error_code& ec,
  372. constraint_t<
  373. is_endpoint_sequence<EndpointSequence>::value
  374. > = 0,
  375. constraint_t<
  376. is_connect_condition<ConnectCondition,
  377. decltype(declval<const EndpointSequence&>().begin())>::value
  378. > = 0);
  379. /// Establishes a socket connection by trying each endpoint in a sequence.
  380. /**
  381. * This function attempts to connect a socket to one of a sequence of
  382. * endpoints. It does this by repeated calls to the socket's @c connect member
  383. * function, once for each endpoint in the sequence, until a connection is
  384. * successfully established.
  385. *
  386. * @param s The socket to be connected. If the socket is already open, it will
  387. * be closed.
  388. *
  389. * @param begin An iterator pointing to the start of a sequence of endpoints.
  390. *
  391. * @param end An iterator pointing to the end of a sequence of endpoints.
  392. *
  393. * @param connect_condition A function object that is called prior to each
  394. * connection attempt. The signature of the function object must be:
  395. * @code bool connect_condition(
  396. * const boost::system::error_code& ec,
  397. * const typename Protocol::endpoint& next); @endcode
  398. * The @c ec parameter contains the result from the most recent connect
  399. * operation. Before the first connection attempt, @c ec is always set to
  400. * indicate success. The @c next parameter is the next endpoint to be tried.
  401. * The function object should return true if the next endpoint should be tried,
  402. * and false if it should be skipped.
  403. *
  404. * @returns An iterator denoting the successfully connected endpoint.
  405. *
  406. * @throws boost::system::system_error Thrown on failure. If the sequence is
  407. * empty, the associated @c error_code is boost::asio::error::not_found.
  408. * Otherwise, contains the error from the last connection attempt.
  409. *
  410. * @par Example
  411. * The following connect condition function object can be used to output
  412. * information about the individual connection attempts:
  413. * @code struct my_connect_condition
  414. * {
  415. * bool operator()(
  416. * const boost::system::error_code& ec,
  417. * const::tcp::endpoint& next)
  418. * {
  419. * if (ec) std::cout << "Error: " << ec.message() << std::endl;
  420. * std::cout << "Trying: " << next << std::endl;
  421. * return true;
  422. * }
  423. * }; @endcode
  424. * It would be used with the boost::asio::connect function as follows:
  425. * @code tcp::resolver r(my_context);
  426. * tcp::resolver::query q("host", "service");
  427. * tcp::resolver::results_type e = r.resolve(q);
  428. * tcp::socket s(my_context);
  429. * tcp::resolver::results_type::iterator i = boost::asio::connect(
  430. * s, e.begin(), e.end(), my_connect_condition());
  431. * std::cout << "Connected to: " << i->endpoint() << std::endl; @endcode
  432. */
  433. template <typename Protocol, typename Executor,
  434. typename Iterator, typename ConnectCondition>
  435. Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
  436. Iterator end, ConnectCondition connect_condition,
  437. constraint_t<
  438. is_connect_condition<ConnectCondition, Iterator>::value
  439. > = 0);
  440. /// Establishes a socket connection by trying each endpoint in a sequence.
  441. /**
  442. * This function attempts to connect a socket to one of a sequence of
  443. * endpoints. It does this by repeated calls to the socket's @c connect member
  444. * function, once for each endpoint in the sequence, until a connection is
  445. * successfully established.
  446. *
  447. * @param s The socket to be connected. If the socket is already open, it will
  448. * be closed.
  449. *
  450. * @param begin An iterator pointing to the start of a sequence of endpoints.
  451. *
  452. * @param end An iterator pointing to the end of a sequence of endpoints.
  453. *
  454. * @param connect_condition A function object that is called prior to each
  455. * connection attempt. The signature of the function object must be:
  456. * @code bool connect_condition(
  457. * const boost::system::error_code& ec,
  458. * const typename Protocol::endpoint& next); @endcode
  459. * The @c ec parameter contains the result from the most recent connect
  460. * operation. Before the first connection attempt, @c ec is always set to
  461. * indicate success. The @c next parameter is the next endpoint to be tried.
  462. * The function object should return true if the next endpoint should be tried,
  463. * and false if it should be skipped.
  464. *
  465. * @param ec Set to indicate what error occurred, if any. If the sequence is
  466. * empty, set to boost::asio::error::not_found. Otherwise, contains the error
  467. * from the last connection attempt.
  468. *
  469. * @returns On success, an iterator denoting the successfully connected
  470. * endpoint. Otherwise, the end iterator.
  471. *
  472. * @par Example
  473. * The following connect condition function object can be used to output
  474. * information about the individual connection attempts:
  475. * @code struct my_connect_condition
  476. * {
  477. * bool operator()(
  478. * const boost::system::error_code& ec,
  479. * const::tcp::endpoint& next)
  480. * {
  481. * if (ec) std::cout << "Error: " << ec.message() << std::endl;
  482. * std::cout << "Trying: " << next << std::endl;
  483. * return true;
  484. * }
  485. * }; @endcode
  486. * It would be used with the boost::asio::connect function as follows:
  487. * @code tcp::resolver r(my_context);
  488. * tcp::resolver::query q("host", "service");
  489. * tcp::resolver::results_type e = r.resolve(q);
  490. * tcp::socket s(my_context);
  491. * boost::system::error_code ec;
  492. * tcp::resolver::results_type::iterator i = boost::asio::connect(
  493. * s, e.begin(), e.end(), my_connect_condition());
  494. * if (ec)
  495. * {
  496. * // An error occurred.
  497. * }
  498. * else
  499. * {
  500. * std::cout << "Connected to: " << i->endpoint() << std::endl;
  501. * } @endcode
  502. */
  503. template <typename Protocol, typename Executor,
  504. typename Iterator, typename ConnectCondition>
  505. Iterator connect(basic_socket<Protocol, Executor>& s,
  506. Iterator begin, Iterator end, ConnectCondition connect_condition,
  507. boost::system::error_code& ec,
  508. constraint_t<
  509. is_connect_condition<ConnectCondition, Iterator>::value
  510. > = 0);
  511. /*@}*/
  512. /**
  513. * @defgroup async_connect boost::asio::async_connect
  514. *
  515. * @brief The @c async_connect function is a composed asynchronous operation
  516. * that establishes a socket connection by trying each endpoint in a sequence.
  517. */
  518. /*@{*/
  519. /// Asynchronously establishes a socket connection by trying each endpoint in a
  520. /// sequence.
  521. /**
  522. * This function attempts to connect a socket to one of a sequence of
  523. * endpoints. It does this by repeated calls to the socket's @c async_connect
  524. * member function, once for each endpoint in the sequence, until a connection
  525. * is successfully established. It is an initiating function for an @ref
  526. * asynchronous_operation, and always returns immediately.
  527. *
  528. * @param s The socket to be connected. If the socket is already open, it will
  529. * be closed.
  530. *
  531. * @param endpoints A sequence of endpoints.
  532. *
  533. * @param token The @ref completion_token that will be used to produce a
  534. * completion handler, which will be called when the connect completes.
  535. * Potential completion tokens include @ref use_future, @ref use_awaitable,
  536. * @ref yield_context, or a function object with the correct completion
  537. * signature. The function signature of the completion handler must be:
  538. * @code void handler(
  539. * // Result of operation. if the sequence is empty, set to
  540. * // boost::asio::error::not_found. Otherwise, contains the
  541. * // error from the last connection attempt.
  542. * const boost::system::error_code& error,
  543. *
  544. * // On success, the successfully connected endpoint.
  545. * // Otherwise, a default-constructed endpoint.
  546. * const typename Protocol::endpoint& endpoint
  547. * ); @endcode
  548. * Regardless of whether the asynchronous operation completes immediately or
  549. * not, the completion handler will not be invoked from within this function.
  550. * On immediate completion, invocation of the handler will be performed in a
  551. * manner equivalent to using boost::asio::async_immediate().
  552. *
  553. * @par Completion Signature
  554. * @code void(boost::system::error_code, typename Protocol::endpoint) @endcode
  555. *
  556. * @par Example
  557. * @code tcp::resolver r(my_context);
  558. * tcp::resolver::query q("host", "service");
  559. * tcp::socket s(my_context);
  560. *
  561. * // ...
  562. *
  563. * r.async_resolve(q, resolve_handler);
  564. *
  565. * // ...
  566. *
  567. * void resolve_handler(
  568. * const boost::system::error_code& ec,
  569. * tcp::resolver::results_type results)
  570. * {
  571. * if (!ec)
  572. * {
  573. * boost::asio::async_connect(s, results, connect_handler);
  574. * }
  575. * }
  576. *
  577. * // ...
  578. *
  579. * void connect_handler(
  580. * const boost::system::error_code& ec,
  581. * const tcp::endpoint& endpoint)
  582. * {
  583. * // ...
  584. * } @endcode
  585. *
  586. * @par Per-Operation Cancellation
  587. * This asynchronous operation supports cancellation for the following
  588. * boost::asio::cancellation_type values:
  589. *
  590. * @li @c cancellation_type::terminal
  591. *
  592. * @li @c cancellation_type::partial
  593. *
  594. * if they are also supported by the socket's @c async_connect operation.
  595. */
  596. template <typename Protocol, typename Executor, typename EndpointSequence,
  597. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  598. typename Protocol::endpoint)) RangeConnectToken
  599. = default_completion_token_t<Executor>>
  600. inline auto async_connect(basic_socket<Protocol, Executor>& s,
  601. const EndpointSequence& endpoints,
  602. RangeConnectToken&& token = default_completion_token_t<Executor>(),
  603. constraint_t<
  604. is_endpoint_sequence<EndpointSequence>::value
  605. > = 0,
  606. constraint_t<
  607. !is_connect_condition<RangeConnectToken,
  608. decltype(declval<const EndpointSequence&>().begin())>::value
  609. > = 0)
  610. -> decltype(
  611. async_initiate<RangeConnectToken,
  612. void (boost::system::error_code, typename Protocol::endpoint)>(
  613. declval<detail::initiate_async_range_connect<Protocol, Executor>>(),
  614. token, endpoints, declval<detail::default_connect_condition>()))
  615. {
  616. return async_initiate<RangeConnectToken,
  617. void (boost::system::error_code, typename Protocol::endpoint)>(
  618. detail::initiate_async_range_connect<Protocol, Executor>(s),
  619. token, endpoints, detail::default_connect_condition());
  620. }
  621. /// Asynchronously establishes a socket connection by trying each endpoint in a
  622. /// sequence.
  623. /**
  624. * This function attempts to connect a socket to one of a sequence of
  625. * endpoints. It does this by repeated calls to the socket's @c async_connect
  626. * member function, once for each endpoint in the sequence, until a connection
  627. * is successfully established. It is an initiating function for an @ref
  628. * asynchronous_operation, and always returns immediately.
  629. *
  630. * @param s The socket to be connected. If the socket is already open, it will
  631. * be closed.
  632. *
  633. * @param begin An iterator pointing to the start of a sequence of endpoints.
  634. *
  635. * @param end An iterator pointing to the end of a sequence of endpoints.
  636. *
  637. * @param token The @ref completion_token that will be used to produce a
  638. * completion handler, which will be called when the connect completes.
  639. * Potential completion tokens include @ref use_future, @ref use_awaitable,
  640. * @ref yield_context, or a function object with the correct completion
  641. * signature. The function signature of the completion handler must be:
  642. * @code void handler(
  643. * // Result of operation. if the sequence is empty, set to
  644. * // boost::asio::error::not_found. Otherwise, contains the
  645. * // error from the last connection attempt.
  646. * const boost::system::error_code& error,
  647. *
  648. * // On success, an iterator denoting the successfully
  649. * // connected endpoint. Otherwise, the end iterator.
  650. * Iterator iterator
  651. * ); @endcode
  652. * Regardless of whether the asynchronous operation completes immediately or
  653. * not, the completion handler will not be invoked from within this function.
  654. * On immediate completion, invocation of the handler will be performed in a
  655. * manner equivalent to using boost::asio::async_immediate().
  656. *
  657. * @par Completion Signature
  658. * @code void(boost::system::error_code, Iterator) @endcode
  659. *
  660. * @par Example
  661. * @code std::vector<tcp::endpoint> endpoints = ...;
  662. * tcp::socket s(my_context);
  663. * boost::asio::async_connect(s,
  664. * endpoints.begin(), endpoints.end(),
  665. * connect_handler);
  666. *
  667. * // ...
  668. *
  669. * void connect_handler(
  670. * const boost::system::error_code& ec,
  671. * std::vector<tcp::endpoint>::iterator i)
  672. * {
  673. * // ...
  674. * } @endcode
  675. *
  676. * @par Per-Operation Cancellation
  677. * This asynchronous operation supports cancellation for the following
  678. * boost::asio::cancellation_type values:
  679. *
  680. * @li @c cancellation_type::terminal
  681. *
  682. * @li @c cancellation_type::partial
  683. *
  684. * if they are also supported by the socket's @c async_connect operation.
  685. */
  686. template <typename Protocol, typename Executor, typename Iterator,
  687. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  688. Iterator)) IteratorConnectToken = default_completion_token_t<Executor>>
  689. inline auto async_connect(
  690. basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end,
  691. IteratorConnectToken&& token = default_completion_token_t<Executor>(),
  692. constraint_t<
  693. !is_connect_condition<IteratorConnectToken, Iterator>::value
  694. > = 0)
  695. -> decltype(
  696. async_initiate<IteratorConnectToken,
  697. void (boost::system::error_code, Iterator)>(
  698. declval<detail::initiate_async_iterator_connect<Protocol, Executor>>(),
  699. token, begin, end, declval<detail::default_connect_condition>()))
  700. {
  701. return async_initiate<IteratorConnectToken,
  702. void (boost::system::error_code, Iterator)>(
  703. detail::initiate_async_iterator_connect<Protocol, Executor>(s),
  704. token, begin, end, detail::default_connect_condition());
  705. }
  706. /// Asynchronously establishes a socket connection by trying each endpoint in a
  707. /// sequence.
  708. /**
  709. * This function attempts to connect a socket to one of a sequence of
  710. * endpoints. It does this by repeated calls to the socket's @c async_connect
  711. * member function, once for each endpoint in the sequence, until a connection
  712. * is successfully established. It is an initiating function for an @ref
  713. * asynchronous_operation, and always returns immediately.
  714. *
  715. * @param s The socket to be connected. If the socket is already open, it will
  716. * be closed.
  717. *
  718. * @param endpoints A sequence of endpoints.
  719. *
  720. * @param connect_condition A function object that is called prior to each
  721. * connection attempt. The signature of the function object must be:
  722. * @code bool connect_condition(
  723. * const boost::system::error_code& ec,
  724. * const typename Protocol::endpoint& next); @endcode
  725. * The @c ec parameter contains the result from the most recent connect
  726. * operation. Before the first connection attempt, @c ec is always set to
  727. * indicate success. The @c next parameter is the next endpoint to be tried.
  728. * The function object should return true if the next endpoint should be tried,
  729. * and false if it should be skipped.
  730. *
  731. * @param token The @ref completion_token that will be used to produce a
  732. * completion handler, which will be called when the connect completes.
  733. * Potential completion tokens include @ref use_future, @ref use_awaitable,
  734. * @ref yield_context, or a function object with the correct completion
  735. * signature. The function signature of the completion handler must be:
  736. * @code void handler(
  737. * // Result of operation. if the sequence is empty, set to
  738. * // boost::asio::error::not_found. Otherwise, contains the
  739. * // error from the last connection attempt.
  740. * const boost::system::error_code& error,
  741. *
  742. * // On success, an iterator denoting the successfully
  743. * // connected endpoint. Otherwise, the end iterator.
  744. * Iterator iterator
  745. * ); @endcode
  746. * Regardless of whether the asynchronous operation completes immediately or
  747. * not, the completion handler will not be invoked from within this function.
  748. * On immediate completion, invocation of the handler will be performed in a
  749. * manner equivalent to using boost::asio::async_immediate().
  750. *
  751. * @par Completion Signature
  752. * @code void(boost::system::error_code, typename Protocol::endpoint) @endcode
  753. *
  754. * @par Example
  755. * The following connect condition function object can be used to output
  756. * information about the individual connection attempts:
  757. * @code struct my_connect_condition
  758. * {
  759. * bool operator()(
  760. * const boost::system::error_code& ec,
  761. * const::tcp::endpoint& next)
  762. * {
  763. * if (ec) std::cout << "Error: " << ec.message() << std::endl;
  764. * std::cout << "Trying: " << next << std::endl;
  765. * return true;
  766. * }
  767. * }; @endcode
  768. * It would be used with the boost::asio::connect function as follows:
  769. * @code tcp::resolver r(my_context);
  770. * tcp::resolver::query q("host", "service");
  771. * tcp::socket s(my_context);
  772. *
  773. * // ...
  774. *
  775. * r.async_resolve(q, resolve_handler);
  776. *
  777. * // ...
  778. *
  779. * void resolve_handler(
  780. * const boost::system::error_code& ec,
  781. * tcp::resolver::results_type results)
  782. * {
  783. * if (!ec)
  784. * {
  785. * boost::asio::async_connect(s, results,
  786. * my_connect_condition(),
  787. * connect_handler);
  788. * }
  789. * }
  790. *
  791. * // ...
  792. *
  793. * void connect_handler(
  794. * const boost::system::error_code& ec,
  795. * const tcp::endpoint& endpoint)
  796. * {
  797. * if (ec)
  798. * {
  799. * // An error occurred.
  800. * }
  801. * else
  802. * {
  803. * std::cout << "Connected to: " << endpoint << std::endl;
  804. * }
  805. * } @endcode
  806. *
  807. * @par Per-Operation Cancellation
  808. * This asynchronous operation supports cancellation for the following
  809. * boost::asio::cancellation_type values:
  810. *
  811. * @li @c cancellation_type::terminal
  812. *
  813. * @li @c cancellation_type::partial
  814. *
  815. * if they are also supported by the socket's @c async_connect operation.
  816. */
  817. template <typename Protocol, typename Executor,
  818. typename EndpointSequence, typename ConnectCondition,
  819. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  820. typename Protocol::endpoint)) RangeConnectToken
  821. = default_completion_token_t<Executor>>
  822. inline auto async_connect(basic_socket<Protocol, Executor>& s,
  823. const EndpointSequence& endpoints, ConnectCondition connect_condition,
  824. RangeConnectToken&& token = default_completion_token_t<Executor>(),
  825. constraint_t<
  826. is_endpoint_sequence<EndpointSequence>::value
  827. > = 0,
  828. constraint_t<
  829. is_connect_condition<ConnectCondition,
  830. decltype(declval<const EndpointSequence&>().begin())>::value
  831. > = 0)
  832. -> decltype(
  833. async_initiate<RangeConnectToken,
  834. void (boost::system::error_code, typename Protocol::endpoint)>(
  835. declval<detail::initiate_async_range_connect<Protocol, Executor>>(),
  836. token, endpoints, connect_condition))
  837. {
  838. return async_initiate<RangeConnectToken,
  839. void (boost::system::error_code, typename Protocol::endpoint)>(
  840. detail::initiate_async_range_connect<Protocol, Executor>(s),
  841. token, endpoints, connect_condition);
  842. }
  843. /// Asynchronously establishes a socket connection by trying each endpoint in a
  844. /// sequence.
  845. /**
  846. * This function attempts to connect a socket to one of a sequence of
  847. * endpoints. It does this by repeated calls to the socket's @c async_connect
  848. * member function, once for each endpoint in the sequence, until a connection
  849. * is successfully established. It is an initiating function for an @ref
  850. * asynchronous_operation, and always returns immediately.
  851. *
  852. * @param s The socket to be connected. If the socket is already open, it will
  853. * be closed.
  854. *
  855. * @param begin An iterator pointing to the start of a sequence of endpoints.
  856. *
  857. * @param end An iterator pointing to the end of a sequence of endpoints.
  858. *
  859. * @param connect_condition A function object that is called prior to each
  860. * connection attempt. The signature of the function object must be:
  861. * @code bool connect_condition(
  862. * const boost::system::error_code& ec,
  863. * const typename Protocol::endpoint& next); @endcode
  864. * The @c ec parameter contains the result from the most recent connect
  865. * operation. Before the first connection attempt, @c ec is always set to
  866. * indicate success. The @c next parameter is the next endpoint to be tried.
  867. * The function object should return true if the next endpoint should be tried,
  868. * and false if it should be skipped.
  869. *
  870. * @param token The @ref completion_token that will be used to produce a
  871. * completion handler, which will be called when the connect completes.
  872. * Potential completion tokens include @ref use_future, @ref use_awaitable,
  873. * @ref yield_context, or a function object with the correct completion
  874. * signature. The function signature of the completion handler must be:
  875. * @code void handler(
  876. * // Result of operation. if the sequence is empty, set to
  877. * // boost::asio::error::not_found. Otherwise, contains the
  878. * // error from the last connection attempt.
  879. * const boost::system::error_code& error,
  880. *
  881. * // On success, an iterator denoting the successfully
  882. * // connected endpoint. Otherwise, the end iterator.
  883. * Iterator iterator
  884. * ); @endcode
  885. * Regardless of whether the asynchronous operation completes immediately or
  886. * not, the completion handler will not be invoked from within this function.
  887. * On immediate completion, invocation of the handler will be performed in a
  888. * manner equivalent to using boost::asio::async_immediate().
  889. *
  890. * @par Completion Signature
  891. * @code void(boost::system::error_code, Iterator) @endcode
  892. *
  893. * @par Example
  894. * The following connect condition function object can be used to output
  895. * information about the individual connection attempts:
  896. * @code struct my_connect_condition
  897. * {
  898. * bool operator()(
  899. * const boost::system::error_code& ec,
  900. * const::tcp::endpoint& next)
  901. * {
  902. * if (ec) std::cout << "Error: " << ec.message() << std::endl;
  903. * std::cout << "Trying: " << next << std::endl;
  904. * return true;
  905. * }
  906. * }; @endcode
  907. * It would be used with the boost::asio::connect function as follows:
  908. * @code tcp::resolver r(my_context);
  909. * tcp::resolver::query q("host", "service");
  910. * tcp::socket s(my_context);
  911. *
  912. * // ...
  913. *
  914. * r.async_resolve(q, resolve_handler);
  915. *
  916. * // ...
  917. *
  918. * void resolve_handler(
  919. * const boost::system::error_code& ec,
  920. * tcp::resolver::iterator i)
  921. * {
  922. * if (!ec)
  923. * {
  924. * tcp::resolver::iterator end;
  925. * boost::asio::async_connect(s, i, end,
  926. * my_connect_condition(),
  927. * connect_handler);
  928. * }
  929. * }
  930. *
  931. * // ...
  932. *
  933. * void connect_handler(
  934. * const boost::system::error_code& ec,
  935. * tcp::resolver::iterator i)
  936. * {
  937. * if (ec)
  938. * {
  939. * // An error occurred.
  940. * }
  941. * else
  942. * {
  943. * std::cout << "Connected to: " << i->endpoint() << std::endl;
  944. * }
  945. * } @endcode
  946. *
  947. * @par Per-Operation Cancellation
  948. * This asynchronous operation supports cancellation for the following
  949. * boost::asio::cancellation_type values:
  950. *
  951. * @li @c cancellation_type::terminal
  952. *
  953. * @li @c cancellation_type::partial
  954. *
  955. * if they are also supported by the socket's @c async_connect operation.
  956. */
  957. template <typename Protocol, typename Executor,
  958. typename Iterator, typename ConnectCondition,
  959. BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
  960. Iterator)) IteratorConnectToken = default_completion_token_t<Executor>>
  961. inline auto async_connect(basic_socket<Protocol, Executor>& s,
  962. Iterator begin, Iterator end, ConnectCondition connect_condition,
  963. IteratorConnectToken&& token = default_completion_token_t<Executor>(),
  964. constraint_t<
  965. is_connect_condition<ConnectCondition, Iterator>::value
  966. > = 0)
  967. -> decltype(
  968. async_initiate<IteratorConnectToken,
  969. void (boost::system::error_code, Iterator)>(
  970. declval<detail::initiate_async_iterator_connect<Protocol, Executor>>(),
  971. token, begin, end, connect_condition))
  972. {
  973. return async_initiate<IteratorConnectToken,
  974. void (boost::system::error_code, Iterator)>(
  975. detail::initiate_async_iterator_connect<Protocol, Executor>(s),
  976. token, begin, end, connect_condition);
  977. }
  978. /*@}*/
  979. } // namespace asio
  980. } // namespace boost
  981. #include <boost/asio/detail/pop_options.hpp>
  982. #include <boost/asio/impl/connect.hpp>
  983. #endif // BOOST_ASIO_CONNECT_HPP