如何使用NSHost获取一堆LAN IP地址背后的名称?

时间:2012-01-17 20:57:52

标签: cocoa dns dig nshost

我知道如何使用终端获取IP地址后面的名称并挖掘。即:

dig @224.0.0.251 -p5353 -x 192.168.0.195 +short

但是,我不想在我的应用程序中使用NSTask。 如何在局域网内使用NSHost获取IP地址后面的名称?我尝试了这个,但它总是返回 nil

NSHost *myHost = [NSHost hostWithAddress:@"192.168.0.195"]; 
NSLog(@"name: %@", [myHost name]);

非常感谢!

修改 这些方法/功能......     + [NSHost hostWithAddress:]     gethostbyaddr(3) - BSD功能 ......似乎与:

相同
dig -x 192.168.0.195

如果我在终端中使用dig命令,则表示无法访问任何服务器。 (是的,我的局域网中没有DNS服务器),所以难怪我回来了 nil

如果我可以在我的应用程序中实现dig @224.0.0.251 -p5353 -x 192.168.0.195 +short(bonjour多播查找)而不必使用NSTask,那将会很棒。 :)

1 个答案:

答案 0 :(得分:2)

它不使用NSHost,而是使用Bonjour-API,它似乎可以按您的方式工作:

#import <Cocoa/Cocoa.h>
#import <dns_sd.h>
#import <resolv.h>

static void callback(DNSServiceRef serviceRef, DNSServiceFlags flags, uint32_t interfaceIndex,
                     DNSServiceErrorType errorCode, const char *fullname,
                     uint16_t rrtype, uint16_t rrclass,
                     uint16_t rdlen, const void *rdata,
                     uint32_t ttl, void *context) {

    char result[1024] = {0};
    dn_expand(rdata, rdata + rdlen, rdata, result, 1024);
    NSLog(@"Found: %s", result);
}

int main(int argc, char const *argv[]) {
    DNSServiceRef reverseLookupService = NULL;

    DNSServiceErrorType error = kDNSServiceErr_NoError;
    error = DNSServiceQueryRecord(&reverseLookupService, kDNSServiceFlagsForceMulticast,
        kDNSServiceInterfaceIndexAny, "5.1.168.192.in-addr.arpa.",
        kDNSServiceType_PTR, kDNSServiceClass_IN,
        callback, NULL);

    if (error != kDNSServiceErr_NoError) {
        NSLog(@"Error: %d", error);
        exit(1);
    }

    error = DNSServiceProcessResult(reverseLookupService);

    DNSServiceRefDeallocate(reverseLookupService);

    return 0;
}

重要的是将DNSServiceQueryRecordkDNSServiceFlagsForceMulticast一起使用。有关此功能的更多信息,请查看https://developer.apple.com/library/mac/#documentation/Networking/Reference/DNSServiceDiscovery_CRef/dns_sd_h/index.html#//apple_ref/c/func/DNSServiceQueryRecord

你必须自己将IP地址转换为in-addr.arpa.-format,但这并不难(八位字节最后是“in-addr.arpa。”。IPv6可能是类似的,但我没有测试过它。)

它导入resolv.h(您需要将其链接到libresolv),但仅适用于dn_expand。传递给回调的数据被压缩,dn_expand创建一个人类可读的表示。