在我的一个 Android 应用程序中,我使用 JmDNS 来支持 Bonjour。启动时,我为 NetworkInterface 中的每个 InetAddress 创建一个 JmDNS 实例。所以代码看起来像:
for(InetAddress addr : addresses) {
JmDNS jmdns = JmDNS.create(addr, "SomeName");
}
到目前为止效果很好,通过对 v4 和 v6 地址执行此操作,我可以从其他客户端(例如在 iOS 上)正确查看所有内容。
但是,对于 IPv6,一个网络适配器实际上可以与多个 v6 地址相关联。因此,例如,我的一位 beta 测试人员向我发送了一份“错误报告”,其中包含以下网络设置(我更改了一些数字以防止信息泄露 - 希望它不会改变含义):
- ip: /fe80::b4a:8eff:fe91:b1bb%mlan0
isLoopBack: false
isLinkLocal: true
isAnyLocal: false
isSiteLocal: false
- ip: /1234:d000:1234:d1:b4a:8eff:fe91:b1bb
isLoopBack: false
isLinkLocal: false
isAnyLocal: false
isSiteLocal: false
- ip: /10.0.1.5
isLoopBack: false
isLinkLocal: false
isAnyLocal: false
isSiteLocal: true
查看该输出,看起来这两个 IPv6 地址实际上非常相似,可能一个是本地链接,而另一个不是。阅读Wikipedia 上的文章,我了解到在 IPv6 中,所有接口实际上也必须有一个本地链接地址。
但是,我对这两者中的哪一个实际用于我的 JmDNS 注册感到困惑。如果我同时注册两者,我会得到一个恒定的日志流,上面写着:
收到来自我们自己的冲突探测:[x@123456789 类型:TYPE_SRV 索引 33,类:CLASS_IN 索引 1,名称:something._tcp.local。ttl:'3599/3600' 服务器:'SomeName.local.:5000']
那么我应该使用哪一个?是否有一些通用规则来决定注册组中的哪些地址?