Error[8]: Undefined offset: 7, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

概述正如标题所示,我想要使用指定的DNS服务器解析主机名(例如www.example.com).例如,在一种情况下,我想使用谷歌的IPv4 DNS,在其他情况下,谷歌的IPv6 DNS. 我在iOS上浏览了类似这样的东西,发现了像这样的问题(Swift – Get device’s IP Address),所以我相信它可以做到,但我不清楚怎么办? 我怎样才能做到这一点? 编辑06/07/2018 @m 正如标题所示,我想要使用指定的DNS服务器解析主机名(例如www.example.com).例如,在一种情况下,我想使用谷歌的IPv4 DNS,在其他情况下,谷歌的IPv6 DNS.

我在iOS上浏览了类似这样的东西,发现了像这样的问题(Swift – Get device’s IP Address),所以我相信它可以做到,但我不清楚怎么办?

我怎样才能做到这一点?

编辑06/07/2018

@mdeora建议从http://www.software7.com/blog/programmatically-query-specific-dns-servers-on-ios/开始解决

此解决方案有效,但仅限于我使用IPv4 DNS,例如Google的“8.8.8.8”.如果我尝试使用IPv6 DNS 2001:4860:4860 :: 8888,我什么都没得到.

我设法改变转换:

voID setup_dns_server(res_state res,const char *dns_server){    res_ninit(res);    struct in_addr addr;//    int returnValue = inet_aton(dns_server,&addr);    inet_pton(AF_INET6,dns_server,&addr); // for IPv6 conversion    res->nsaddr_List[0].sin_addr = addr;    res->nsaddr_List[0].sin_family = AF_INET;    res->nsaddr_List[0].sin_port = htons(NS_DEFAulTPORT);    res->nscount = 1;};

但仍然有这个问题:

voID query_ip(res_state res,const char *host,char ip[]){    u_char answer[NS_PACKETSZ];//NS_IN6ADDRSZ NS_PACKETSZ    int len = res_nquery(res,host,ns_c_in,ns_t_a,answer,sizeof(answer));    ns_msg handle;    ns_initparse(answer,len,&handle);    if(ns_msg_count(handle,ns_s_an) > 0) {        ns_rr rr;        if(ns_parserr(&handle,ns_s_an,&rr) == 0) {            strcpy(ip,inet_ntoa(*(struct in_addr *)ns_rr_rdata(rr)));        }    }}

len得到-1.从我收集的内容来看,我似乎需要为IPv6配置res_state.

解决方法 这里我上面提到的博客中的代码稍微适应了使用IPv6.

适应setup_dns_server

首先我们可以从setup_dns_server的更改开始:

voID setup_dns_server(res_state res,const char *dns_server) {    struct in6_addr addr;    inet_pton(AF_INET6,&addr);    res->_u._ext.ext->nsaddrs[0].sin6.sin6_addr = addr;    res->_u._ext.ext->nsaddrs[0].sin6.sin6_family = AF_INET6;    res->_u._ext.ext->nsaddrs[0].sin6.sin6_port = htons(NS_DEFAulTPORT);    res->nscount = 1;}

添加__res_state_ext

由于缺少struct __res_state_ext,因此无法编译.不幸的是,这种结构位于私有头文件中.

但是这个的定义可以从这里得出:
https://opensource.apple.com/source/libresolv/libresolv-65/res_private.h.auto.html:

struct __res_state_ext {    union res_sockaddr_union nsaddrs[MAXNS];    struct sort_List {        int af;        union {            struct in_addr  ina;            struct in6_addr in6a;        } addr,mask;    } sort_List[MAXRESolVSORT];    char nsuffix[64];    char bsuffix[64];    char nsuffix2[64];};

可以添加结构,例如在文件的顶部.

适应resolveHost

这里的更改包括更长的ip缓冲区(INET6_ADDRSTRLEN). res_ninit从setup_dns_server移动到此方法,现在与res_ndestroy匹配.

+ (Nsstring *)resolveHost:(Nsstring *)host usingDNSServer:(Nsstring *)dnsServer {    struct __res_state res;    char ip[INET6_ADDRSTRLEN];    memset(ip,'
voID query_ip(res_state res,char ip[]) {    u_char answer[NS_PACKETSZ];    int len = res_nquery(res,ns_t_aaaa,&rr) == 0) {            inet_ntop(AF_INET6,ns_rr_rdata(rr),ip,INET6_ADDRSTRLEN);        }    }}
',sizeof(ip)); res_ninit(&res); setup_dns_server(&res,[dnsServer cStringUsingEnCoding:NSASCIIStringEnCoding]); query_ip(&res,[host cStringUsingEnCoding:NSUTF8StringEnCoding],ip); res_ndestroy(&res); return [[Nsstring alloc] initWithCString:ip enCoding:NSASCIIStringEnCoding];}

检索IPv6地址

如果您只想为DNS服务器使用IPv6地址,则上述更改已足够.因此,在query_ip中,如果您仍想检索IPv4地址,则无需进行任何更改.

如果您还想从DNS服务器检索IPv6地址,您可以这样做:

Nsstring *resolved = [ResolveUtil resolveHost:@"www.Google.com" usingDNSServer:@"2001:4860:4860::8888"];NSLog(@"%@",resolved);

请注意:我们在这里使用ns_t_aaaa来获取AAAA资源记录(quad-A记录),因为在DNS中它指定了IPv6地址和主机名之间的映射.对于许多主机,没有这样的四A记录,这意味着您可以通过IPv4访问它们.

呼叫

你会称它为例如像这样:

[+++]

结果如下:

放弃

这些只是简单的示例调用,演示了函数的基本用法.没有错误处理.

总结

以上是内存溢出为你收集整理的iOS:如何指定用于将主机名解析为IP地址的DNS?全部内容,希望文章能够帮你解决iOS:如何指定用于将主机名解析为IP地址的DNS?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
iOS:如何指定用于将主机名解析为IP地址的DNS?_app_内存溢出

iOS:如何指定用于将主机名解析为IP地址的DNS?

iOS:如何指定用于将主机名解析为IP地址的DNS?,第1张

概述正如标题所示,我想要使用指定的DNS服务器解析主机名(例如www.example.com).例如,在一种情况下,我想使用谷歌的IPv4 DNS,在其他情况下,谷歌的IPv6 DNS. 我在iOS上浏览了类似这样的东西,发现了像这样的问题(Swift – Get device’s IP Address),所以我相信它可以做到,但我不清楚怎么办? 我怎样才能做到这一点? 编辑06/07/2018 @m 正如标题所示,我想要使用指定的DNS服务器解析主机名(例如www.example.com).例如,在一种情况下,我想使用谷歌的IPv4 DNS,在其他情况下,谷歌的IPv6 DNS.

我在iOS上浏览了类似这样的东西,发现了像这样的问题(Swift – Get device’s IP Address),所以我相信它可以做到,但我不清楚怎么办?

我怎样才能做到这一点?

编辑06/07/2018

@mdeora建议从http://www.software7.com/blog/programmatically-query-specific-dns-servers-on-ios/开始解决

此解决方案有效,但仅限于我使用IPv4 DNS,例如Google的“8.8.8.8”.如果我尝试使用IPv6 DNS 2001:4860:4860 :: 8888,我什么都没得到.

我设法改变转换:

voID setup_dns_server(res_state res,const char *dns_server){    res_ninit(res);    struct in_addr addr;//    int returnValue = inet_aton(dns_server,&addr);    inet_pton(AF_INET6,dns_server,&addr); // for IPv6 conversion    res->nsaddr_List[0].sin_addr = addr;    res->nsaddr_List[0].sin_family = AF_INET;    res->nsaddr_List[0].sin_port = htons(NS_DEFAulTPORT);    res->nscount = 1;};

但仍然有这个问题:

voID query_ip(res_state res,const char *host,char ip[]){    u_char answer[NS_PACKETSZ];//NS_IN6ADDRSZ NS_PACKETSZ    int len = res_nquery(res,host,ns_c_in,ns_t_a,answer,sizeof(answer));    ns_msg handle;    ns_initparse(answer,len,&handle);    if(ns_msg_count(handle,ns_s_an) > 0) {        ns_rr rr;        if(ns_parserr(&handle,ns_s_an,&rr) == 0) {            strcpy(ip,inet_ntoa(*(struct in_addr *)ns_rr_rdata(rr)));        }    }}

len得到-1.从我收集的内容来看,我似乎需要为IPv6配置res_state.

解决方法 这里我上面提到的博客中的代码稍微适应了使用IPv6.

适应setup_dns_server

首先我们可以从setup_dns_server的更改开始:

voID setup_dns_server(res_state res,const char *dns_server) {    struct in6_addr addr;    inet_pton(AF_INET6,&addr);    res->_u._ext.ext->nsaddrs[0].sin6.sin6_addr = addr;    res->_u._ext.ext->nsaddrs[0].sin6.sin6_family = AF_INET6;    res->_u._ext.ext->nsaddrs[0].sin6.sin6_port = htons(NS_DEFAulTPORT);    res->nscount = 1;}

添加__res_state_ext

由于缺少struct __res_state_ext,因此无法编译.不幸的是,这种结构位于私有头文件中.

但是这个的定义可以从这里得出:
https://opensource.apple.com/source/libresolv/libresolv-65/res_private.h.auto.html:

struct __res_state_ext {    union res_sockaddr_union nsaddrs[MAXNS];    struct sort_List {        int af;        union {            struct in_addr  ina;            struct in6_addr in6a;        } addr,mask;    } sort_List[MAXRESolVSORT];    char nsuffix[64];    char bsuffix[64];    char nsuffix2[64];};

可以添加结构,例如在文件的顶部.

适应resolveHost

这里的更改包括更长的ip缓冲区(INET6_ADDRSTRLEN). res_ninit从setup_dns_server移动到此方法,现在与res_ndestroy匹配.

+ (Nsstring *)resolveHost:(Nsstring *)host usingDNSServer:(Nsstring *)dnsServer {    struct __res_state res;    char ip[INET6_ADDRSTRLEN];    memset(ip,'
voID query_ip(res_state res,char ip[]) {    u_char answer[NS_PACKETSZ];    int len = res_nquery(res,ns_t_aaaa,&rr) == 0) {            inet_ntop(AF_INET6,ns_rr_rdata(rr),ip,INET6_ADDRSTRLEN);        }    }}
',sizeof(ip)); res_ninit(&res); setup_dns_server(&res,[dnsServer cStringUsingEnCoding:NSASCIIStringEnCoding]); query_ip(&res,[host cStringUsingEnCoding:NSUTF8StringEnCoding],ip); res_ndestroy(&res); return [[Nsstring alloc] initWithCString:ip enCoding:NSASCIIStringEnCoding];}

检索IPv6地址

如果您只想为DNS服务器使用IPv6地址,则上述更改已足够.因此,在query_ip中,如果您仍想检索IPv4地址,则无需进行任何更改.

如果您还想从DNS服务器检索IPv6地址,您可以这样做:

Nsstring *resolved = [ResolveUtil resolveHost:@"www.Google.com" usingDNSServer:@"2001:4860:4860::8888"];NSLog(@"%@",resolved);

请注意:我们在这里使用ns_t_aaaa来获取AAAA资源记录(quad-A记录),因为在DNS中它指定了IPv6地址和主机名之间的映射.对于许多主机,没有这样的四A记录,这意味着您可以通过IPv4访问它们.

呼叫

你会称它为例如像这样:

结果如下:

放弃

这些只是简单的示例调用,演示了函数的基本用法.没有错误处理.

总结

以上是内存溢出为你收集整理的iOS:如何指定用于将主机名解析为IP地址的DNS?全部内容,希望文章能够帮你解决iOS:如何指定用于将主机名解析为IP地址的DNS?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/web/1067119.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存