使用 kDNSServiceFlagsShareConnection 共享 DNSServiceRef 会停止我的程序

发布于 2024-09-12 16:38:09 字数 1267 浏览 5 评论 0原文

我正在使用 Bonjour 的 dns-sd api 构建客户端。我注意到有一个名为 kDNSServiceFlagsShareConnection 的标志,它用于共享一个 DNSServiceRef 的连接。

苹果网站说

为了提高效率,执行许多并发操作的客户端可能希望使用与后台守护程序的单个 Unix 域套接字连接,而不是为每个独立操作使用单独的连接。要使用此模式,客户端首先调用 DNSServiceCreateConnection(&MainRef) 来初始化主 DNSServiceRef。对于共享同一连接的每个后续操作,客户端复制 MainRef,然后传递该副本的地址,设置 ShareConnection 标志以告诉库此 DNSServiceRef 不是典型的未初始化的 DNSServiceRef;它是现有 DNSServiceRef 的副本,应重用其连接信息。

甚至还有一个示例展示了如何使用该标志。我遇到的问题是,当我运行程序时,每当我调用带有标志的函数时,它就像在等待某些东西。这是代码:

DNSServiceErrorType error;
DNSServiceRef MainRef, BrowseRef;

error = DNSServiceCreateConnection(&MainRef);
BrowseRef = MainRef;
//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

有什么想法吗?想法?建议?

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 = MainRef;
//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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

北陌 2024-09-19 16:38:09

由于存在相互矛盾的答案,我挖掘了来源 - 我的注释。

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

primary 字段在其他地方进行了解释:

// 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

问题的问题是 DNSServiceBrowse 映射到 ref->op==browse_request ,这会导致 代码>kDNSServiceErr_BadReference。

看起来 kDNSServiceFlagsShareConnection 已经实现了一半,因为我也见过它起作用的情况 - 这个来源是通过追溯它不起作用时找到的。

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.

夕色琉璃 2024-09-19 16:38:09

不幸的是,用于浏览和解析的服务引用可能不会被共享。请参阅 kDNSServiceFlagsShareConnection 标志的 Bonjour 文档。由于您只浏览两次,我只会让他们有单独的服务引用。

因此,DNSServiceBrowse()DNSServiceResolve() 都需要未分配的 service-ref 作为第一个参数。

我无法解释为什么你的程序会卡住。示例中的第一个 DNSServiceBrowse() 调用应立即返回并带有错误代码。

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.

赤濁 2024-09-19 16:38:09

虽然是一个老问题,但它应该可以帮助人们现在寻找答案。

vidtige 的答案是不正确的,只要您将“kDNSServiceFlagsShareConnection”标志与参数一起传递,就可以为任何操作共享该答案。下面的示例 -

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

参考 - http://osxr.org/android/源/外部/mdnsresponder/mDNSShared/dns_sd.h#0267

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文