到目前为止,我得到的是:
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不是我的功能,但我不得不处理它。任何帮助都将不胜感激。
发布于 2017-11-10 17:12:08
由于Objective是一个真正的C超集,并且达尔文被证明与SUS 3兼容,您的iOS目标-C程序应该能够使用C接口到系统的名称解析器:getaddrinfo()。可以使用此函数的第三个参数来指定只需要IPv4结果(或只希望IPv6结果)。
你应该注意的事情:
getaddrinfo()分配并返回一个链接的地址列表,因此- in principle, you might need to check more than one
- you need to free the list after you're done with it via `freeaddrinfo()`
发布于 2021-10-06 21:06:45
您没有得到回调的原因是您没有使用调度队列。DNSServiceGetAddrInfo API是异步的。如果您是在Apple设备上执行此操作,则需要更多类似于以下内容的内容:
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为您做了“愉快的眼球”部分--尝试每个响应直到它得到一个连接,并返回它得到的连接,取消其他的连接。
但你没有问这个问题,所以我不会在这里详述。
https://stackoverflow.com/questions/47227298
复制相似问题