开发者

Sharing a DNSServiceRef using kDNSServiceFlagsShareConnection stalls my program

开发者 https://www.devze.com 2023-01-09 19:52 出处:网络
I\'m building a client using dns-sd api from Bonjour. I notice that there is a flag called kDNSServiceFlagsShareConnection that it is used to share the connection of one DNSServiceRef.

I'm building a client using dns-sd api from Bonjour. I notice that there is a flag called kDNSServiceFlagsShareConnection that it is used to share the connection of one DNSServiceRef.

Apple site says

For efficiency, clients that perform many concurrent operations may want to use a single Unix Domain Socket connection with the background daemon, instead of having a separate connection for each independent operation. To use this mode, clients first call DNSServiceCreateConnection(&MainRef) to initialize the main DNSServiceRef. For each subsequent operation that is to share that same connection, the client copies the MainRef, and then passes the address of that copy, setting the ShareConnection flag to tell the library that this DNSServiceRef is not a typical uninitialized DNSServiceRef; it's a copy of an existing DNSServiceRef whose connection information should be reused.

There is even an example that shows how to use the flag. The problem i'm having is when I run the program it stays like waiting for something whenever I call a function with the flag. Here is the code:

DNSServiceErrorType error;
DNSServiceRef MainRef, BrowseRef;

error = DNSServiceCreateConnection(&MainRef);
BrowseRef = Mai开发者_运维问答nRef;
//I'm omitting when I check for errors

error = DNSServiceBrowse(&MainRef, kDNSServiceFlagsShareConnection, 0, "_http._tcp", "local", browse_reply, NULL); 
// After this call the program stays waiting for I don't know what

//I'm omitting when I check for errors
error = DNSServiceBrowse(&BrowseRef, kDNSServiceFlagsShareConnection, 0, "_http._tcp", "local", browse_reply, NULL);
//I'm omitting when i check for errors
DNSServiceRefDeallocate(BrowseRef); // Terminate the browse operation
DNSServiceRefDeallocate(MainRef); // Terminate the shared connection

Any ideas? thoughts? suggestion?


Since there are conflicting answers, I dug up the source - annotations by me.

// If sharing...
if (flags & kDNSServiceFlagsShareConnection)
{
    // There must be something to share (can't use this on the first call)
    if (!*ref)
    {
        return kDNSServiceErr_BadParam;
    }
    // Ref must look valid (specifically, ref->fd)
    if (!DNSServiceRefValid(*ref) || 
    // Most operations cannot be shared.
          ((*ref)->op != connection_request &&
           (*ref)->op != connection_delegate_request) ||
    // When sharing, pass the ref from the original call.
        (*ref)->primary)
    {
         return kDNSServiceErr_BadReference;
    }

The primary fiels is explained elsewhere:

// When using kDNSServiceFlagsShareConnection, there is one primary _DNSServiceOp_t, and zero or more subordinates
// For the primary, the 'next' field points to the first subordinate, and its 'next' field points to the next, and so on.
// For the primary, the 'primary' field is NULL; for subordinates the 'primary' field points back to the associated primary

The problem with the question is that DNSServiceBrowse maps to ref->op==browse_request which causes a kDNSServiceErr_BadReference.

It looks like kDNSServiceFlagsShareConnection is half-implemented, because I've also seen cases in which it works - this source was found by tracing back when it didn't work.


Service referenses for browsing and resolving may unfortunately not be shared. See the comments in the Bonjour documentation for the kDNSServiceFlagsShareConnection-flag. Since you only browse twice I would just let them have separate service-refs instead.

So both DNSServiceBrowse() and DNSServiceResolve() require an unallocated service-ref as first parameter.

I can't explain why your program chokes though. The first DNSServiceBrowse() call in your example should return immediately with an error code.


Although an old question, but it should help people looking around for answers now.

The answer by vidtige is incorrect, the may be shared for any operation, provided you pass the 'kDNSServiceFlagsShareConnection' flag along with the arguments. Sample below -

    m_dnsrefsearch = m_dnsservice;
    DNSServiceErrorType mdnserr = DNSServiceBrowse(&m_dnsrefsearch,kDNSServiceFlagsShareConnection,0,
        "_workstation._tcp",NULL,
        DNSServiceBrowseReplyCallback,NULL);

Reference - http://osxr.org/android/source/external/mdnsresponder/mDNSShared/dns_sd.h#0267

0

精彩评论

暂无评论...
验证码 换一张
取 消