我打电话DNSServiceBrowse
,具有“共享连接”(见dns_sd.h
对于文件)如:
DNSServiceCreateConnection(&ServiceRef);
// Need to copy the main ref to another variable.
DNSServiceRef BrowseServiceRef = ServiceRef;
DNSServiceBrowse(&BrowseServiceRef, // Receives reference to Bonjour browser object.
kDNSServiceFlagsShareConnection, // Indicate it's a shared connection.
kDNSServiceInterfaceIndexAny, // Browse on all network interfaces.
"_servicename._tcp", // Browse for service types.
NULL, // Browse on the default domain (e.g. local.).
BrowserCallBack, // Callback function when Bonjour events occur.
this); // Callback context.
这是称为ServiceDiscovery
一个线程类的主run
方法内。 ServiceRef
是ServiceDiscovery
的成员。
于是马上按照上面的代码中,我有一个主事件循环如下所示:
while (true)
{
err = DNSServiceProcessResult(ServiceRef);
if (err != kDNSServiceErr_NoError)
{
DNSServiceRefDeallocate(BrowseServiceRef);
DNSServiceRefDeallocate(ServiceRef);
ServiceRef = nullptr;
}
}
然后,在BrowserCallback
你必须设置决心要求:
void DNSSD_API ServiceDiscovery::BrowserCallBack(DNSServiceRef inServiceRef,
DNSServiceFlags inFlags,
uint32_t inIFI,
DNSServiceErrorType inError,
const char* inName,
const char* inType,
const char* inDomain,
void* inContext)
{
(void) inServiceRef; // Unused
ServiceDiscovery* sd = (ServiceDiscovery*)inContext;
...
// Pass a copy of the main DNSServiceRef (just a pointer). We don't
// hang to the local copy since it's passed in the resolve callback,
// where we deallocate it.
DNSServiceRef resolveServiceRef = sd->ServiceRef;
DNSServiceErrorType err =
DNSServiceResolve(&resolveServiceRef,
kDNSServiceFlagsShareConnection, // Indicate it's a shared connection.
inIFI,
inName,
inType,
inDomain,
ResolveCallBack,
sd);
然后在ResolveCallback
你应该拥有你需要的一切。
// Callback for Bonjour resolve events.
void DNSSD_API ServiceDiscovery::ResolveCallBack(DNSServiceRef inServiceRef,
DNSServiceFlags inFlags,
uint32_t inIFI,
DNSServiceErrorType inError,
const char* fullname,
const char* hosttarget,
uint16_t port, /* In network byte order */
uint16_t txtLen,
const unsigned char* txtRecord,
void* inContext)
{
ServiceDiscovery* sd = (ServiceDiscovery*)inContext;
assert(sd);
// Save off the connection info, get TXT records, etc.
...
// Deallocate the DNSServiceRef.
DNSServiceRefDeallocate(inServiceRef);
}
hosttarget
和port
包含您的连接信息,并且可以使用DNS-SD API(例如TXTRecordGetCount
和TXTRecordGetItemAtIndex
)获得的任何文字记录。
使用共享连接引用时,必须在完成每个引用时基于(或从中复制父引用)来释放每个引用。当您将共享引用的副本传递给其中一个函数时,我认为DNS-SD API会执行一些引用计数(以及父/子关系)。再次请参阅文档以获取详细信息。
我尝试不使用共享连接,我只是传递ServiceRef
,导致它被覆盖在回调和我的主循环中,以混淆。我想如果你不使用共享连接,你需要维护一个需要进一步处理的引用列表(并且处理每个引用),然后在完成时将它们销毁。共享连接方式似乎更容易。