我写了一个小的C ++ asio程序,现在我想将备份服务器添加到客户端的服务器“列表”中。客户端尝试通过asio解析程序连接到服务器,但如果服务器处于脱机状态,客户端应自动连接到“备份服务器”。那么我可以向解析器添加多个地址,还是需要编写整个“尝试连接 - >失败 - >尝试连接到下一个服务器”功能?
答案 0 :(得分:3)
虽然正确的其他答案断言您正在寻找完全的东西不存在,但您可以非常轻松地构建它:
struct multi_iterator : tcp::resolver::iterator {
using base = typename tcp::resolver::iterator;
multi_iterator() = default;
template <typename T>
explicit multi_iterator(T&& v) : base(std::forward<T>(v)) {}
using base::values_;
void append(tcp::resolver::results_type const& r) {
if (!values_) values_.reset(new typename base::values_type);
values_->insert(values_->end(), r.begin(), r.end());
}
};
现在您可以合并许多查询的结果:
multi_iterator it;
std::vector<tcp::resolver::query> queries {
{ "localhost", "8080" },
{ "localhost", "8081" },
{ "google.com", "https" },
{ "localhost", "6767" },
};
for (auto query : queries)
it.append(tcp::resolver(io).resolve(query));
使用boost::asio::connect
或boost::asio::async_connect
进行端点迭代:
tcp::socket sock(io);
auto ep = *boost::asio::connect(sock, it);
std::cout << "Connected to " << ep.endpoint() << " (for " << ep.host_name() << ":" << ep.service_name() << ")\n";
在我的系统上打印
Connected to 172.217.19.206:443 (for google.com:https)
因为我没有在本地侦听端口8080或8081。打开netcat -l -p 8081
之后的其中一个:
Connected to 127.0.0.1:8081 (for localhost:8081)
还包括更通用的basic_multi_iterator<Protocol>
:
#include <boost/asio.hpp>
#include <iostream>
template <typename Proto>
struct basic_multi_iterator : boost::asio::ip::basic_resolver<Proto>::iterator {
using resolver = typename boost::asio::ip::basic_resolver<Proto>;
using base = typename resolver::iterator;
basic_multi_iterator() = default;
template <typename T> explicit basic_multi_iterator(T&& v)
: base(std::forward<T>(v))
{}
using base::values_;
void append(typename resolver::results_type const& r) {
if (!values_)
values_.reset(new typename base::values_type);
values_->insert(values_->end(), r.begin(), r.end());
}
};
using boost::asio::ip::tcp;
using multi_iterator = basic_multi_iterator<tcp>;
int main() {
boost::asio::io_context io;
multi_iterator it;
std::vector<tcp::resolver::query> queries {
{ "localhost", "8080" },
{ "localhost", "8081" },
{ "google.com", "https" },
{ "localhost", "6767" },
};
for (auto query : queries)
it.append(tcp::resolver(io).resolve(query));
try {
tcp::socket sock(io);
auto ep = *boost::asio::connect(sock, it);
std::cout << "Connected to " << ep.endpoint() << " (for " << ep.host_name() << ":" << ep.service_name() << ")\n";
} catch (boost::system::system_error const& e) {
std::cout << e.what() << " - " << e.code().message() << "\n";
}
}
答案 1 :(得分:0)
Asio不提供这种“跳过并尝试其他服务器”功能的开箱即用功能。您需要自己编写该代码。