简体   繁体   中英

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.

I've figured out the IP address part. 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.
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.
  2. This program works really slow. It takes 254 seconds to complete.

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. 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

在此处输入图片说明

This program works really slow. It takes 254 seconds to complete.

I think I know why. From the InetAddress documentation :

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.

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. 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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