将 Java 版本从 12 更新到 15 后,此代码现在在 Windows 上抛出一个相当非描述性SocketException
的内容,但前提是 IPv6 在以下位置禁用NetworkInterface
:
NetworkInterface networkInterface = NetworkInterface.getByInetAddress(InetAddress.getLocalHost());
DatagramSocket socket = new MulticastSocket(65533);
((MulticastSocket) socket).setTimeToLive(128);
((MulticastSocket) socket).setNetworkInterface(networkInterface); // <-- Exception thrown here
这是一个例外:
java.net.SocketException: Invalid argument: no further information
at java.base/sun.nio.ch.Net.setInterface6(Native Method)
at java.base/sun.nio.ch.DatagramChannelImpl.setOption(DatagramChannelImpl.java:364)
at java.base/sun.nio.ch.DatagramSocketAdaptor.setOption(DatagramSocketAdaptor.java:418)
at java.base/sun.nio.ch.DatagramSocketAdaptor.setNetworkInterface(DatagramSocketAdaptor.java:600)
at java.base/java.net.MulticastSocket.setNetworkInterface(MulticastSocket.java:466)
...
但是,如果我这样创建Socket
,则不会引发异常:
NetworkInterface networkInterface = NetworkInterface.getByInetAddress(InetAddress.getLocalHost());
DatagramSocket socket = new MulticastSocket(
new InetSocketAddress(Collections.list(networkInterface.getInetAddresses()).get(0), 65533));
((MulticastSocket) socket).setTimeToLive(128);
((MulticastSocket) socket).setNetworkInterface(networkInterface); // <-- No exception is thrown
这是预期/预期的行为吗?如果是这样,这是否记录在某处?
这个测试脚本...
System.out.println("Example 1");
try {
NetworkInterface netIf1 = NetworkInterface.getByInetAddress(InetAddress.getLocalHost());
System.out.println(netIf1 + " " + Collections.list(netIf1.getInetAddresses()).get(0));
DatagramSocket sock1 = new MulticastSocket(65533);
((MulticastSocket) sock1).setTimeToLive(128);
((MulticastSocket) sock1).setNetworkInterface(netIf1);
System.out.println("Success");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Example 2");
try {
NetworkInterface netIf2 = NetworkInterface.getByInetAddress(InetAddress.getLocalHost());
System.out.println(netIf2 + " " + Collections.list(netIf2.getInetAddresses()).get(0));
DatagramSocket sock2 = new MulticastSocket(new InetSocketAddress(Collections.list(netIf2.getInetAddresses()).get(0), 65533));
((MulticastSocket) sock2).setTimeToLive(128);
((MulticastSocket) sock2).setNetworkInterface(netIf2);
System.out.println("Success");
} catch (Exception e) {
e.printStackTrace();
}
...将以下语句打印到控制台:
Example 1
name:eth8 (Intel(R) Ethernet Connection (7) I219-LM) /10.240.10.193
java.net.SocketException: Invalid argument: no further information
at java.base/sun.nio.ch.Net.setInterface6(Native Method)
at java.base/sun.nio.ch.DatagramChannelImpl.setOption(DatagramChannelImpl.java:364)
at java.base/sun.nio.ch.DatagramSocketAdaptor.setOption(DatagramSocketAdaptor.java:418)
at java.base/sun.nio.ch.DatagramSocketAdaptor.setNetworkInterface(DatagramSocketAdaptor.java:600)
at java.base/java.net.MulticastSocket.setNetworkInterface(MulticastSocket.java:466)
at com.example.MyApplication.createSocket(MyApplication.java:32)
Example 2
name:eth8 (Intel(R) Ethernet Connection (7) I219-LM) /10.240.10.193
Success