获取Java中特定网络接口的名称
我正在使用windows 10,我想在我的计算机上插入一个设备(它创建了一个名为“Ethernet 12”和描述为“foobar”的新网络接口),并能够使用Java设置此接口的IP地址。使用此链接:,我可以配置接口的IP地址。我遇到的问题是,在java中,我无法检索设备创建的接口的名称。根据我找到的文档,我做了以下工作:获取Java中特定网络接口的名称,java,jvm,network-programming,network-interface,Java,Jvm,Network Programming,Network Interface,我正在使用windows 10,我想在我的计算机上插入一个设备(它创建了一个名为“Ethernet 12”和描述为“foobar”的新网络接口),并能够使用Java设置此接口的IP地址。使用此链接:,我可以配置接口的IP地址。我遇到的问题是,在java中,我无法检索设备创建的接口的名称。根据我找到的文档,我做了以下工作: Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetwork
Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
while(networkInterfaces.hasMoreElements())
{
NetworkInterface networkInterface = networkInterfaces.nextElement();
if (networkInterface.isUp())
System.out.println("Display name: " + networkInterface.getDisplayName() + "\nName: " + networkInterface.getName() + "\nAddress: " + networkInterface.getInterfaceAddresses().get(0));
}
我希望名称是“Ethernet 12”,而不是“eth15”,这似乎没有任何意义。我注意到我的所有其他接口(wifi、以太网等)都是如此。因为我需要我接口的真实名称(Ethernet 12)来配置netsh的IP地址(而不是像“eth15”这样的随机地址),所以我被卡住了
是否有理由将“eth15”作为接口的名称
多谢各位
是否有理由将“eth15”作为接口的名称
这需要一些挖掘。在Java世界中,NetworkInterface
由Java.net.NetworkInterface::getNetworkInterfaces()
枚举,它调用本机Java.net.NetworkInterface::getAll()
我们可以在OpenJDK 11中找到getAll()
的本机源代码,在这里我们可以找到以下注释:
/*
* 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.
*/
因此,曾几何时,当Windows95还是一个东西的时候,有人决定不阅读实际的Windows界面名称,而是使用“我们自己的约定”。为什么?不知道。我更希望得到一个单独的deviceName()
和一个我们自己的约定,但不幸的是没有人咨询我
底层Windows API调用以数组的形式返回每个接口的名称:
JVM似乎是,然后,最后
简言之,它的实现在很多年里看起来并没有改变,而且如果不创建一个全新的API,在这一点上进行更改可能是不可能的。否则你就有可能破坏别人的密码
在我看来,有两种方法可以获得实际的接口名称:
使用JNI自己对GetIfTable
进行本机调用
执行netsh
并解析响应
这两种解决方案都有点难看,需要您确保在Windows上运行。看起来您并不孤单:
/*
* 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.
*/
typedef struct _MIB_IFROW {
WCHAR wszName[MAX_INTERFACE_NAME_LEN];
IF_INDEX dwIndex;
IFTYPE dwType;
DWORD dwMtu;
DWORD dwSpeed;
DWORD dwPhysAddrLen;
UCHAR bPhysAddr[MAXLEN_PHYSADDR];
DWORD dwAdminStatus;
INTERNAL_IF_OPER_STATUS dwOperStatus;
DWORD dwLastChange;
DWORD dwInOctets;
DWORD dwInUcastPkts;
DWORD dwInNUcastPkts;
DWORD dwInDiscards;
DWORD dwInErrors;
DWORD dwInUnknownProtos;
DWORD dwOutOctets;
DWORD dwOutUcastPkts;
DWORD dwOutNUcastPkts;
DWORD dwOutDiscards;
DWORD dwOutErrors;
DWORD dwOutQLen;
DWORD dwDescrLen;
UCHAR bDescr[MAXLEN_IFDESCR];
} MIB_IFROW, *PMIB_IFROW;