gpt4 book ai didi

c++ - gai_cancel() 需要很长时间才能成功

转载 作者:太空狗 更新时间:2023-10-29 12:38:59 24 4
gpt4 key购买 nike

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

#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;
}

像这样编译:

g++ -o main main.cpp -lanl

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

time ./main

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

最佳答案

好的,如果您需要短于 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 )。这是供任何人查看的示例:

#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;
}

关于c++ - gai_cancel() 需要很长时间才能成功,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56553708/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com