Java 加快查找连接到Wifi网络的设备并获取设备名称

Java 加快查找连接到Wifi网络的设备并获取设备名称,java,networking,network-programming,Java,Networking,Network Programming,我正在编写一个Java程序,它将显示连接到我的Wifi网络的设备的名称和IP地址 我已经计算出IP地址部分。代码如下: public static void main(String[] args) throws IOException { InetAddress localhost = InetAddress.getLocalHost(); // this code assumes IPv4 is used byte[] ip = localhost.getAddr

我正在编写一个Java程序,它将显示连接到我的Wifi网络的设备的名称和IP地址

我已经计算出IP地址部分。代码如下:

public static void main(String[] args) throws IOException {
    InetAddress localhost = InetAddress.getLocalHost();
    // this code assumes IPv4 is used   
    byte[] ip = localhost.getAddress();
    for (int i = 1; i <= 254; i++) {
        ip[3] = (byte) i;
        InetAddress address = InetAddress.getByAddress(ip);
        if (address.isReachable(1000)) {
            // machine is turned on and can be pinged
            System.out.println(address + "is online");
        } else if (!address.getHostAddress().equals(address.getHostName())) {
            // machine is known in a DNS lookup
            System.out.println(address + "is in a DNS lookup");
        } else {
            // the host address and host name are equal, meaning the host name could not be resolved
            System.out.println(address + " is not online");
        }
    }
}
publicstaticvoidmain(字符串[]args)引发IOException{
InetAddress localhost=InetAddress.getLocalHost();
//此代码假定使用了IPv4
字节[]ip=localhost.getAddress();
对于(int i=1;i
这个程序运行非常慢,需要254秒才能完成

我想我知道原因了。从以下方面:

超时值(以毫秒为单位)表示尝试应花费的最大时间量。如果在获得答案之前操作超时,则主机被视为无法访问。负值将导致引发非法galargumentException


这就是你的问题所在。如果你分配一秒作为你的
超时值,那么如果所有主机都无法访问,你的程序将需要254秒才能完成。试着减少它。

降低超时值是加快发现过程的一种方法,但是Java 8带来了并行流。使用并行流,你可以发现远程e网络设备是并行的,而不是顺序的,而顺序的过程会占用你的时间

下面是我将如何尝试使用并行流来发现网络设备

public static void main(String[] args) throws Exception {
    byte[] localHostIp = InetAddress.getLocalHost().getAddress();
    List<DiscoverNetworkDevice> networkDevices = new ArrayList();
    for (int i = 1; i < 255; i++) {
        // Assuming IPV4
        localHostIp[3] = (byte) i;
        networkDevices.add(new DiscoverNetworkDevice(
                InetAddress.getByAddress(localHostIp).getHostAddress()));
    }

    discover(networkDevices);
    parallelDiscover(networkDevices);
}

public static void discover(List<DiscoverNetworkDevice> networkDevices) {
    long start = System.currentTimeMillis();

    Object[] discoveredDevices = networkDevices
            .stream()
            .filter(nd -> nd.Discover()).toArray();
    for (Object obj : discoveredDevices) {
        System.out.println(obj);
    }

    long end = System.currentTimeMillis();
    System.out.println("Elapsed: " + (end - start));
    System.out.println();
}

public static void parallelDiscover(List<DiscoverNetworkDevice> networkDevices) {
    long start = System.currentTimeMillis();

    Object[] discoveredDevices = networkDevices
            .parallelStream()
            .filter(nd -> nd.Discover()).toArray();
    for (Object obj : discoveredDevices) {
        System.out.println(obj);
    }

    long end = System.currentTimeMillis();
    System.out.println("Elapsed: " + (end - start));
    System.out.println();
}

public static class DiscoverNetworkDevice {
    private String hostIp;
    private String hostName;

    public DiscoverNetworkDevice(String hostIp) {
        this.hostIp = hostIp;
    }

    public boolean Discover() {
        try {
            InetAddress host = InetAddress.getByName(hostIp);
            if (host.isReachable(500)) {
                hostName = host.getHostName();
                return true;
            }
        } catch (IOException ioe) {
        }
        return false;
    }

    @Override
    public String toString() {
        return String.format("IP: %s \t Name: %s", hostIp, hostName);
    }
}
正如您所看到的,使用并行流在处理时间方面有很大的不同

至于名称是IP地址,请参见


嗨,也许现在给出答案已经太晚了。我正在寻找解决同一问题的方法,也许我的答案对其他人有用 我认为扫描器程序使用多线程来加速搜索 这真的很有效这是我的代码

public class NetLimiter {

public interface DiscoverDeviceEeventListener extends EventListener {
    public void discovered(Device device);
    public void failed(Device device);
}

DiscoverDeviceEeventListener discoverDeviceEventHandler = null;

public void setDiscoverDeviceEvent(DiscoverDeviceEeventListener handler) {
    this.discoverDeviceEventHandler = handler;
}

public class Device {

    private String hostIp;
    private String hostName;

    public Device(String hostIp) {

        this.hostIp = hostIp;
        EventListenerList l = new EventListenerList();

    }

    public boolean discover() {
        try {
            InetAddress host = InetAddress.getByName(hostIp);
            if (host.isReachable(1000)) {
                hostName = host.getHostName();
                if (discoverDeviceEventHandler != null) {
                    discoverDeviceEventHandler.discovered(this);
                }
                return true;
            } else if (discoverDeviceEventHandler != null) {
                discoverDeviceEventHandler.failed(this);
            }
        } catch (IOException ioe) {
            System.out.print(ioe);
        }
        return false;
    }

    @Override
    public String toString() {
        return String.format("IP: %s \t Name: %s", hostIp, hostName);
    }
}

String subnet = "";

public NetLimiter(String subnet) {
    this.subnet = subnet;
}

public void checkDevices() {

    for (int i = 1; i < 255; i++) {
        String host = subnet + "." + i;
        (new Thread(){
            @Override
            public void run(){
                     (new Device(host)).discover();
            }
        }).start();

    }

}



}
公共类网络限制器{
公共接口DiscoverDeviceEventListener扩展了EventListener{
发现公共空间(设备);
公共作废失败(设备);
}
DiscoverDeviceEventListener discoverDeviceEventHandler=null;
public void setDiscoverDeviceEvent(DiscoverDeviceEventListener处理程序){
this.discoverDeviceEventHandler=handler;
}
公共类设备{
私有字符串主机IP;
私有字符串主机名;
公用设备(字符串主机IP){
this.hostIp=hostIp;
EventListenerList l=新的EventListenerList();
}
公共布尔发现(){
试一试{
InetAddress主机=InetAddress.getByName(主机IP);
if(主机可更换(1000)){
hostName=host.getHostName();
if(discoverDeviceEventHandler!=null){
discoverDeviceEventHandler.discovered(此);
}
返回true;
}else if(discoverDeviceEventHandler!=null){
discoverDeviceEventHandler.failed(此);
}
}捕获(ioe异常ioe){
系统输出打印(ioe);
}
返回false;
}
@凌驾
公共字符串toString(){
返回String.format(“IP:%s\t名称:%s”、主机IP、主机名);
}
}
字符串子网=”;
公用网络限制器(字符串子网){
this.subnet=子网;
}
公共无效检查设备(){
对于(int i=1;i<255;i++){
字符串主机=子网+“+i;
(新线程(){
@凌驾
公开募捐{
(新设备(主机)).discover();
}
}).start();
}
}
}

也许生成253个线程是有害的,但将它们拆分为多个线程,就像一个线程中的每10个线程一样,这将有效地加快进程

谢谢!我将超时值从1000减少到100,从254减少到20。它现在运行得非常快!你能帮我找到设备的名称吗?@ChinmayDabke,我想是这样的她或她会这样做。我尝试了两种建议。它们都不起作用。它只是再次向我显示了IP地址,而不是设备的名称。请帮助我!你假设你的网络是a/24网络。可能有超过254个节点连接到你的WiFi网络,具体取决于子网掩码。BruceWayne的建议有效吗获取设备名称?@afzalex-Nope。它不起作用。你知道获取设备名称的方法吗?请帮助我!它只会生成计算为机器最佳的线程数。例如,在我的笔记本电脑上,它将首先运行4个线程来检查4个IP,而不是另外4个、另一个和另一个…总共255个。它将比synchron更快ic操作,尽管它仍然会浪费大量的时间等待(空闲)多次。有没有一种方法可以同时生成和启动所有线程,而不是一次由几个线程“批量等待”?
IP: 192.168.1.1      Name: 192.168.1.1
IP: 192.168.1.121    Name: 192.168.1.121
IP: 192.168.1.137    Name: 192.168.1.137
Elapsed: 126523

IP: 192.168.1.1      Name: 192.168.1.1
IP: 192.168.1.121    Name: 192.168.1.121
IP: 192.168.1.137    Name: 192.168.1.137
Elapsed: 16113
public class NetLimiter {

public interface DiscoverDeviceEeventListener extends EventListener {
    public void discovered(Device device);
    public void failed(Device device);
}

DiscoverDeviceEeventListener discoverDeviceEventHandler = null;

public void setDiscoverDeviceEvent(DiscoverDeviceEeventListener handler) {
    this.discoverDeviceEventHandler = handler;
}

public class Device {

    private String hostIp;
    private String hostName;

    public Device(String hostIp) {

        this.hostIp = hostIp;
        EventListenerList l = new EventListenerList();

    }

    public boolean discover() {
        try {
            InetAddress host = InetAddress.getByName(hostIp);
            if (host.isReachable(1000)) {
                hostName = host.getHostName();
                if (discoverDeviceEventHandler != null) {
                    discoverDeviceEventHandler.discovered(this);
                }
                return true;
            } else if (discoverDeviceEventHandler != null) {
                discoverDeviceEventHandler.failed(this);
            }
        } catch (IOException ioe) {
            System.out.print(ioe);
        }
        return false;
    }

    @Override
    public String toString() {
        return String.format("IP: %s \t Name: %s", hostIp, hostName);
    }
}

String subnet = "";

public NetLimiter(String subnet) {
    this.subnet = subnet;
}

public void checkDevices() {

    for (int i = 1; i < 255; i++) {
        String host = subnet + "." + i;
        (new Thread(){
            @Override
            public void run(){
                     (new Device(host)).discover();
            }
        }).start();

    }

}



}