1

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

dig @224.0.0.251 -p5353 -x 192.168.0.195 +short

但是,我不想在我的应用程序中使用 NSTask。如何使用 NSHost 获取 LAN 内 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,那就太好了。:)

4

1 回答 1

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;
}

重要的部分是使用DNSServiceQueryRecordwith kDNSServiceFlagsForceMulticast。有关此功能的更多信息,请查看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创建人类可读的表示。

于 2012-04-10T16:13:39.857 回答