Java NetworkInterface getName () не работает в Windows?

Я пишу программу для Windows, которая перечисляет все сетевые адаптеры и деактивирует все, кроме выбранного. Я знаю, как модифицировать сетевые адаптеры с помощью netsh, но проблема в том, что я не могу получить соответствующую информацию из класса NetworkInterface.

Класс NetworkInterface имеет методы getName() и getDisplayName(), но они, похоже, выдают только нерелевантные данные.

Я взял пример непосредственно из оракула:

http://docs.oracle.com/javase/tutorial/networking/nifs/listing.html

public class ListNets {

  public static void main(String args[]) throws SocketException {
    Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
    for (NetworkInterface netint : Collections.list(nets))
      displayInterfaceInformation(netint);
  }

  static void displayInterfaceInformation(NetworkInterface netint) throws SocketException {
    out.printf("Display name: %s\n", netint.getDisplayName());
    out.printf("Name: %s\n", netint.getName());
    Enumeration<InetAddress> inetAddresses = netint.getInetAddresses();
    for (InetAddress inetAddress : Collections.list(inetAddresses)) {
      out.printf("InetAddress: %s\n", inetAddress);
    }
    out.printf("\n");
  }
}  

Этот пример производит такой вывод:

Display name: Intel(R) Ethernet Connection (2) I219-V
Name: eth4
InetAddress: /10.0.0.4
InetAddress: /fe80:0:0:0:cc75:ed6:3089:bd61%eth4

Но я не могу использовать эту информацию, потому что netsh требует имя адаптера, а именно Ethernet 1, а не Intel(R) Ethernet Connection (2) I219-V или eth4.
На мой взгляд, getName() должен возвращать имя, специфичное для ОС, с использованием в самой ОС. Есть ли возможность получить настоящее имя адаптера с другими стандартными классами Java?

На данный момент моим единственным решением было бы getmac /fo csv /v получить правильную информацию и проанализировать ее. Из-за того, что я не хочу писать свою собственную оболочку, которая обращается к функции С++ GetAdaptersAddresses, потому что мне нужно будет ее изучить.


person Riesi    schedule 06.08.2016    source источник
comment
Вызов внешней команды, вероятно, самый простой, но не переносимый   -  person George Birbilis    schedule 07.08.2016
comment
Да, это своего рода моя точка зрения. Я хотел бы оставаться независимым от платформы как можно дольше, но я не могу, если java не предоставляет важную информацию об адаптере. Возможно, я рассмотрю возможность написания оболочки, но на данный момент я даже не могу скомпилировать код примера Microsoft в Visual Studio (у меня есть Visual Studio C++) или MinGW.   -  person Riesi    schedule 07.08.2016


Ответы (1)


Я только что ответил на похожий вопрос и столкнулся с этим. Итак, всем, кто интересуется, tl; dr - это этот комментарий из нативной реализации, которая перечисляет имена интерфейсов в JVM:

/*
 * Windows implementation of the java.net.NetworkInterface native methods.
 * This module provides the implementations of getAll, getByName, getByIndex,
 * and getByAddress.
 *
 * Interfaces and addresses are enumerated using the IP helper routines
 * GetIfTable, GetIfAddrTable resp. These routines are available on Windows
 * 98, NT SP+4, 2000, and XP. They are also available on Windows 95 if
 * IE is upgraded to 5.x.
 *
 * Windows does not have any standard for device names so we are forced
 * to use our own convention which is based on the normal Unix naming
 * convention ("lo" for the loopback, eth0, eth1, .. for ethernet devices,
 * tr0, tr1, .. for token ring, and so on). This convention gives us
 * consistency across multiple Windows editions and also consistency with
 * Solaris/Linux device names. Note that we always enumerate in index
 * order and this ensures consistent device number across invocations.
 */

Так что да, он сломан (намеренно), так как Windows 95 была вещью.

person Malt    schedule 30.10.2019