Как использовать NSHost, чтобы получить имя за кучей IP-адресов локальной сети? - PullRequest
1 голос
/ 18 января 2012

Я знаю, как получить имя за IP-адресом с помощью терминала и копать. То есть:

dig @224.0.0.251 -p5353 -x 192.168.0.195 +short

Однако я не хочу использовать NSTask в своем приложении. Как я могу использовать NSHost, чтобы получить имя за IP-адресом в локальной сети? Я пробовал это, но всегда возвращает ноль :

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

Большое спасибо!

Edit: Эти методы / функции ... + [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 multicast lookup) в своем приложении без использования NSTask. :)

1 Ответ

2 голосов
/ 10 апреля 2012

Он не использует 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;
}

Важная часть - использование DNSServiceQueryRecord с 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.-самостоятельно, но это не сложно (октетыв конце «in-addr.arpa.», вероятно, похож на IPv6, но я его не проверял).

Импортирует resolv.h (и вам нужно связать его с libresolv), нотолько для dn_expand.Данные, передаваемые в обратный вызов, сжимаются, и dn_expand создает удобочитаемое представление.

...