2011-11-26 115 views
5

我有一個Java/Android應用程序需要發送一些數據到本地網絡上的服務器。問題是服務器的IP地址是動態的,所以找到它的唯一方法是通過它的MAC地址查找。 這在Java中可能嗎?你能看到其他選擇嗎?Java - 通過MAC地址找到主機

+0

修改程序我懷疑我自己一個MAC地址查找將成爲可能,但不能通過主機名進行連接?因此,您可以連接到「www.google.com」,而不是「74.125.237.116」。 –

回答

0

這在Java中可能嗎?

不在純Java中。

沒有將MAC地址直接映射到IP地址的服務。主機操作系統的網絡堆棧使用ARP協議和(在Linux/UNIX上)ARP daemon將IP地址映射到MAC地址。 AFAIK,不可能使用Java的ARP協議。

你可以做的最好的事情是在Linux上運行「arpd -l」作爲外部命令。這會將守護程序的ARP映射轉儲爲您的Java應用程序可以讀取和解析的定義良好的格式。如果您的服務器在本地網絡上處於活動狀態,則其MAC地址將與相應的IP地址一起出現。但是如果它不在本地網絡上,那麼它的ARP廣播將不會到達你的機器,所以守護進程表中將不會有條目。


這將是更好地分配你的服務器的靜態IP地址...和DNS地址。另一種可能性是讓服務器使用Dynamic DNS服務註冊自己。

+0

你可以通過廣播,查詢MAC「NetworkInterface.getHardwareAddress()」並檢查它是否符合標準,即服務器必須是合作的。這是另一個故事,如果Android設備可以實際播出。 – bestsss

+0

@bestsss - 可能無法正常工作。在普通ARP中,您廣播IP地址並獲取MAC地址。除非服務器實現逆向ARP - http://tools.ietf.org/html/rfc2390 - 否則無法請求MAC地址的IP地址。 –

+0

我是指包含MAC作爲有效載荷的常規廣播,並且服務器應該回復廣播,只要它已經在該MAC上啓動(因此是合作的)。只是發現。雖然一個殘酷的方法也可以做到,但只需發送到網絡中的所有IP,如端口掃描器即可。 – bestsss

2

通過MAC地址查找主機只能在您的本地網絡中工作。 Mac地址是IP地址下的一層。基於Mac Adresses的路由不存在於其他網絡中。

廣播/多播

如果你正在尋找一個解決方案,只能在本地網絡,監聽和發送廣播或組播可能是一種選擇你。如果您將數據包發送到廣播地址,本地網絡中的每臺主機都會收到此數據包,並可以回答它是否是您要查找的服務器。多播在概念上有所不同,只有那些希望接收到發往特定多播地址的數據包的主機才能接收到這些數據包。如果您使用Multicast,則需要爲您的應用程序選擇一個地址,每個客戶端都會將數據包發送到該地址,每發現一個服務器都會偵聽此地址。甚至存在一些網絡(例如一些大學網絡),其中多播分組被路由到有限的一組其他本地網絡。

DNS或其他靜態服務器

你可以使用第二個服務器,你用它來找到您的動態serevr一個靜態IP地址。每當它發生變化時,你的動態服務器就會告訴你的靜態服務器他的IP地址您的客戶端會向靜態服務器詢問動態服務器的地址。這種模式在整個互聯網上都能正常工作,無論你的動態服務器和客戶端在哪裏。

這個靜態服務器可能是你的DNS服務器或某些dyndns提供商的DNS服務器。但是這不僅限於DNS。 DNS旨在找出如何到達服務/服務器,但這可以通過任何協議完成。例如,如果您更喜歡web服務,則可以通過您開發的某個http/web應用程序來完成。

2

只是一個小小的警告:此代碼是未經測試,

嘗試挖掘到ARP緩存,就像這樣:

public static String getIpFromArpCache(String macaddr) { 
    if (ip == null) 
     return null; 
    BufferedReader br = null; 
    try { 
     br = new BufferedReader(new FileReader("/proc/net/arp")); 
     String line; 
     while ((line = br.readLine()) != null) { 
      String[] splitted = line.split(" +"); 
      if (splitted != null && splitted.length >= 4 && macaddr.equals(splitted[3])) { 
       // Basic sanity check 
       String ip = splitted[0]; 
       if (validateIp(ip)) { 
        return ip; 
       } else { 
        return null; 
       } 
      } 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } finally { 
     try { 
      br.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
    return null; 
} 

private static final String PATTERN = 
    "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + 
    "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + 
    "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + 
    "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$"; 

public static boolean validateIp(final String ip){   

     Pattern pattern = Pattern.compile(PATTERN); 
     Matcher matcher = pattern.matcher(ip); 
     return matcher.matches();    
} 

here

+0

這並不意味着MAC將在本地緩存中。因此,在某些情況下,它可能工作,但也可能不行。 – bestsss

+0

我知道,你是對的,他可能必須在做這個之前做一個多播。我會在週末後測試它並更新答案。 – Reno