2015-06-19 158 views
1

我正在编写一个Java程序,该程序将显示连接到我的Wifi网络的设备的名称和IP地址。加速查找连接到Wifi网络的设备并获取设备名称

我想出了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"); 
     } 
    } 
} 

此代码的工作原理,它显示连接的设备的IP地址。
但也有我面临两个问题:

  1. 我不能获得连接设备的名称。我只能得到IP地址。
  2. 这个程序工作起来非常慢。完成需要254秒。

那么,如何显示连接设备的名称,并有什么方法来加快这个程序?

任何帮助表示赞赏!

+2

您假定您的网络是一个/ 24网络。可能有超过254个节点连接到您的WiFi网络,具体取决于子网掩码。 – RealSkeptic

+0

BruceWayne的建议是获取设备名称吗? – afzalex

+0

@afzalex没有。它没有工作。你知道一种获取设备名称的方法吗?请帮助我! –

回答

2

这个程序工作起来非常慢。完成需要254秒。

我想我知道为什么。从InetAddress documentation

public boolean isReachable(int timeout) 
       throws IOException 

的超时值,以毫秒为单位,表示时间的尝试应该采取的最高金额。如果操作在获得答案之前超时,主机将被视为无法访问。负值将导致抛出IllegalArgumentException。

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

+0

谢谢!我将超时值从1000减少到100,从254减少到20,现在它运行得非常快!你能帮我拿到设备的名字吗? –

+0

@ChinmayDabke,我会认为['getHostName()'](http://docs.oracle.com/javase/7/docs/api/java/net/InetAddress.html#getHostName())或[' getCanonicalHostName()'](http://docs.oracle.com/javase/7/docs/api/java/net/InetAddress.html#getCanonicalHostName())会做到这一点。 –

+0

我尝试了两个建议。他们都没有工作。它只是再次向我显示了IP地址,而不是设备的名称。请帮助我! –

2

降低超时值是加快发现过程的一种方式,但是Java 8并行流会降低发现过程。通过并行流,您可以并行发现远程网络设备,而不是顺序发现,而其顺序过程可以节省您的时间。

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

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

正如你可以看到,使用并行流使尽可能处理时间相当显著的差异。

至于名字被再次IP地址,请参阅InetAddress Documentation特别

enter image description here

0

嗨也许是来不及把答案放在我一个解决方案寻找同样的问题,也许我的答案将是我认为扫描仪程序用于加快搜索 多线程其他 有用的,它是真正有效的是我的代码

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

    } 

} 



} 

也许这对于生成253个线程是有害的,但是将它们分解为多个线程(比如每个线程中的每个线程都有10个线程),它将有效加速进程