Need to identify local machine somehow in java
I'm trying to find out the name of the local machine (or some other way of uniquely identifying a particular m开发者_高级运维achine) that an application is running on.
I've been using this:
String hostname = java.net.InetAddress.getLocalHost().getHostName();
which works fine, but I just happened to notice in the profiler that it's taking quite a bit of time to execute that so I was wondering if there was something functionally similar that ran more quickly.
Doesn't have to be host name, could be anything as long as it uniquely identifies the machine.
To uniquely identify a machine, I would use the systems MAC address using getHardwareAddress()
.
However, I'm not sure if that would be any faster - but it would definitely be a better way of uniquely identifying the machine.
For an example, see: http://www.java2s.com/Code/Java/Network-Protocol/GetMACaddressofahostjavanetNetworkInterfacegetHardwareAddress.htm
You could grab the MAC address of the machine. Here's an example of how to get it.
byte[] mac = null;
List<NetworkInterface> interfaces =
(List<NetworkInterface>) Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface iface: interfaces) {
if (!iface.isLoopback()) {
mac = iface.getHardwareAddress();
if (mac != null) {
break;
}
}
}
This code grabs the MAC address off the first interface that has one. In addition to loopback interfaces, some machines might also have virtual interfaces for VPNs that won't have hardware addresses associated with them.
Tried getHostAddress()
? From the docs, it seems that getHostName()
involves a security check first (if there is a SecurityManager
), which means one more method call.
I came up with this:
String dirname = Utils.safetrim(System.getProperty("user.dir"));
It obviously doesn't world uniquely identify a machine but for my purposes it's good enough, because each person running this program will be logged in as themselves and probably be running from their home directory, so it makes the response unique enough for me.
And of course it's wicked fast, which is the important part.
Just to save the next person from stumbling over the incomplete MAC retrieval code, here is my version that works on my Windows 7 machine as well as other computers. Note that the code may still return different MACs on each invocation in case the user messed with his hardware and the network devices might be returned in different order.
private static final String generateHashIdentifier() throws Exception {
Enumeration<NetworkInterface> networkInterfaces
= NetworkInterface.getNetworkInterfaces();
while (networkInterfaces.hasMoreElements()) {
NetworkInterface networkInterface = networkInterfaces.nextElement();
if (networkInterface == null
|| networkInterface.isLoopback()
|| networkInterface.isVirtual()) {
continue;
}
byte[] mac = networkInterface.getHardwareAddress();
if (mac == null || mac.length == 0)
continue;
StringBuilder sb = new StringBuilder();
int zeroFieldCount = 0;
for (int i = 0; i < mac.length; i++) {
if (mac[i] == 0)
zeroFieldCount++;
sb.append(String.format("%02X%s", mac[i],
(i < mac.length - 1) ? "-" : ""));
}
if (zeroFieldCount > 4)
continue;
return sb.toString();
}
throw new RuntimeException("Failed to obtain MAC");
}
In Windows I get tons of additional devices which may or may not return a NULL mac or a mac with mostly zeros. The code tries to find the first device that gives a reasonable MAC and returns it as a nice String as a bonus.
精彩评论