- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我的机器上有三个接口(interface)(eth0,Loopback,wlan0)
,我想使用 Java-API 来获取 mac 地址。
我使用这个代码。
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。
更新
o/p (strace -f java Networks 2>&1| grep ioctl
).. blank(empty).
java -version
Java 版本“1.7.0_21”Java(TM) SE 运行时环境(build 1.7.0_21-b11)Java HotSpot(TM) 64 位服务器 VM(构建 23.21-b01,混合模式)
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(无法分配请求的地址)
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)
最佳答案
显然,我一开始就错了:尽管 ifconfig
和 Java API 都在使用相同的 ioctl()
系统调用,它们的行为不同。
首先,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.
So, the SIOCGIFCONF ioctl()
which is used by both ifconfig
and the JAVA API only returns the running interfaces. This can also be seen in the strace ifconfig ...
output from the question - the very first ioctl
only returns lo
and wlan0
, but not eth0.
Then, where does ifconfig
get the eth0
from at all? Checking the ifconfig
source code (from the net-tools
package on Debian/Ubuntu), we seethat ifconfig
is not using the result from the ioctl()
as the basis for the network device enumeration,but first of all reads the /proc
filesystem to determine all network interfaces. Then, it uses the ioctl()
syscalls to determine further information about each interface.
Unfortunately, the java.net.NetworkInterface.getByName()
method does not even return a network interface objectfor an unconfigured interface if we explicitly pass the name, like eth0
.
Essentially, there remain three different approaches to get the hardware addresses of all devices on Linux:
ifconfig
and parse the output (should be last resort)ifconfig
does (requires an architecture dependent shared library)/proc
and the /sys
filesystems.All of these approaches are system dependant and not portable. The benefit of the third approach is that it can beimplemented in pure Java. The following is a sample implementation of the third approach which worked well in my environment:
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!!)
...
}
}
关于java - NetworkInterface.getNetworkInterfaces() 没有列出所有接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17698971/
我使用 XMLEncode 将一些网络数据存储在 xml 文件中,因为它确实很方便。不幸的是,一些类(如 NetworkInterface)无法通过 XMLEncoder 序列化(这个词正确吗?)为
NetworkInterface.GetAllNetworkInterfaces方法返回的是系统上所有接口(interface)的列表,但是它返回了很多看似垃圾的接口(interface)太像了 xx
我已经使用这个 API 来选择设备的 mac 地址, NetworkInterface.getHardwareAddress() 但这是针对 API 级别 9 及更高版本的,我应该使用什么来选择 AP
我拿起我的一些旧代码进行重建,曾经在我的平板电脑和手机上使用的方法之一不再有效。我正在尝试使用我在此处选择的例程来获取我的 IP 地址。 当程序执行到第 4 行(以“for (Enumeration.
我想获取当前设备的可用网络,所以我首先获取网络接口(interface)列表: NetworkInterface.getNetworkInterfaces(); 然后,迭代每一个: NetworkIn
我想使用 Wifi 和 LAN 连接在设备上运行一系列测试。我有两张网卡,一张是WiFi,一张是有线。该设备具有可通过两个网络接口(interface)访问的单个 IP 地址。有没有办法保证我的机器使
我有一个在 OpenShift (Kubernetes) 中运行的软件,其中许可证基于 MAC 地址。重新启动应用程序时,容器的MAC地址发生变化,我必须申请新的许可证文件。 由于 k8s pod 中
我想使用 Wifi 和 LAN 连接在设备上运行一系列测试。我有两张网卡,一张是WiFi,一张是有线。该设备具有可通过两个网络接口(interface)访问的单个 IP 地址。有没有办法保证我的机器使
什么情况下返回值为true? 谢谢大家! public class Test1 { public static void main(String[] args) { try {
我正在使用以下代码来检测我的电脑上网络接口(interface)卡的名称。我正在使用 USB 调制解调器。 public class DetectNIC { public string Ret
我有一个 .NET 应用程序需要从网站访问资源。访问这些资源可能需要用户更改其代理设置。 我想知道如何以一种有助于决定是否为用户提供更改其代理设置的能力的方式从应用程序检测网络的存在(即潜在的互联网连
该特定字段返回什么?我想要每秒接收的字节数。我应该依赖这个吗? 最佳答案 我认为你可以这样使用它: long beginValue = NetworkInterface.GetIPv4Statisti
我在 Spring 的代码是: group = SysUtil.isLinux()?new EpollEventLoopGroup():new NioEventLoopGroup(); 这里的代码块,
我的 android API 有问题:如果我查看 android API 文档,类 NetworkInterface 的方法 isUP() 存在,但是当我尝试在代码中使用它时,我无法编译我的应用程序。
在我们的部分代码中,我试图将 mac 地址与我们的许可证文件绑定(bind),但我面临一个问题,即我用于计算机器所有 mac 地址的代码没有返回所有物理 mac 地址。这是获取所有mac地址的代码 p
我正在尝试编译一个简单的 Qt5.2 程序,它使用 libnm-qt5 和 libmm-qt5 来管理连接,但是当我试图用这段代码列出它们时: #include #include #include
我要测试一个将 java.net.NetworkInterface 列表作为参数的方法,因此我应该模拟最终的抽象类或实例化它。对做这些有什么想法吗? 方法是这样的: public void handl
我的机器上有三个接口(interface)(eth0,Loopback,wlan0),我想使用 Java-API 来获取 mac 地址。 我使用这个代码。 Enumeration nets = Net
我遇到了 this tracker issue 中报告的问题早在 2011 年,并希望开发一个合适的解决方法。我想向用户显示所有 Android 设备的网络接口(interface),并按它们的类型以
我有一个 Azure 网站,对 NetworkInterface.GetIsNetworkAvailable() 的调用始终返回 false。还有其他人遇到过这种行为吗? 最佳答案 正如 MSFT J
我是一名优秀的程序员,十分优秀!