2015-06-19 198 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個線程),它將有效加速進程