如何使用 c-ares 将 IP 解析为主机?

发布于 2024-10-15 06:57:22 字数 553 浏览 2 评论 0原文

这就是我到目前为止所做的。它可以编译,但当我尝试运行它时会出现段错误。

#include <iostream>
#include <netdb.h>
#include <arpa/inet.h>
#include <ares.h>

void dns_callback (void* arg, int status, int timeouts, struct hostent* host)
  {
    std::cout << host->h_name << "\n";
  }

int main(int argc, char **argv)
  {
    struct in_addr ip;
    char *arg;
    inet_aton(argv[1], &ip);
    ares_channel channel;
    ares_gethostbyaddr(channel, &ip, 4, AF_INET, dns_callback, arg);
    sleep(15);
    return 0;
  }

This is what I've done so far. It compiles, but it segfaults when I try to run it.

#include <iostream>
#include <netdb.h>
#include <arpa/inet.h>
#include <ares.h>

void dns_callback (void* arg, int status, int timeouts, struct hostent* host)
  {
    std::cout << host->h_name << "\n";
  }

int main(int argc, char **argv)
  {
    struct in_addr ip;
    char *arg;
    inet_aton(argv[1], &ip);
    ares_channel channel;
    ares_gethostbyaddr(channel, &ip, 4, AF_INET, dns_callback, arg);
    sleep(15);
    return 0;
  }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我一直都在从未离去 2024-10-22 06:57:22

在使用 ares_channel 之前,您至少必须初始化

 if(ares_init(&channel) != ARES_SUCCESS) {
   //handle error
  }

您还需要一个事件循环来处理ares 文件描述符上的事件并调用 ares_process 来处理这些事件(更常见的是,您d 将其集成到应用程序的事件循环中)
ares 没有什么神奇之处,它不使用线程来进行异步处理,因此只需调用 sleep(15);不允许 ares 在“后台”运行

您的回调还应该检查 status 变量,如果查找失败,您将无法访问 host->h_name

一个完整的例子变成:

#include <time.h>
#include <iostream>
#include <netdb.h>
#include <arpa/inet.h>
#include <ares.h>

void dns_callback (void* arg, int status, int timeouts, struct hostent* host)
{
    if(status == ARES_SUCCESS)
        std::cout << host->h_name << "\n";
    else
        std::cout << "lookup failed: " << status << '\n';
}
void main_loop(ares_channel &channel)
{
    int nfds, count;
    fd_set readers, writers;
    timeval tv, *tvp;
    while (1) {
        FD_ZERO(&readers);
        FD_ZERO(&writers);
        nfds = ares_fds(channel, &readers, &writers);
        if (nfds == 0)
          break;
        tvp = ares_timeout(channel, NULL, &tv);
        count = select(nfds, &readers, &writers, NULL, tvp);
        ares_process(channel, &readers, &writers);
     }

}
int main(int argc, char **argv)
{
    struct in_addr ip;
    int res;
    if(argc < 2 ) {
        std::cout << "usage: " << argv[0] << " ip.address\n";
        return 1;
    }
    inet_aton(argv[1], &ip);
    ares_channel channel;
    if((res = ares_init(&channel)) != ARES_SUCCESS) {
        std::cout << "ares feiled: " << res << '\n';
        return 1;
    }
    ares_gethostbyaddr(channel, &ip, sizeof ip, AF_INET, dns_callback, NULL);
    main_loop(channel);
    return 0;
  }
 $ g++ -Wall test_ares.cpp  -lcares
 $ ./a.out 8.8.8.8
google-public-dns-a.google.com

You atleast have to initialize the ares_channel before you use it

 if(ares_init(&channel) != ARES_SUCCESS) {
   //handle error
  }

You also need an event loop to process events on the ares file descriptors and call ares_process to handle those events (more commonly, you'd integrate this in the event loop of your application)
There's nothing magic with ares, it doesn't use threads to do the async processing so simply calling sleep(15); doesn't let ares run in the "background"

Your callback should also inspect the status variable, you can't access host->h_name if the lookup failed.

A full example becomes:

#include <time.h>
#include <iostream>
#include <netdb.h>
#include <arpa/inet.h>
#include <ares.h>

void dns_callback (void* arg, int status, int timeouts, struct hostent* host)
{
    if(status == ARES_SUCCESS)
        std::cout << host->h_name << "\n";
    else
        std::cout << "lookup failed: " << status << '\n';
}
void main_loop(ares_channel &channel)
{
    int nfds, count;
    fd_set readers, writers;
    timeval tv, *tvp;
    while (1) {
        FD_ZERO(&readers);
        FD_ZERO(&writers);
        nfds = ares_fds(channel, &readers, &writers);
        if (nfds == 0)
          break;
        tvp = ares_timeout(channel, NULL, &tv);
        count = select(nfds, &readers, &writers, NULL, tvp);
        ares_process(channel, &readers, &writers);
     }

}
int main(int argc, char **argv)
{
    struct in_addr ip;
    int res;
    if(argc < 2 ) {
        std::cout << "usage: " << argv[0] << " ip.address\n";
        return 1;
    }
    inet_aton(argv[1], &ip);
    ares_channel channel;
    if((res = ares_init(&channel)) != ARES_SUCCESS) {
        std::cout << "ares feiled: " << res << '\n';
        return 1;
    }
    ares_gethostbyaddr(channel, &ip, sizeof ip, AF_INET, dns_callback, NULL);
    main_loop(channel);
    return 0;
  }
 $ g++ -Wall test_ares.cpp  -lcares
 $ ./a.out 8.8.8.8
google-public-dns-a.google.com
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文