首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >gai_cancel()需要很长时间才能成功

gai_cancel()需要很长时间才能成功
EN

Stack Overflow用户
提问于 2019-06-12 09:59:43
回答 1查看 157关注 0票数 2

我正在尝试在c++中异步查找域。原因是我希望能够有效地添加一个超时周期,以防系统无法查找该域。我遇到了getaddrinfo_a()命令,所以我决定试一试。然而,在我的机器上,取消任何不会成功的dns查找(例如,当没有互联网连接时)需要的时间永远不会少于20秒。下面是一个简单的例子:

代码语言:javascript
复制
#include <iostream>
#include <netdb.h>
#include <string.h>
#include <unistd.h>

using namespace std;

int main() {


        int ret;
        gaicb* reqs;

        reqs = new gaicb;

        memset(reqs, 0, sizeof (gaicb));
        reqs->ar_name = "google.com";

        ret = getaddrinfo_a(GAI_NOWAIT, &reqs, 1, NULL);
        if (ret != 0) {
                cout << "something went wrong" << endl;
                return false;
        }

        while (1) {
                ret = gai_cancel(reqs);
                if (ret == EAI_CANCELED || ret == EAI_ALLDONE) {
                        break;
                }
                usleep(100 * 1000); //sleep for 100 milliseconds
        }

        cout << "finished cancellation" << endl;


        return 0;
}

像这样编译:

代码语言:javascript
复制
g++ -o main main.cpp -lanl

然后在没有internet连接的基于linux的系统上运行该命令,如下所示:

代码语言:javascript
复制
time ./main

您会发现该程序总是需要大约20秒才能关闭。任何帮助都将不胜感激!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-14 05:54:44

好的,如果您需要小于20秒的异步dns查找,那么答案是不要使用getaddrinfo_a(3)。此外,根据Martin Sustrik对http://sourceware-org.1504.n7.nabble.com/getaddrinfo-a-memory-leaks-td233794.html的第二条评论,以及我在这里的经验,getaddrinfo_a看起来是相当实验性的,无论如何都不应该使用。实际上,我最终还是使用了dns.c (https://github.com/wahern/dns)。下面是一个示例,供任何正在查看的人参考:

代码语言:javascript
复制
#include "dns.c"

uint8_t getaddrinfo_k(
uint32_t* ip_addr, const char* dns_address, uint32_t timeout) {
    int32_t                 rc;
    struct addrinfo         hints;
    struct dns_resolv_conf* dns_conf;
    struct dns_hosts*       dns_hosts;
    struct dns_hints*       dns_hints;
    struct dns_resolver*    resolver;
    struct dns_addrinfo*    ai;
    struct addrinfo*        it;

    dns_conf    = dns_resconf_local(&rc);
    assert(dns_conf);
    dns_hosts   = dns_hosts_local(&rc);
    assert(dns_hosts);
    dns_hints   = dns_hints_local(dns_conf, &rc);
    assert(dns_hints);
    resolver    = dns_res_open(
    dns_conf, dns_hosts, dns_hints, NULL, dns_opts(), &rc);
    assert(resolver);
    it          = NULL;

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = PF_INET;

    ai = dns_ai_open(dns_address, "80", DNS_T_A, &hints, resolver, &rc);
    assert(ai);

    while (timeout-- > 0) {
        rc = dns_ai_nextent(&it, ai);
        switch(rc) {
                case 0:
                        *ip_addr = (
                        (struct sockaddr_in *) it->ai_addr)->sin_addr.s_addr;
                        free(it);
                        goto exit_loop;
                case EAGAIN:
                        rc = dns_ai_poll(ai, 1);
                        assert(rc == 0);
                        break;
                default:
                        goto exit_loop;
        }
        usleep(100 * 1000);
    }

    exit_loop:

    dns_ai_close        (ai);
    dns_res_close       (resolver);
    dns_hints_close     (dns_hints);
    dns_hosts_close     (dns_hosts);
    dns_resconf_close   (dns_conf);

    switch(rc) {
        case 0:
            return 1;
        case EAGAIN:
            printf("DNS_WRAPPER: timed out\n");
            break;
        case ENOENT:
            printf("DNS_WRAPPER: file doesn't exist\n");
            break;
        default:
            printf("DNS_WRAPPER: unknown error\n");
            break;
    }

    return 0;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56553708

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档