2013-07-17 9 views
15

tüm arayüzleri listeleme ve ben mac adresini almak için Java API kullanmak almak istemez.NetworkInterface.getNetworkInterfaces() Benim makinede üç arayüzleri <code>(eth0,Loopback,wlan0)</code> var

  • Bu kodu kullanıyorum.

    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())); 
    } 
    
  • Ama bu yasanın yazılı wlan0,loopback, ama eth0 kaçırdı.

  • Benim OS Ubuntu, herhangi bir yardım

    .

Güncelleme

  • o/p (strace -f java Networks 2>&1| grep ioctl) .. boş (boş). java -version

  • java versiyonu "1.7.0_21" Java (TM) SE Runtime Environment Java HotSpot (TM) 64-bit sunucu VM (23.21 build (1.7.0_21-b11 inşa) -b01, karışık mod)

    • strace ifconfig 2> & 1 | grep 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 yapılandırılmış mı? Ifconfig'i ne zaman gösterir? –

    +0

    Kodunuz benim için çalışıyor (Ubuntu 12.04 LTS) - 'lo' ve 'eth0' gösterir –

    +2

    As @ Erik dedi: 'ifconfig' çıktı nedir? Hem 'ifconfig' hem de Java API'sı nihayetinde aynı "ioctl" çağrısını kullanıyor ('SIOCGIFCONF'), bu yüzden tutarlı olmalılar –

    cevap

    6

    Açıkçası, ilk etapta yanlış: hatta hem ifconfig ve Java API aynı ioctl() syscalls kullanıyor olsa da, bunlar farklı davranır.Her şeyden

    Öncelikle SIOCGIFCONF ioctl() (http://linux.die.net/man/7/netdevice bakınız) aşağıdaki gibi belgelenmiştir:

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

    Yani, hem ifconfig ve JAVA API tarafından kullanılan SIOCGIFCONF ioctl() sadece arayüzleri çalışan döndürür. Bu, strace ifconfig ... çıktısında da görülebilir - ilk ioctl yalnızca lo ve wlan0, ancak eth0 değil. Sonra

    , nerede ifconfig hiç dan eth0 alır? /proc dosya sistemi (Debian/Ubuntu üzerinde net-tools paketinden) ifconfig kaynak kodunu, biz ağ aygıt numaralandırma, ama her şeyden önce temel olarak ioctl() sonucunu kullanmıyor ifconfig görüyoruz okur Denetleme tüm belirlemek için Ağ arayüzleri. Sonra, her bir arayüz hakkında daha fazla bilgi belirlemek için ioctl() syscalls kullanır. Biz açıkça eth0 gibi, isim geçerse

    Maalesef java.net.NetworkInterface.getByName() yöntem bile yapılandırılmamış arabirimi için bir ağ arabirim nesnesi döndürmez.

    • Çağrı ifconfig ve bir JNI'yı kütüphanesi uygulamak (olmalıdır son çare)
    • çıkışını ayrıştırmak:

      Esasen, Linux üzerinde tüm cihazların donanım adreslerini almak için üç farklı yaklaşımlar orada kalır ifconfig (mimariye bağımlı bir paylaşımlı kütüphane gerektirir) ne yapar?

    • Verileri doğrudan /proc ve /sys dosya sistemlerinden okuyun.

    bu yaklaşımların tamamı sistem bağımlı ve taşınabilir değildir. Üçüncü yaklaşımın yararı, saf Java'da uygulanan olabilir.

    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

    Belki de bu olayı çözmek için nasıl bileceksiniz? https://stackoverflow.com/questions/45607188/not-receiving-all-network-interfaces-of-an-android-device –

    0

    getNetworkInterfaces arayarak Java

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

    Yalnızca değildir dönecektir Bu issue olanlardan. Görünüşe göre, linux üzerinde Java bir IP atanana (yani yapılandırılmış adaptörler) tek arayüzleri dönecektir.

    Ama bakış uygulamanız noktasından

    Bir IP adresinden bunu hiç olmaması gibi olmayan bir arayüze sahip olan (bir ağ yapılandırma uygulaması inşa ediyoruz sürece). Sen arayüzler için iki anket zorunda ya Onlara her eriştiğinizde alacak, diyelim ki, uygulamanızda "Ağ Tercihleri".

    +0

    Belki de Bunu nasıl çözeceğimi bileceğim? https://stackoverflow.com/questions/45607188/not-receiving-all-network-interfaces-of-an-android-device –

    0

    @Andreas cevap genişletilmesi, biz daha küçük (sadece 3 hat) dosyasını olacak sonra $ifconfg | grep "Link encap" > some_file gibi küçük bir kabuk yazılımı ve olabilir: my ortamda iyi çalıştı üçüncü yaklaşımın örnek bir uygulama Aşağıdaki Her satırda ilk belirteci ayrıştırmak ve seçmek için. HWaddress almak için de benzer bir şey. Daha az java kodu yazacağız.

    Diğer seçenek ayarlarını okumak için Apache commons IOUtils.toString(new FileInputStream(<file_path>,US_ASCII)) kullanmak olabilir. Bu, kendi çözümlerinde tekrarlayan java I/O kodunu ortadan kaldıracaktır.

    +0

    Belki de bu olayı çözmek için nasıl bileceksiniz? https://stackoverflow.com/questions/45607188/not-receiving-all-network-interfaces-of-an-android-device –

    İlgili konular