2013-07-17 2 views
15

मैं अपने मशीन पर तीन इंटरफेस (eth0,Loopback,wlan0) है लिस्टिंग नहीं और मैं जावा एपीआई का उपयोग मैक पते पाने के लिए करना चाहते हैं।NetworkInterface.getNetworkInterfaces() सभी इंटरफ़ेस

  • मैं इस कोड का उपयोग करता हूं।

    Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces(); 
        for (NetworkInterface netint : Collections.list(nets)) 
         displayInterfaceInformation(netint); 
    } 
    
    static void displayInterfaceInformation(NetworkInterface netint) 
        throws SocketException 
    { 
        System.out.println("Display name: " 
         + netint.getDisplayName()); 
        System.out.println("Hardware address: " 
         + Arrays.toString(netint.getHardwareAddress())); 
    } 
    
  • लेकिन उस कोड प्रिंट wlan0,loopback, लेकिन eth0 याद किया।

  • मेरे ओएस Ubuntu, किसी भी मदद करते हैं।

अद्यतन

  • ओ/पी (strace -f java Networks 2>&1| grep ioctl) .. खाली (खाली)

  • java -version

जावा संस्करण "1.7.0_21" जावा (टीएम) एसई रनटाइम वातावरण (निर्माण 1.7.0_21-B11) जावा हॉटस्पॉट (टीएम) 64-बिट सर्वर वी एम (23.21 निर्माण -b01, मिश्रित मोड)

  • strace ifconfig 2> & 1 | ग्रेप ioctl

ioctl(4, SIOCGIFCONF, {80, {{"lo", {AF_INET, inet_addr("127.0.0.1")}}, {"wlan0", {AF_INET, inet_addr("192.168.1.101")}}}}) = 0 
ioctl(5, SIOCGIFFLAGS, {ifr_name="eth0", ifr_flags=IFF_UP|IFF_BROADCAST|IFF_MULTICAST}) = 0 
ioctl(5, SIOCGIFHWADDR, {ifr_name="eth0", ifr_hwaddr=-----------------}) = 0 
ioctl(5, SIOCGIFMETRIC, {ifr_name="eth0", ifr_metric=0}) = 0 
ioctl(5, SIOCGIFMTU, {ifr_name="eth0", ifr_mtu=1500}) = 0 
ioctl(5, SIOCGIFMAP, {ifr_name="eth0", ifr_map={mem_start=0, mem_end=0, base_addr=0, irq=0, dma=0, port=0}}) = 0 
ioctl(5, SIOCGIFMAP, {ifr_name="eth0", ifr_map={mem_start=0, mem_end=0, base_addr=0, irq=0, dma=0, port=0}}) = 0 
ioctl(5, SIOCGIFTXQLEN, {ifr_name="eth0", ifr_qlen=1000}) = 0 
ioctl(4, SIOCGIFADDR, {ifr_name="eth0", ???}) = -1 EADDRNOTAVAIL (Cannot assign requested address) 
ioctl(5, SIOCGIFFLAGS, {ifr_name="lo", ifr_flags=IFF_UP|IFF_LOOPBACK|IFF_RUNNING}) = 0 
ioctl(5, SIOCGIFHWADDR, {ifr_name="lo", ifr_hwaddr=00:00:00:00:00:00}) = 0 
ioctl(5, SIOCGIFMETRIC, {ifr_name="lo", ifr_metric=0}) = 0 
ioctl(5, SIOCGIFMTU, {ifr_name="lo", ifr_mtu=16436}) = 0 
ioctl(5, SIOCGIFMAP, {ifr_name="lo", ifr_map={mem_start=0, mem_end=0, base_addr=0, irq=0, dma=0, port=0}}) = 0 
ioctl(5, SIOCGIFMAP, {ifr_name="lo", ifr_map={mem_start=0, mem_end=0, base_addr=0, irq=0, dma=0, port=0}}) = 0 
ioctl(5, SIOCGIFTXQLEN, {ifr_name="lo", ifr_qlen=0}) = 0 
ioctl(4, SIOCGIFADDR, {ifr_name="lo", ifr_addr={AF_INET, inet_addr("127.0.0.1")}}) = 0 
ioctl(4, SIOCGIFDSTADDR, {ifr_name="lo", ifr_dstaddr={AF_INET, inet_addr("127.0.0.1")}}) = 0 
ioctl(4, SIOCGIFBRDADDR, {ifr_name="lo", ifr_broadaddr={AF_INET, inet_addr("0.0.0.0")}}) = 0 
ioctl(4, SIOCGIFNETMASK, {ifr_name="lo", ifr_netmask={AF_INET, inet_addr("255.0.0.0")}}) = 0 
ioctl(5, SIOCGIFFLAGS, {ifr_name="wlan0", ifr_flags=IFF_UP|IFF_BROADCAST|IFF_RUNNING|IFF_MULTICAST}) = 0 
ioctl(5, SIOCGIFHWADDR, {ifr_name="wlan0", ifr_hwaddr=---------------}) = 0 
ioctl(5, SIOCGIFMETRIC, {ifr_name="wlan0", ifr_metric=0}) = 0 
ioctl(5, SIOCGIFMTU, {ifr_name="wlan0", ifr_mtu=1500}) = 0 
ioctl(5, SIOCGIFMAP, {ifr_name="wlan0", ifr_map={mem_start=0, mem_end=0, base_addr=0, irq=0, dma=0, port=0}}) = 0 
ioctl(5, SIOCGIFMAP, {ifr_name="wlan0", ifr_map={mem_start=0, mem_end=0, base_addr=0, irq=0, dma=0, port=0}}) = 0 
ioctl(5, SIOCGIFTXQLEN, {ifr_name="wlan0", ifr_qlen=1000}) = 0 
ioctl(4, SIOCGIFADDR, {ifr_name="wlan0", ifr_addr={AF_INET, inet_addr("192.168.1.101")}}) = 0 
ioctl(4, SIOCGIFDSTADDR, {ifr_name="wlan0", ifr_dstaddr={AF_INET, inet_addr("192.168.1.101")}}) = 0 
ioctl(4, SIOCGIFBRDADDR, {ifr_name="wlan0", ifr_broadaddr={AF_INET, inet_addr("192.168.1.255")}}) = 0 
ioctl(4, SIOCGIFNETMASK, {ifr_name="wlan0", ifr_netmask={AF_INET, inet_addr("255.255.255.0")}}) = 0 

