我想你需要遍历所有的地址,还要检查广播地址是否为空.
考虑到您可能会拥有您不期望分配给该接口的地址.在我的Linux系统上,使用你的代码,我看到的第一个地址是一个IPv6地址,具有空广播(因为没有像IPv6广播这样的东西 – 尽管可以使用组播实现相同的效果).
您需要完全删除第1路代码段.当你继续你会去下一个界面,而不是考虑有两个地址的可能性.
您总是希望迭代所有可以播放的地址的另一个原因是因为您需要考虑到可能在分配给接口的两个网络上具有地址.例如,您可能有一个分配了192.168.0.1/24和172.16.0.1/24的接口.
另外,请考虑使用Set来存储广播地址以防止在同一子网上分配两个地址的情况.
最后,由于使用广播地址将限制您仅对具有同一子网中IP地址的主机进行通话,您可能会错过使用相同子网/网络掩码配置不正确的主机.所以你可能想考虑为此使用组播;您可以使用IPv4(或IPv6)所有节点组播地址来访问子网上的所有主机,而不管配置的地址如何. (分别为224.0.0.1和FF01 :: 1)
编辑:您还有第二种方式的错误,与您使用迭代器有关.由于您每次在for循环中获得一个新的.iterator(),所以幸运的是这里没有无限循环.我把你的代码改成了这个,它适用于我:
$cat Broadcasts.java
import java.net.*;
import java.util.*;
public class Broadcasts
{
public static void main(String[] args)
{
HashSet listOfBroadcasts = new HashSet();
Enumeration list;
try {
list = NetworkInterface.getNetworkInterfaces();
while(list.hasMoreElements()) {
NetworkInterface iface = (NetworkInterface) list.nextElement();
if(iface == null) continue;
if(!iface.isLoopback() && iface.isUp()) {
//System.out.println("Found non-loopback, up interface:" + iface);
Iterator it = iface.getInterfaceAddresses().iterator();
while (it.hasNext()) {
InterfaceAddress address = (InterfaceAddress) it.next();
//System.out.println("Found address: " + address);
if(address == null) continue;
InetAddress broadcast = address.getBroadcast();
if(broadcast != null)
{
System.out.println("Found broadcast: " + broadcast);
listOfBroadcasts.add(broadcast);
}
}
}
}
} catch (SocketException ex) {
System.err.println("Error while getting network interfaces");
ex.printStackTrace();
}
// return listOfBroadcasts;
}
}
可能遇到的另一个问题是try / catch基本上是整个函数,这将导致此代码停止,如果它发生意外事件.最好用try / catch来围绕可能的故障点,并做一些理智的事情(比如跳过接口或地址),但是我没有看到哪些方法可以抛出异常.
编辑2:我误读你的代码你的迭代器很好. ;-)这个问题(我之前提到的)是你的第一种方式是短路你的第二种方式;因为它击中了继续;语句,如果第一个地址为空,你甚至不试图循环遍历它们.
无论如何,如果你仍然遇到问题,请运行这些println语句并发布结果.
编辑3:好的,我放弃了;-)根据你发布的输出,看起来你正在NetworkInterface类中遇到一个bug.
我不知道是否有帮助关闭preferIPv4Stack选项,但您应该测试.我搜索了一些描述这种行为的bug报告,找不到任何内容.
由于你在Linux上,所以你总是可以采取后退的方式来执行shelling,并调用如下命令:
/sbin/ip addr | perl -ne 'print "$1\n" if $_ =~ /inet.* brd ([0-9\.]*)/'
…应该向您发送广播地址列表.
编辑4:我刚刚注意到JavaDoc为NetworkInterface有一个getSubInterfaces()调用.也许你需要调用这个,以确保你得到所有的地址? (它可能有助于发布/ sbin / ip addr和/ sbin / ifconfig的输出)
编辑5:关于刚刚的赏金. (这个问题是一年多了!)有人可以在上面的答案中运行代码(编辑以使其易于复制/粘贴/运行)并告诉我它是否可行?如果没有,请编辑问题并记下确切的错误/问题.