使用Ehcache多播获取"无法分配请求的地址"java.net.SocketException

eeb*_*sen 37 java multicast ehcache ipv6 multicastsocket

获取java.net.SocketException试图启动一个多播提供程序时:

2013-09-11 11:45:44,204 [main] ERROR net.sf.ehcache.distribution.MulticastRMICacheManagerPeerProvider: Error starting heartbeat. Error was: Can't assign requested address
java.net.SocketException: Can't assign requested address
at java.net.PlainDatagramSocketImpl.join(Native Method)
at java.net.AbstractPlainDatagramSocketImpl.join(AbstractPlainDatagramSocketImpl.java:178)
at java.net.MulticastSocket.joinGroup(MulticastSocket.java:319)
at net.sf.ehcache.distribution.MulticastKeepaliveHeartbeatReceiver.init(MulticastKeepaliveHeartbeatReceiver.java:88)
at net.sf.ehcache.distribution.MulticastRMICacheManagerPeerProvider.init(MulticastRMICacheManagerPeerProvider.java:95)
Run Code Online (Sandbox Code Playgroud)

eeb*_*sen 93

这是由返回的IPv6地址引起的java.net.NetworkInterface.getDefault().我在Macbook上使用无线 - p2p0(用于AirDrop)作为默认网络接口返回,但我的p2p0只有一个IPv6 ether条目(通过运行找到ipconfig).

两个解决方案,这两个解决方案都适用于我(我更喜欢第一个解决方案,因为无论您使用的是有线连接还是无线连接都可以

  1. 使用启动JVM -Djava.net.preferIPv4Stack=true.这导致java.net.NetworkInterface.getDefault()返回我的vboxnet0网络接口 - 如果您没有运行仅限主机的VM,则不确定将获得什么.
  2. 关闭无线并使用有线连接

  • `java -Djava.net.preferIPv4Stack = true MyProgram` (5认同)
  • 谢谢,直到我厌倦了这个,才能在我的 macbook 上进行多播。 (2认同)
  • 如果使用Maven,请按照以下步骤设置这些属性:http://stackoverflow.com/a/7579853/32453 (2认同)

小智 10

接受的答案略有不同:您还可以在Java代码中添加以下代码行:

System.setProperty("java.net.preferIPv4Stack", "true");
Run Code Online (Sandbox Code Playgroud)

  • 这并不总是有效; 至少在macOS下,"java.net.preferIPv4Stack"-property仅在JVM启动时读取 - 以编程方式设置它无效. (4认同)

Cam*_*gón 7

您需要先向Java VM添加某些配置,然后才能在任何计算机中加入多播套接字.

首先在尝试连接之前添加此行,以确保只获得IPv4地址:

System.setProperty("java.net.preferIPv4Stack", "true");
Run Code Online (Sandbox Code Playgroud)

在大多数情况下,您的计算机有多个网络接口,因此您需要选择正确的网络接口:

Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
while (networkInterfaces.hasMoreElements()) {
    NetworkInterface networkInterface = networkInterfaces.nextElement();
    Enumeration<InetAddress> addressesFromNetworkInterface = networkInterface.getInetAddresses();
    while (addressesFromNetworkInterface.hasMoreElements()) {
        InetAddress inetAddress = addressesFromNetworkInterface.nextElement();
        if (inetAddress.isSiteLocalAddress()
                && !inetAddress.isAnyLocalAddress()
                && !inetAddress.isLinkLocalAddress()
                && !inetAddress.isLoopbackAddress()
                && !inetAddress.isMulticastAddress()) {
            socket.setNetworkInterface(NetworkInterface.getByName(networkInterface.getName()));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)