Windows下mDNS查询API—DnsStartMulticastQuery/DnsStopMulticastQuery的使 ...

打印 上一主题 下一主题

主题 862|帖子 862|积分 2601

背景及问题:

目前很多局域网设备通过mNDS协议实现互联,IP地址为自动IP段-169.254.x.x,有时候设备厂家提供的API需要通过知晓局域网中的IP地址/设备名,才能连接该设备。这样要求每个软件必须配置设备名或者启动时遍历所有IP(6w+),不是很方便,这时候可以通过mDNS查询,自动拿到设备名,再进行连接,相对便捷,高效。
解决办法:

在Win10 版本中,windows提供了mDNS查询的API-DnsStartMulticastQuery,官方定义如下:

其中PMDNS_QUERY_REQUEST定义为

其中各字段定义如下:
Version必须 DNS_QUERY_REQUEST_VERSION1结构版本
ulRefCount保留。 请勿使用。
Query表示要通过 mDNS 查询的名称的字符串。
QueryType一个值,该值表示要查询的记录的类型。有关可能的值,请参阅DNS_RECORD_TYPE 。
QueryOptions一个表示查询选项的 值。 DNS_QUERY_STANDARD 是唯一支持的值。
InterfaceIndex一个 值,该值包含要播发服务的接口索引。 如果 InterfaceIndex 为 0,则将考虑所有接口。
pQueryCallback指向类型为 MDNS_QUERY_CALLBACK) 的函数 (的指针,该函数表示每当 mDNS 结果可用时要异步调用的回调
pQueryContext指向用户上下文的指针。
fAnswerReceived保留。 请勿使用。
ulResendCount保留。 请勿使用
 
需要注意的是:
Query是所查询的字符串, pQueryCallback是查询等到回复的回调函数,定义如下:

其中PDNS_QUERY_RESULT含有查询结果DNS_RECORD ,对该结构体进行解析可以得到结果。拿到结果之后需要使用 DnsRecordListFree 函数释放空间。
示例程序:
  1. #include<Windows.h>
  2. #include"mdns.h"
  3. #pragma comment(lib, "dnsapi.lib")
  4. VOID WINAPI multicastQueryCallback(PVOID pQueryContext, PMDNS_QUERY_HANDLE pQueryHandle, PDNS_QUERY_RESULT pQueryResults)
  5. {
  6. //pQueryResults为返回结果,对其中的pQueryRecords进行解析
  7. if (pQueryResults->pQueryRecords)
  8. {
  9. //解析查询结果
  10. // 释放空间
  11. dnsRecordListFree(pQueryResults->pQueryRecords,DnsFreeRecordList)
  12. )
  13. }
  14. void GetQueryResponse(const wchar_t* queryName)
  15. {
  16. MDNS_QUERY_HANDLE h1;
  17. MDNS_QUERY_REQUEST r1;
  18. int context = 222;
  19. r1.Version = DNS_QUERY_REQUEST_VERSION1;
  20. r1.QueryOptions = DNS_QUERY_STANDARD;
  21. r1.QueryType = DNS_TYPE_PTR;
  22. r1.Query = queryName;
  23. r1.pQueryContext = (PVOID)context;
  24. r1.InterfaceIndex = 0;
  25. r1.pQueryCallback = multicastQueryCallback;
  26. DnsStartMulticastQuery(&r1, &h1);
  27. Sleep(100);
  28. DnsStopMulticastQuery(&h1);
  29. }
复制代码
 

需要注意的是:


  • 目前该API似乎不是很稳定, Release/X64,双字节字符串(VS字符集需设置为Unicode)平台下使用没有问题
  • 此方法为异步查询,如果不使用DnsStopMulticastQuery结束查询,则查询字符串会一直发送,回调函数会被一直调用。
  • pQueryContext可以用来存储查询结果(示例中没有使用)
  • QueryOptions设为DNS_QUERY_BYPASS_CACHE可以绕过缓存查询,每次查询最新的结果
  • 同样的Release/X64平台, DnsQuery API也可以查询,且支持单双字符串,但是DNS_QUERY_BYPASS_CACHE不起作用;同步查询,有1s左右延时
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

大连全瓷种植牙齿制作中心

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表