ifconfig

$ ifconfig 
eth0  Link encap:Ethernet HWaddr ------------- 
      UP BROADCAST MULTICAST MTU:1500 Metric:1 
      RX packets:0 errors:0 dropped:0 overruns:0 frame:0 
      TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 
      collisions:0 txqueuelen:1000 
      RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) 

lo  Link encap:Local Loopback 
      inet addr:127.0.0.1 Mask:255.0.0.0 
      inet6 addr: ::1/128 Scope:Host 
      UP LOOPBACK RUNNING MTU:16436 Metric:1 
      RX packets:1695 errors:0 dropped:0 overruns:0 frame:0 
      TX packets:1695 errors:0 dropped:0 overruns:0 carrier:0 
      collisions:0 txqueuelen:0 
      RX bytes:129949 (129.9 KB) TX bytes:129949 (129.9 KB) 

wlan0  Link encap:Ethernet HWaddr ------------------- 
      inet addr:192.168.1.101 Bcast:192.168.1.255 Mask:255.255.255.0 
      inet6 addr: fe80::-------------- Scope:Link 
      UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 
      RX packets:8396 errors:0 dropped:0 overruns:0 frame:0 
      TX packets:5524 errors:0 dropped:0 overruns:0 carrier:0 
      collisions:0 txqueuelen:1000 
      RX bytes:3959941 (3.9 MB) TX bytes:1513934 (1.5 MB) 
+8

क्या eth0 कॉन्फ़िगर किया गया है? जब आप 'ifconfig' करते हैं तो यह दिखाता है? –

+0

आपका कोड मेरे लिए काम करता है (उबंटू 12.04 एलटीएस) - यह 'लो' और' eth0' –

+2

दिखाता है जैसा @Erik ने कहा: 'ifconfig' का आउटपुट क्या है? 'Ifconfig' और जावा एपीआई दोनों अंततः एक ही' ioctl' कॉल ('SIOCGIFCONF') का उपयोग कर रहे हैं, इसलिए वे लगातार –

उत्तर

6

जाहिर है, मैं पहली जगह में गलत था: यहां तक ​​कि दोनों ifconfig और जावा एपीआई ही ioctl() syscalls उपयोग कर रहे हैं, हालांकि, वे अलग तरह से व्यवहार।

