我在LAN上的设备上运行的服务器应用程序可通过DNS-SD(即Zeroconf / Bonjour / Avahi)发现。同样在LAN上的客户端设备连接到此服务器。我无法控制用于连接到我的服务器应用程序的应用程序,但我知道他们可能正在使用DNS-SD和mDNS来发现并连接到服务器。如何在C或C ++中仅检索识别这些客户端设备的链接本地域名?
根据RFC 6762 Multicast DNS - Section 4. Reverse Address Mapping:
“Like”.local。“,IPv4和IPv6反向映射域也被定义为链接本地...由于此域下的名称对应于IPv4链接本地地址,因此本地链接是合乎逻辑的。找到与这些名称有关的信息的最佳位置。“
理论上,应该可以通过IP地址查找链接本地域名。有谁知道怎么样?也许我没有找到合适的位置,但我没有在Bonjour文档中看到API调用。
答案 0 :(得分:1)
我最终通过Apple的Bonjour Dev邮件列表得到了这个问题的答案。
根据 Quinn“The Eskimo!”,以下是您可以这样做的方法:
static void DNSCallback(
DNSServiceRef sdRef,
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
)
{
const uint8_t * cursor;
fprintf(stderr, "DNSCallback\n");
assert(rrtype == kDNSServiceType_PTR);
assert(rrclass == kDNSServiceClass_IN);
cursor = (const uint8_t *) rdata;
while ( *cursor != 0 ) {
fprintf(stderr, "%.*s.", (int) *cursor, cursor + 1);
cursor += *cursor + 1;
}
fprintf(stderr, "\n");
}
static void SocketCallBack(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *data, void *info)
{
DNSServiceErrorType err;
fprintf(stderr, "SocketCallBack\n");
err = DNSServiceProcessResult(((AppDelegate *) info)->sdRef);
fprintf(stderr, "err = %d\n", (int) err);
}
- (IBAction)testAction:(id)sender
{
DNSServiceErrorType err;
int sock;
CFSocketRef cfSock;
fprintf(stderr, "-[AppDelegate testAction:]\n");
assert(self->sdRef == NULL);
err = DNSServiceQueryRecord(
&self->sdRef,
kDNSServiceFlagsForceMulticast,
0,
"9.40.0.10.in-addr.arpa.",
kDNSServiceType_PTR,
kDNSServiceClass_IN,
DNSCallback,
self
);
fprintf(stderr, "err = %d\n", (int) err);
sock = DNSServiceRefSockFD(self->sdRef);
fprintf(stderr, "sock = %d\n", sock);
CFSocketContext context = { 0, self, NULL, NULL, NULL };
cfSock = CFSocketCreateWithNative(NULL, sock, kCFSocketReadCallBack, SocketCallBack, &context);
assert(cfSock != NULL);
CFRunLoopSourceRef rls;
rls = CFSocketCreateRunLoopSource(NULL, cfSock, 0);
assert(rls != NULL);
CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
}
此示例将找到IP地址10.0.40.9的链接本地主机名。 IP地址以相反的顺序插入。