首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否有一种方法可以为IPv4和IPv6单独在ObjC或ObjC中进行DNS请求?

是否有一种方法可以为IPv4和IPv6单独在ObjC或ObjC中进行DNS请求?
EN

Stack Overflow用户
提问于 2017-11-10 16:32:08
回答 2查看 578关注 0票数 0

到目前为止,我得到的是:

代码语言:javascript
复制
void startQueryIPv4(const char *hostName){
printf("startQueryIPv4");
DNSServiceRef serviceRef;
DNSServiceGetAddrInfo(&serviceRef, kDNSServiceFlagsForceMulticast, 0, kDNSServiceProtocol_IPv4, hostName, queryIPv4Callback, NULL);
DNSServiceProcessResult(serviceRef);
DNSServiceRefDeallocate(serviceRef);
}


static void queryIPv4Callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *hostname, const struct sockaddr *address, uint32_t ttl, void *context){
printf("queryIPv4Callback");

if (errorCode == kDNSServiceErr_NoError) {

    printf("no error");
    char *theAddress = NULL;

    switch(address->sa_family) {
        case AF_INET: {
            struct sockaddr_in *addr_in = (struct sockaddr_in *)address;
            theAddress = malloc(INET_ADDRSTRLEN);
            inet_ntop(AF_INET, &(addr_in->sin_addr), theAddress, INET_ADDRSTRLEN);
            break;
        }
        case AF_INET6: {
            struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)address;
            theAddress = malloc(INET6_ADDRSTRLEN);
            inet_ntop(AF_INET6, &(addr_in6->sin6_addr), theAddress, INET6_ADDRSTRLEN);
            break;
        }
        default:
            break;
    }
    printf("IP address: %s\n", theAddress);
    free(theAddress);

} else {
    printf("%d", errorCode);
}

}

但回调从来没有被调用过。在控制台中,我得到了这个错误: TIC读取状态9:0x0: 1:57 ObjectiveC不是我的功能,但我不得不处理它。任何帮助都将不胜感激。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-11-10 17:12:08

由于Objective是一个真正的C超集,并且达尔文被证明与SUS 3兼容,您的iOS目标-C程序应该能够使用C接口到系统的名称解析器:getaddrinfo()。可以使用此函数的第三个参数来指定只需要IPv4结果(或只希望IPv6结果)。

你应该注意的事情:

  • 当然,这是一个同步接口;如果您想要异步,那么您需要自己安排。
  • getaddrinfo()分配并返回一个链接的地址列表,因此
代码语言:javascript
复制
- in principle, you might need to check more than one
- you need to free the list after you're done with it via `freeaddrinfo()`

票数 0
EN

Stack Overflow用户

发布于 2021-10-06 21:06:45

您没有得到回调的原因是您没有使用调度队列。DNSServiceGetAddrInfo API是异步的。如果您是在Apple设备上执行此操作,则需要更多类似于以下内容的内容:

代码语言:javascript
复制
void startQueryIPv4(const char *hostName) {
  printf("startQueryIPv4");
  DNSServiceRef serviceRef;
  DNSServiceGetAddrInfo(&serviceRef, kDNSServiceFlagsForceMulticast, 0, kDNSServiceProtocol_IPv4, hostName, queryIPv4Callback, NULL);
  main_queue = dispatch_get_main_queue();
  DNSServiceSetDispatchQueue(sdref, main_queue);
  dispatch_main();
}

注意,dispatch_main()是lib分派的主要事件循环:如果您想做其他事情,需要在调度循环中安排它,因为dispatch_main()不会返回。

在您的原始代码中,您调用了DNSServiceRefDeallocate(),但是在您想要停止查询之前不能这样做。如果在启动查询后立即调用它,它将取消查询。因此,你可以从回调中调用它。

但是,一个更好的流程是执行一个长寿命查询(kDNSServiceFlagsLongLivedQuery),以便在信息发生变化时得到更新。当然,您需要更改要连接到的主机,所以只有在应用程序连接时间较长的情况下才需要这样做。

此外,你可能会得到一个以上的答案。如果你这样做了,那可能是有些答案起作用了,而另一些答案则不起作用。因此,你可能喜欢累积答案并尝试每一个答案,而不是放弃如果你得到的第一个答案不起作用。如果有更多的数据立即出现,回调将包括kDNSServiceFlagsMoreComing标志。每次调用回调时,它都会得到一个答案(或者表示查询以某种方式失败)。

当然,这是一个相当低级别的API.如果你想让你的生活简单一点,你应该使用网络框架。Network为您做了“愉快的眼球”部分--尝试每个响应直到它得到一个连接,并返回它得到的连接,取消其他的连接。

但你没有问这个问题,所以我不会在这里详述。

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

https://stackoverflow.com/questions/47227298

复制
相关文章

相似问题

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