java 网络接口,获取Java中特定网络接口的名称

I am using windows 10 and I would like to plug a device on my computer (which created a new network interface with the name "Ethernet 12" and description "foobar") and be able to set the IP address of this interface using Java. Using this link: Change Computer IP address using JAVA, I am able to configure the IP address of the interface. The issue I have is that I am not able, in java, to retrieve the name of the interface created by the device. From the documentation I found, I did the following:

Enumeration 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));

}

and got the following result:

Display name: foobar

Name: eth15

Address 111.116.15.4

I expected the name to be "Ethernet 12" and not "eth15", which doesn't seem to make any sense. I noticed the same for all my other interface (wifi, ethernet, etc...). Since I need the real name of my interface (Ethernet 12) to configure the IP address with netsh (and not a random one like "eth15"), I am stuck...

Is there a reason why I am getting "eth15" as the name of my interface ?

Thank you

解决方案

Is there a reason why I am getting "eth15" as the name of my interface ?

That took some digging. In Java world, NetworkInterfaces are enumerated by java.net.NetworkInterface::getNetworkInterfaces() which calls the native java.net.NetworkInterface::getAll().

We can find the native source code for getAll() in OpenJDK 11 here where we find this comment:

/*

* 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.

*/

So once upon a time, when Windows 95 was still a thing, someone decided not to read the actual Windows interface names, and instead use "our own convention". Why? No idea. I would have preferred getting a separate deviceName() and a ourOwnConventionWhichHasNothingToDoWithTheActualNameDeviceName(), but unfortunately I wasn't consulted.

The underlying Windows API call GetIfTable does return a name for each interface in the form an array of MIB_IFROW:

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;

In short, it doesn't look like the implementation has changed in many years, and it's probably impossible to change at this point without creating a completely new API. Otherwise you risk breaking people's code.

The way I see it, there are two ways to get the actual interface names:

Use JNI to make the native call to GetIfTable yourself.

Execute netsh and parse the response.

Both solutions are kinda ugly and require you to make sure you're running on Windows.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值