我目前正在开发一个项目,需要解析端点,并且我正在使用 Boost Asio 的 udp 解析器。但是,我遇到以下错误:“找不到主机(非权威),请稍后再试。” 我可以使用 nslookup 在终端中解决它,我也可以直接连接到 IP 地址,问题实际上是在我的应用程序中解决它。
这是我用来执行此操作的代码:
nf::Result<std::vector<udp::endpoint>, errorCode> EndpointResolver::resolveEndpoint(const std::string& endpointString, boost::asio::io_service &ioService) {
std::vector<std::string> endpointSplit;
boost::split(endpointSplit, endpointString, boost::is_any_of(":"));
if (endpointSplit.size() != 2) {
nf::error("Unable to split endpoint into host and port. Provided endpoint: {}", endpointString);
return nf::result::Err<errorCode>{boost::system::errc::make_error_code(boost::system::errc::bad_address)};
}
const std::string& hostname = endpointSplit.front();
const std::string& port = endpointSplit.back();
boost::system::error_code error;
udp::resolver resolver(ioService);
auto resolvedEndpoints = resolver.resolve(hostname, port, error);
if (error) {
return nf::result::Err<errorCode>{error};
}
return std::accumulate(resolvedEndpoints,
decltype(resolvedEndpoints){},
std::vector<udp::endpoint>{},
[&endpointString](auto acc, const auto& ep) {
nf::debug("Endpoint '{}' resolved to: {}", endpointString, ep.endpoint());
udp::endpoint endpoint(ep);
acc.push_back(endpoint);
return acc;
});
}
我尝试使用解析器标志、解析函数的不同重载,但仍然遇到相同的错误。 我认为这可能是我机器上的 DNS 配置,但我不知道如何处理它。
如果没有独立的示例,很难诊断。这是我经过代码审查的、简化得多的函数:
nf::Result<std::vector<udp::endpoint>, errorCode> //
resolve(std::string_view input) {
auto colon = input.find_last_of(":");
auto port = input.substr(colon + 1);
auto hostname = input.substr(0, colon);
if (hostname == port) {
// nf::error("Unable to split endpoint into host and port. Provided endpoint: {}", input);
return make_error_code(asio::error::invalid_argument); // TODO fix error code!
}
errorCode error;
udp::resolver resolver(asio::system_executor{});
auto eps = resolver.resolve(hostname, port, error);
if (error)
return error;
return std::vector<udp::endpoint>(eps.begin(), eps.end());
}
有完整的演示! 实时编译器资源管理器
#include <boost/asio.hpp>
#include <fmt/ranges.h>
#include <fmt/std.h>
#include <fmt/ostream.h>
#include <string>
namespace asio = boost::asio;
using asio::ip::udp;
using errorCode = boost::system::error_code;
template <> struct fmt::formatter<udp::endpoint> : ostream_formatter {};
template <> struct fmt::formatter<errorCode> : formatter<std::string> {
auto format(errorCode const& ec, auto& ctx) const {
return fmt::format_to(ctx.out(), "{}", ec.message());
}
};
namespace nf { // mock ups for demo
template <typename T, typename U> using Result = std::variant<T, U>;
void error(auto fmt, auto const&... args) {
fmt::print(stderr, fmt::runtime(fmt), args...);
fmt::print(stderr, "\n");
}
void debug(auto fmt, auto const&... args) {
fmt::print(fmt::runtime(fmt), args...);
fmt::print("\n");
}
} // namespace nf
struct EndpointResolver {
nf::Result<std::vector<udp::endpoint>, errorCode> //
resolve(std::string_view input) {
auto colon = input.find_last_of(":");
auto port = input.substr(colon + 1);
auto hostname = input.substr(0, colon);
if (hostname == port) {
// nf::error("Unable to split endpoint into host and port. Provided endpoint: {}", input);
return make_error_code(asio::error::invalid_argument); // TODO fix error code!
}
errorCode error;
udp::resolver resolver(asio::system_executor{});
auto eps = resolver.resolve(hostname, port, error);
if (error)
return error;
return std::vector<udp::endpoint>(eps.begin(), eps.end());
}
};
int main() {
EndpointResolver er;
for (auto input : {
"",
":80",
"google.com:http",
"127.0.0.1:12345",
"example.com:https",
}) {
fmt::print("'{}' -> {}\n", input, er.resolve(input));
}
}
打印预期输出:
'' -> variant(Invalid argument)
':80' -> variant([[::1]:80, 127.0.0.1:80])
'google.com:http' -> variant(Service not found)
'127.0.0.1:12345' -> variant([127.0.0.1:12345])
'example.com:https' -> variant([93.184.216.34:443, [2606:2800:220:1:248:1893:25c8:1946]
:443])
当然,在线编译器不允许网络访问,所以这里是本地的: