我有一个使用 MFC 构建的应用程序,我需要将 Bonjour/Zeroconf 服务发现添加到其中。我在弄清楚如何最好地做到这一点时遇到了一些麻烦,但我决定使用 mDNSresponder 源代码中提供的 DLL 存根并将我的应用程序链接到由它生成的静态库(反过来使用系统dnssd.dll)。
但是,我仍然遇到问题,因为回调似乎并不总是被调用,所以我的设备发现停止了。让我感到困惑的是,在 OSX 下,使用 OSX dns-sd 终端服务和在 Windows 下使用 dns-sd 命令行服务,这一切都可以正常工作。在此基础上,我排除了客户端服务的问题,并试图找出我的 Windows 代码出了什么问题。
我基本上是在调用 DNSBrowseService(),然后在该回调中调用 DNSServiceResolve(),最后调用 DNSServiceGetAddrInfo() 来获取设备的 IP 地址,以便我可以连接到它。
所有这些调用都基于使用 WSAAsyncSelect,如下所示:
DNSServiceErrorType err = DNSServiceResolve(&client,kDNSServiceFlagsWakeOnResolve,
interfaceIndex,
serviceName,
regtype,
replyDomain,
ResolveInstance,
context);
if(err == 0)
{
err = WSAAsyncSelect((SOCKET) DNSServiceRefSockFD(client), p->m_hWnd, MESSAGE_HANDLE_MDNS_EVENT, FD_READ|FD_CLOSE);
}
但有时即使服务在那里,回调也不会被调用,并且使用命令行会确认这一点。
我完全不知道为什么这不是 100% 可靠,但如果我在命令行中使用相同的 DLL,那就是这样。我唯一可能的解释是,DNSServiceResolve 函数尝试在 WSAAsyncSelect 为套接字注册处理消息之前调用回调函数,但我看不到任何解决方法。
我在这上面花了很长时间,现在完全没有想法了。任何建议都会受到欢迎,即使它们是“这是一种非常愚蠢的方法,你为什么不做 X、Y、Z”。