.NET 基于 mDNS 服务发现和注册
新建一个 .NET 的项目,使用 nuget 命令引用如下包
服务注册
mDNS 查询过程
通过分析抓包数据,mDNS 协议在局域网内的 IP 地址查询过程大致是这样的:
A:发起查询的主机
B:被查询的主机
A,B 在加入网络时都会发 IGMP 报文加入组 224.0.0.251;向组播路由器宣告要成为 224.0.0.251组播的成员。
A 向组 224.0.0.251 发送 mDNS 组播报文查询 B 的主机名,所有在组内的主机都会收到这个查询请求;
B 向组 224.0.0.251 发送回应 mDNS 报文,内容包括自己的主机名和 IP 地址;
A 得到 B 的 IP 地址。
其中,mDNS 报文是包装在 UDP 组播报文中的,使用 5353 端口。
https://blog.beanbang.cn/2019/08/07/locate-hosts-using-mdns/
一段 mDNS 报文的内容:
Multicast Domain Name System (response)
[Request In: 172]
[Time: 0.205589000 seconds]
Transaction ID: 0x0000
Flags: 0x8400 Standard query response, No error
Questions: 0
Answer RRs: 4
Authority RRs: 0
Additional RRs: 0
Answers
9.c.4.3.e.b.a.3.5.6.5.3.2.8.e.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.e.f.ip6.arpa: type PTR, class IN, cache flush, raspberrypi.local
raspberrypi.local: type A, class IN, cache flush, addr 192.168.10.108
108.10.168.192.in-addr.arpa: type PTR, class IN, cache flush, raspberrypi.local
raspberrypi.local: type AAAA, class IN, cache flush, addr fe80::e82:3565:3abe:34c9
源地址是 192.168.10.108,目标地址是 224.0.0.251。 返回的记录中有树莓派的 IPv4 和 IPv6 地址,以及一个相同的字段 raspberrypi.local。
raspberrypi.local 就是树莓派的域名
mDNS工作原理
首先,在 IP 协议里规定了一些保留地址,其中有一个是 224.0.0.251,对应的 IPv6 地址是 [FF02::FB]。
mDNS 协议规定了一个端口,5353。
mDNS 基于 UDP 协议。
每个进入局域网的主机,如果开启了mDNS服务的话,都会向局域网内的所有主机组播一个消息,我是谁,和我的IP地址是多少。然后其他也有该服务的主机就会响应,也会告诉你,它是谁,它的IP地址是多少。
智能终端设备注册,主要分为两部分
var sd = new ServiceDiscovery();
//发布一个服务,服务名称是有讲究的,一般都是_开头的,可以找一下相关资料
var p = new ServiceProfile("ipfs1", "_ipfs-discovery._udp", 5010);
p.AddProperty("connstr", "Server");
//必须要设置这一项,否则不解析TXT记录
sd.AnswersContainsAdditionalRecords = true;
sd.Advertise(p);
//sd.Announce(p);
Console.ReadKey();
sd.Unadvertise();
创建一个ServiceInfo 实例
var p = new ServiceProfile("ipfs1", "_ipfs-discovery._udp", 5010);
将刚刚创建的ServerInfo进行注册
并进行广播
sd.Advertise(p);
How to discover ESP32 service over mDNS
https://iotespresso.com/how-to-discover-esp32-service-over-mdns/
举个例子:
A 主机进入局域网,开启了 mDNS 服务,并向 mDNS 服务注册以下信息:我提供 TCP 服务,我的 IP 是 192.168.1.101,端口是 9504。
当 B 主机进入局域网,并向 B 主机的 mDNS 服务请求,我要找局域网内 TCP 服务器,B主机的 mDNS 就会去局域网内向其他的 mDNS 询问,并且最终告诉你,有一个IP地址为 192.168.1.101,端口号是 9504 的主机,也就是 A 主机提供 TCP 服务,所以 B 主机就知道了 A 主机的 IP 地址和端口号了。
https://www.cnblogs.com/Taurus12C/p/mDNS.html
mDNS的工作原理如下:
当一个设备想要解析一个主机名时,它将会在本地网络中广播一个mDNS请求,请求包含了想要解析的主机名。
所有收到请求的设备都会检查他们是否对应请求中的主机名。如果一个设备发现它对应了请求中的主机名,它就会响应请求,回复它的IP地址。
请求发起设备收到回复后,就知道了对应主机名的设备的IP地址,然后就可以直接和那个设备通信了。
mDNS主要用在小型网络中,例如家庭网络,或者是单个办公室的网络。在这些网络中,设备的数量不多,而且设备之间又经常需要通信,所以mDNS非常适用。在这些网络中使用mDNS,可以让设备在没有中央站点分配名称的情况下互相发现和通信,大大简化了网络配置。
QU:单播
QM:多播
A 记录:主机名称和IPV4之间的对应关系。
AAAA 记录:主机名称和IPV6之间的对应关系。
SRV 记录:标识服务实例名称对应哪一个主机名和端口号。
PTR 记录:标识服务实例名称和服务类型之间的对应关系,一般在查询具有相同服务类型的实例时使用。
TXT 记录:对某个服务实例提供的附加信息按照key/value形式给出。
ANY 记录:任意类型,一般用于查询中。
有一种 DNS 记录类型叫 SRV记录(Service Record,服务定位记录),它用来记录服务器提供的服务,即识别服务的 IP 和端口
blog
https://www.itsvse.com/thread-10047-1-1.html
https://zhuanlan.zhihu.com/p/255273790
project
https://github.com/richardschneider/net-mdns
https://blog.csdn.net/u010927489/article/details/121852900