सबसे पहले, SIOCGIFCONF ioctl() इस प्रकार से प्रलेखित है (http://linux.die.net/man/7/netdevice देखें):

 
SIOCGIFCONF 
    Return a list of interface (transport layer) addresses. 
    ... 
    The kernel fills the ifreqs with all current L3 interface 
    addresses that are running. 

तो, SIOCGIFCONF ioctl() जो दोनों ifconfig और जावा एपीआई द्वारा किया जाता है केवल रिटर्न इंटरफेस चल रहा है। यह प्रश्न से strace ifconfig ... आउटपुट में भी देखा जा सकता है - पहले ioctl केवल lo और wlan0 लौटाता है, लेकिन eth0 नहीं।

फिर, ifconfig कहां से eth0 प्राप्त करता है? (Debian/Ubuntu पर net-tools पैकेज से) ifconfig स्रोत कोड, हम कि ifconfig नेटवर्क डिवाइस गणन, लेकिन सब से पहले के लिए आधार के रूप में ioctl() से परिणाम का उपयोग नहीं कर रहा है पढ़ने जाँच हो रही है /proc फाइल सिस्टम सभी निर्धारित करने के लिए नेटवर्क इंटरफेस। फिर, यह प्रत्येक इंटरफ़ेस के बारे में और जानकारी निर्धारित करने के लिए ioctl() सिस्कोल का उपयोग करता है।

दुर्भाग्यवश, java.net.NetworkInterface.getByName() विधि किसी कॉन्फ़िगर किए गए इंटरफ़ेस के लिए नेटवर्क इंटरफ़ेस ऑब्जेक्ट भी वापस नहीं करता है अगर हम स्पष्ट रूप से eth0 जैसे नाम को पास करते हैं।

मूलतः, वहाँ लिनक्स पर सभी उपकरणों की हार्डवेयर पतों प्राप्त करने के लिए तीन अलग-अलग दृष्टिकोण रहते हैं:

  • कॉल ifconfig और (अंतिम उपाय होना चाहिए) उत्पादन पार्स
  • करने के लिए एक JNI पुस्तकालय को लागू करें वही करें जो ifconfig करता है (एक आर्किटेक्चर निर्भर साझा लाइब्रेरी की आवश्यकता होती है)
  • सीधे /proc और /sys फाइल सिस्टम से डेटा पढ़ें।

ये सभी दृष्टिकोण सिस्टम निर्भर हैं और पोर्टेबल नहीं हैं। तीसरे दृष्टिकोण का लाभ यह है कि यह शुद्ध जावा में लागू हो सकता है। निम्न तृतीय दृष्टिकोण का एक नमूना कार्यान्वयन जो मेरे वातावरण में अच्छी तरह से काम कर रहा है:

static void printHardwareAddresses() throws SocketException { 
    if (System.getProperty("os.name").equals("Linux")) { 

     // Read all available device names 
     List<String> devices = new ArrayList<>(); 
     Pattern pattern = Pattern.compile("^ *(.*):"); 
     try (FileReader reader = new FileReader("/proc/net/dev")) { 
      BufferedReader in = new BufferedReader(reader); 
      String line = null; 
      while((line = in.readLine()) != null) { 
       Matcher m = pattern.matcher(line); 
       if (m.find()) { 
        devices.add(m.group(1)); 
       } 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     // read the hardware address for each device 
     for (String device : devices) { 
      try (FileReader reader = new FileReader("/sys/class/net/" + device + "/address")) { 
       BufferedReader in = new BufferedReader(reader); 
       String addr = in.readLine(); 

       System.out.println(String.format("%5s: %s", device, addr)); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 

    } else { 
     // use standard API for Windows & Others (need to test on each platform, though!!) 
     ... 
    } 
} 
+0

शायद आपको पता चलेगा कि इसे कैसे हल किया जाए? https://stackoverflow.com/questions/45607188/not-receiving-all-network-interfaces-of-an-android-device –

0

जब getNetworkInterfaces बुला जावा

all the interfaces on this machine. Returns null if no network interfaces could be found on this machine.

आप केवल नहीं हैं वापस आ जाएगी इस issue के साथ एक। जाहिर है, लिनक्स जावा पर केवल उन इंटरफेस लौटाएंगे जिनके पास एक आईपी पता आवंटित किया गया है (यानी कॉन्फ़िगर किए गए एडाप्टर)।

लेकिन देखने के लिए आपके आवेदन बिंदु से (जब तक आप एक नेटवर्क विन्यास आवेदन का निर्माण कर रहे) को IP पते यह बिल्कुल नहीं होने की तरह है बिना एक अंतरफलक है। आपको या तो इंटरफेस के लिए मतदान करना होगा या अपने आवेदन में "नेटवर्क प्राथमिकताएं" कहने पर उन्हें हर बार प्राप्त करना होगा।

+0

शायद आप यह भी पता चलेगा कि इसे कैसे हल किया जाए? https://stackoverflow.com/questions/45607188/not-receiving-all-network-interfaces-of-an-android-device –

0

@Andreas जवाब का विस्तार, हम $ifconfg | grep "Link encap" > some_file जैसे एक छोटे खोल स्क्रिप्ट लिख सकता है और उसके बाद एक छोटे (केवल 3 लाइनों) फ़ाइल होगा प्रत्येक पंक्ति पर पहला टोकन पार्स और चुनने के लिए। HWaddress पाने के लिए इसी तरह की बात है। हम कम जावा कोड लिखेंगे।

सेटिंग्स को पढ़ने के लिए अपाचे कॉमन्स IOUtils.toString(new FileInputStream(<file_path>,US_ASCII)) का उपयोग करने के लिए अन्य विकल्प हो सकता है। यह अपने समाधान में दोहराए गए जावा I/O कोड को खत्म कर देगा।

+0

शायद आपको पता चलेगा कि इसे कैसे हल किया जाए? https://stackoverflow.com/questions/45607188/not-receiving-all-network-interfaces-of-an-android-device –

संबंधित मुद्दे