可以使用一个adns的c库,版本是1.6,官方地址:adns - advanced, alternative, asynchronous resolver
下载地址是:http://www.chiark.greenend.org.uk/~ian/adns/ftp/adns-1.6.0.tar.gz
我实验环境是ubuntu20.04
解压,并编译
tar xzvf adns-1.6.0.tar.gz
cd adns-1.6.0
./configure
make
我没有make install
直接创建了一个测试目录,拷贝静态库
mkdir test
cp ./src/adns.h ./test
cp ./src/libadns.a ./test
建立一个测试文件
test.c
#include "adns.h"
#include
#include
#include
#include
int test_dns(char *host) {
adns_state ads;
adns_initflags flags;
flags = (adns_initflags)(adns_if_nosigpipe | adns_if_noerrprint);
adns_init(&ads, flags, NULL);
adns_query quer = NULL;
adns_submit(ads, host, (adns_rrtype)adns_r_a, (adns_queryflags)0, NULL, &quer);
int tryCount = -1;
int adns_cname = 0;
adns_answer *ans = NULL;
while (tryCount < 32)
{
tryCount += 1;
int res = adns_check(ads, &quer, &ans, NULL);
if (res == 0)
{
if (ans->status == adns_s_prohibitedcname)
{
char cname[128];
strncpy(cname, ans->cname, 127);
printf("cname = %s \n", ans->cname );
cname[strlen(ans->cname)] = '\0';
//if (quer)
// free(quer);
if (ans)
free(ans);
ans = NULL;
quer = NULL;
adns_submit(ads, cname, (adns_rrtype)adns_r_addr, (adns_queryflags)0, NULL, &quer);
adns_cname = 1;
}
else
{
// resolve IPv4 address
if (adns_cname)
{
printf("ip: %s\n", ans->status == adns_s_ok ? inet_ntoa(ans->rrs.addr->addr.inet.sin_addr) : "no");
}
else {
printf("ip: %s\n", ans->status == adns_s_ok ? inet_ntoa(*(ans->rrs.inaddr)) : "no");
}
adns_finish(ads);
ads = NULL;
break;
}
}
else if (res == ESRCH || res == EAGAIN)
{
usleep(1000);
}
else
{
printf("host(%s) is err!\n", host);
}
}
//if (quer)
// free(quer);
if (ans)
free(ans);
if (ads)
{
printf("time out to find\n");
adns_finish(ads);
}
return 0;
}
int main(int argc, char *argv[])
{
char host[128];
while (1)
{
scanf("%s", host);
if (strlen(host) == 4 && 0 == strcmp(host, "exit"))
break;
test_dns(host);
}
return 0;
}
这里解释一下,为什么不直接用wait,而非要做一个循环检测,主要是因为首次返回的可能是别名,而不是地址,必须要递归检测一下才能获取真实地址;
另外注意内存释放!!!
手动编译
gcc -o test ./test.c -L./ -ladns
生成test文件,
执行一下内存测试:
valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all --undef-value-errors=no --log-file=log.txt ./test
www.sohu.com
cname = gs.a.sohu.com
ip: 123.125.116.12
www.baidu.com
ip: 182.61.200.7
www.github.com
ip: 20.205.243.166
exit
==============华丽的分割线======================================
这里再附赠一个真正可以用的c++版本:
/**
* @file dns_test.cpp
* @author robin (390017268@qq.com)
* @brief example to show how to use libadns to parse domain name, and use it in a worker thread
* @version 0.1
* @date 2022-05-12
*
* @copyright Copyright (c) 2022
*
* build: gcc ./test.cpp -std=c++11 -L./ -ladns -lpthread -lstdc++ -w -g -o test
* valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all --undef-value-errors=no --log-file=log.txt ./test
*/
#include
#include
#include
#include
// just for cpp,
#include
#include
#include
#include
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)