检测所有可用网络';Java中的广播地址

检测所有可用网络';Java中的广播地址,java,networking,broadcast,Java,Networking,Broadcast,对于我的项目,我希望获得所有可用广播地址的列表,以便我可以广播一个请求,位于未指定网络中其他计算机上的我的其他应用程序将作出响应,为了获得列表,我(现在使用Mike贡献的小修改版本)得出以下结论: private ArrayList<InetAddress> getBroadcastAddresses() { ArrayList<InetAddress> listOfBroadcasts = new ArrayList(); Enumeration

对于我的项目,我希望获得所有可用广播地址的列表,以便我可以广播一个请求,位于未指定网络中其他计算机上的我的其他应用程序将作出响应,为了获得列表,我(现在使用Mike贡献的小修改版本)得出以下结论:


private ArrayList<InetAddress> getBroadcastAddresses() {
        ArrayList<InetAddress> listOfBroadcasts = new ArrayList();
        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) listOfBroadcasts.add(broadcast);
                    }
                }
            }
        } catch (SocketException ex) {
            return new ArrayList<InetAddress>();
        }

        return site;
}

私有ArrayList getBroadcastAddresses(){
ArrayList listOfBroadcasts=新的ArrayList();
枚举表;
试一试{
list=NetworkInterface.getNetworkInterfaces();
while(list.hasMoreElements()){
NetworkInterface iface=(NetworkInterface)list.nextElement();
如果(iface==null)继续;
如果(!iface.isLoopback()&&iface.isUp()){
System.out.println(“发现非环回,up接口:+iface”);
迭代器it=iface.getInterfaceAddresses().Iterator();
while(it.hasNext()){
InterfaceAddress=(InterfaceAddress)it.next();
System.out.println(“找到的地址:“+地址”);
如果(地址==null)继续;
InetAddress广播=address.getBroadcast();
if(broadcast!=null)listOfBroadcasts.add(broadcast);
}
}
}
}捕获(SocketException例外){
返回新的ArrayList();
}
返回站点;
}
它对于普通LAN非常有效,但是当谈到WiFi LAN时,它只是在一步之后跳过第二个while循环,因为
地址
等于null,即使我使用
System.out.println(interfaceItem)
为了查看正在通过的接口,它写下了无线局域网的名称和网络对应的我的IP

编辑1: 是输出,其中172.16.1.104是无线网络中的我的IP。这个问题只出现在我的带有Wifi的笔记本上。输出来自我的笔记本,我主要使用无线,有时使用UTP与我的朋友连接。我的笔记本上还有一个VirtualBox的网络接口

你能告诉我有什么问题吗?谢谢大家!


注意:这可能是我的笔记本电脑的问题,而代码对其他人都有效,我喜欢这种问题:-)对我来说似乎是个死胡同,但无论如何还是要感谢你的帮助:-)

仍然爱你!;-)

我认为您需要遍历所有地址,并另外检查广播地址是否为
null

考虑一下,您可能有一些不希望分配给接口的地址。在我的Linux系统上,使用您的代码,我看到的第一个地址是IPv6地址,带有空广播(因为没有IPv6广播——尽管您可以使用多播来实现相同的效果)

您需要完全删除代码的
1st-way
部分。当您
继续时在那里,您将转到下一个接口,而不是考虑存在两个地址的可能性

<> P>您之所以希望迭代所有可以广播的地址,是因为您需要考虑在分配给接口的两个网络上有地址。例如,您可能有一个分配了
192.168.0.1/24
172.16.0.1/24
的接口

也可以考虑使用<代码> SET>代码>来存储广播地址,以防止您在同一子网上有两个地址。 最后,由于使用广播地址将限制您仅与同一子网中具有IP地址的主机通话,因此您可能会错过未正确配置相同子网/网络掩码的主机。因此,您可能需要考虑为此使用多播;您可以使用(或)所有节点多播地址到达子网上的所有主机,而不管配置的地址如何。(分别为224.0.0.1和FF01::1)

编辑:在第二条路径上也有一个与迭代器使用相关的bug。因为每次在for循环中都会得到一个新的
.iterator()
,所以幸运的是这里没有无限循环。我将您的代码更改为此,它对我有效:

$ cat Broadcasts.java 
import java.net.*;
import java.util.*;

public class Broadcasts
{
    public static void main(String[] args)
    {
        HashSet<InetAddress> listOfBroadcasts = new HashSet<InetAddress>();
        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;
    }
}
。。。它将返回广播地址列表

edit4:我刚刚注意到JavaDoc中有一个
getSubInterfaces()
调用。也许你需要打电话来确定你有所有的地址?(发布
/sbin/ip addr
/sbin/ifconfig
的输出可能会有所帮助)


编辑5:关于刚刚增加的赏金。(这个问题已经有一年多的历史了!)请有人运行我上面答案中的代码(编辑以便于复制/粘贴/运行)并告诉我它是否有效?如果没有,请编辑问题并记下确切的错误/问题。

也许,只迭代一次内环是可以的,因为您的NIC只有一个IP主机地址?我承认,正如您所说,不需要通过InterfaceAddress,因为在那里,如果有的话,应该只有一个,但即使现在也能工作,不是吗?我知道这个例子对你们中的一些人来说不容易测试,因为你们没有WiFi网络来测试它,但这对我来说还是没有意义,为什么它不适用于无线。我想你需要遍历getInterfaceAddresses,您可能会发现它有多个元素,而您感兴趣的元素不是0。如果您看到的是toString()的正确结果,也许可以查看OpenJDK代码,看看它在那里实际做了什么
/sbin/ip addr | perl -ne 'print "$1\n" if $_  =~ /inet.* brd ([0-9\.]*)/'