简体   繁体   English

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

[英]Speed up finding devices connected to a Wifi network and get device name

I'm writing a Java program that will show the names and IP addresses of the devices connected to my Wifi network. 我正在编写一个Java程序,该程序将显示连接到Wifi网络的设备的名称和IP地址。

I've figured out the IP address part. 我已经弄清楚了IP地址部分。 Here's the code : 这是代码:

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");
        }
    }
}

This code works and it shows the IP addresses of the connected devices. 该代码有效,并且显示了所连接设备的IP地址。
But there are two problems that I'm facing: 但是我面临两个问题:

  1. I'm not able to get the connected device's name. 我无法获取连接设备的名称。 I can only get the IP address. 我只能获取IP地址。
  2. This program works really slow. 该程序的运行速度非常慢。 It takes 254 seconds to complete. 这需要254秒才能完成。

So how do I display the name of the connected devices and is there any way to speed this program up? 那么,如何显示所连接设备的名称,有什么方法可以加快此程序的速度?

Any help is appreciated! 任何帮助表示赞赏!

Lowering the timeout value is one way to speed up the discovery process, but with Java 8 came parallel streams. 降低超时值是加快发现过程的一种方法,但是Java 8带来了并行流。 With parallel streams you can discover remote network devices in parallel rather than sequential, and its the sequential process that eats up your time. 使用并行流,您可以并行而不是顺序地发现远程网络设备,而顺序过程会占用您的时间。

Here's how I would try using parallel streams to discover network devices. 这是我尝试使用并行流发现网络设备的方法。

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);
    }
}

Results: 结果:

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

As you can see, using parallel streams make a pretty significant difference as far as processing time. 如您所见,使用并行流在处理时间方面有很大的不同。

As far as the name being the IP address again, see InetAddress Documentation particularly 至于名称再次是IP地址,请特别参阅InetAddress文档

在此处输入图片说明

This program works really slow. 该程序的运行速度非常慢。 It takes 254 seconds to complete. 这需要254秒才能完成。

I think I know why. 我想我知道为什么。 From the InetAddress documentation : InetAddress文档中

public boolean isReachable(int timeout)
                throws IOException

The timeout value, in milliseconds, indicates the maximum amount of time the try should take . 超时值(以毫秒为单位)表示尝试应花费最长时间 If the operation times out before getting an answer, the host is deemed unreachable. 如果操作在获得答案之前超时,则认为主机不可访问。 A negative value will result in an IllegalArgumentException being thrown. 负值将导致抛出IllegalArgumentException。

Therein lies your problem. 这就是你的问题。 If you allocate a second as your timeout value, your program will take 254 seconds to complete if all hosts were unreachable. 如果您将秒数指定为timeout值,则如果所有主机均无法访问,则程序将需要254秒才能完成。 Try reducing it. 尝试减少它。

Hi Maybe it's too late to put an answer put I was searching on a solution for the same problem and maybe my answer would be useful for other I think that the scanners program use the multi threading for speed up the search and it's really effective that's my code 嗨,也许现在把答案放在我正在寻找相同问题的解决方案的位置上为时已晚,也许我的答案将对其他人有用,我认为扫描仪程序使用多线程来加快搜索速度,这真的很有效码

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();

    }

}



}

maybe it's harmful to generate 253 thread but splitting them to multi threads like each 10 of them in one thread it will effectively speed up the process 生成253个线程可能有害,但是将它们分成多个线程,例如将每个线程分成10个线程,这将有效地加快进程

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM