找不到主机(非权威) - Boost::asio udp 解析器

问题描述 投票:0回答:1

我目前正在开发一个项目,需要解析端点,并且我正在使用 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 配置,但我不知道如何处理它。

c++ dns udp boost-asio
1个回答
0
投票

如果没有独立的示例,很难诊断。这是我经过代码审查的、简化得多的函数:

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])

当然,在线编译器不允许网络访问,所以这里是本地的:

© www.soinside.com 2019 - 2024. All rights reserved.