我一直有问题试图让JmDNS在Mac OS X上工作。症状是我可以发现网络上的任何服务,除了我的自己的电脑。无论他们是在本地主机还是在我的计算机上运行的虚拟机上 - 无论是哪种情况,他们都不会从list
调用回来。JmDNS在Mac OS X上似乎没有任何作用
我设法将我们正在做的事情压缩到在Windows上传递但在Mac OS X上失败的测试。现在问题是我无法弄清楚问题出在哪里。
@Test
public void testAdvertisingOverLoopback() throws Exception
{
// happens on any address but loopback is the strangest
InetAddress address = InetAddress.getLoopbackAddress();
String type = "_test._tcp.local.";
String name = "test-service";
int port = 9999;
Map<String, String> properties = ImmutableMap.of("key", "value");
// simulate the service starting up. issue also occurs in separate VMs
try (JmDNS serviceDns = JmDNS.create(address))
{
serviceDns.registerService(ServiceInfo.create(type, name, port,
0, 0, properties));
try (JmDNS clientDns = JmDNS.create(address))
{
ServiceInfo[] services = clientDns.list(type);
// One of the entries should:
assertThat(services, is(arrayContaining(allOf(
// Contain an address which matches the one we advertised (culling those which might
// be registered by other tests which happen to run at the same time.)
hasProperty("inetAddresses", arrayContaining(sameAddressAs(address))),
// Match the parameters we specified in the call to list.
hasProperty("application", equalTo("test")),
hasProperty("protocol", equalTo("tcp")),
hasProperty("domain", equalTo("local")),
// Match the info we advertised.
hasProperty("port", equalTo(9999)),
hasCustomProperty("key", "value")
))));
}
}
}
private static Matcher<InetAddress> sameAddressAs(final InetAddress address)
{
return new TypeSafeMatcher<InetAddress>()
{
@Override
protected boolean matchesSafely(InetAddress inetAddress)
{
return Arrays.equals(address.getAddress(), inetAddress.getAddress());
}
@Override
public void describeTo(Description description)
{
description.appendText("same address as ");
description.appendValue(address.getHostAddress());
}
};
}
private static Matcher<ServiceInfo> hasCustomProperty(final String key,
final String value)
{
return new TypeSafeMatcher<ServiceInfo>()
{
@Override
protected boolean matchesSafely(ServiceInfo serviceInfo)
{
return value.equals(serviceInfo.getPropertyString(key));
}
@Override
public void describeTo(Description description)
{
description.appendText("has custom mDNS property ");
description.appendValue(key);
description.appendText(" = ");
description.appendValue(value);
}
};
}
在调试器中,我可以看到它没有将套接字绑定到任何特定的地址,只是一个特定的端口。但是,它将其设置为特定的界面。
我在Wireshark中看到的是,数据包从我机器的公共IP(en0的地址)出来,即使lo0是我用于测试的接口。我也看到了查询和响应数据包。 的回复是回来。
但是在Java方面,我看到它叫DatagramSocket#receive(DatagramPacket)
,从来没有得到一个数据包。 (我也花了半天的时间寻找JmDNS的替代品,但它看起来像声称替换它的其他库不能真正实现多播,这使得它们有点没有意义:()
这到底是怎么回事呢?
“对于Windows,这可以正常工作,因为永远不会有另一个zeroconf守护进程在运行。”显然现在不再与Windows 10:https://www.slightfuture.com/technote/windows-mdns-dnssd – Grodriguez
阅读您的答案,我试图禁用mDNS守护进程根据:http://www.dgkapps.com/博客/ osx-tips/osx-tips-turn-off-disable-bonjour-from-the-command-line /并玩弄配置。虽然deamons似乎已经关闭('ps aux | grep mDNS'),但它们似乎仍然会干扰jmDNS库 - 任何想法? – Wingo
我完全采取了另一种方式 - 禁用jMDNS for macOS,并使用系统API来注册我的记录。 – Trejkaz