2011-05-28 19 views
20

puedo usarObtener dirección MAC en la máquina local con Java

ip = InetAddress.getLocalHost(); 
NetworkInterface.getByInetAddress(ip); 

para obtener la dirección MAC, pero si uso este código en una máquina sin conexión no funciona.

Entonces, ¿Cómo puedo obtener la dirección de Mac?

+3

Técnicamente, se debe tratar a una máquina fuera de línea, aunque no tiene la tarjeta de red de todos modos. ¿Cómo lidias con este último caso? –

+1

¿Por qué su programa necesita esta información? ¿Qué beneficio le proporciona al usuario final? –

+0

¿Y qué pasa si la máquina tiene más de una? ¿Y sabe que el usuario puede cambiar la dirección MAC?No hay nada que pueda hacer con una dirección MAC en Java, excepto tratar de usarla como un identificador de máquina, para lo cual no es adecuado. – EJP

Respuesta

26

Con Java 6+, puedes usar NetworkInterface.getHardwareAddress.

Tenga en cuenta que una computadora no puede tener tarjetas de red, especialmente si está integrada o es virtual. También puede tener más de uno. Puede obtener una lista de todas las tarjetas de red con NetworkInterface.getNetworkInterfaces().

+3

Tuve un problema, que en algunas computadoras solo obtuve una mac-dirección truncada de 4 bytes. Logré resolver esto incluyendo -Djava.net.preferIPv4Stack = true como parámetro de inicio para java – runholen

5

En cuanto al equipo que está fuera de línea, por lo general no tiene una dirección IP asignada, porque DHCP se utiliza ampliamente ...

Y para la pregunta del título: NetworkInterface.getHardwareAddress()

1

Otra forma es utilizar un comando del sistema operativo 'getmac' a través de la ejecución de código nativo.

Process p = Runtime.getRuntime().exec("getmac /fo csv /nh"); 
    java.io.BufferedReader in = new java.io.BufferedReader(new java.io.InputStreamReader(p.getInputStream())); 
    String line; 
    line = in.readLine();   
    String[] result = line.split(","); 

    System.out.println(result[0].replace('"', ' ').trim()); 
+4

'getmac' está disponible solo en Windows. Pero no en Ubuntu 13.10 (ni con 'apt-get') y Android 4.2. –

1

Prueba esto:

final NetworkInterface netInf = NetworkInterface.getNetworkInterfaces().nextElement(); 
final byte[] mac = netInf.getHardwareAddress(); 
final StringBuilder sb = new StringBuilder(); 
for (int i = 0; i < mac.length; i++) { 
     sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : ""));   
} 
log.info("Mac addr: {}", sb.toString()); 
+0

Hay algunas excepciones que debe atrapar. –

0

limpiado código de here:

import java.net.InetAddress; 
import java.net.NetworkInterface; 
import java.net.SocketException; 
import java.net.UnknownHostException; 

public class HardwareAddress 
{ 
    public static String getMacAddress() throws UnknownHostException, 
      SocketException 
    { 
     InetAddress ipAddress = InetAddress.getLocalHost(); 
     NetworkInterface networkInterface = NetworkInterface 
       .getByInetAddress(ipAddress); 
     byte[] macAddressBytes = networkInterface.getHardwareAddress(); 
     StringBuilder macAddressBuilder = new StringBuilder(); 

     for (int macAddressByteIndex = 0; macAddressByteIndex < macAddressBytes.length; macAddressByteIndex++) 
     { 
      String macAddressHexByte = String.format("%02X", 
        macAddressBytes[macAddressByteIndex]); 
      macAddressBuilder.append(macAddressHexByte); 

      if (macAddressByteIndex != macAddressBytes.length - 1) 
      { 
       macAddressBuilder.append(":"); 
      } 
     } 

     return macAddressBuilder.toString(); 
    } 
} 
16

Con todas las posibles soluciones que he encontrado aquí y otro responde, entonces voy a aportar mi solución. Debe especificar un parámetro con una cadena que contenga "ip" o "mac" dependiendo de lo que necesite verificar. Si la computadora no tiene interfaz, devolverá una Cadena que contenga nulo; de lo contrario, devolverá una Cadena que contenga lo que solicitó (la dirección IP o el mac).

Cómo se usa:

System.out.println("Ip: " + GetNetworkAddress.GetAddress("ip")); 
System.out.println("Mac: " + GetNetworkAddress.GetAddress("mac")); 

resultado (si el equipo tiene una tarjeta de red):

Ip: 192.168.0.10 
Mac: 0D-73-ED-0A-27-44 

resultado (si el equipo no tiene una tarjeta de red):

Ip: null 
Mac: null 

Aquí está el código:

import java.net.Inet4Address; 
import java.net.InetAddress; 
import java.net.NetworkInterface; 
import java.net.SocketException; 
import java.net.UnknownHostException; 
import java.util.Enumeration; 

public class GetNetworkAddress { 

    public static String GetAddress(String addressType) { 
     String address = ""; 
     InetAddress lanIp = null; 
     try { 

      String ipAddress = null; 
      Enumeration<NetworkInterface> net = null; 
      net = NetworkInterface.getNetworkInterfaces(); 

      while (net.hasMoreElements()) { 
       NetworkInterface element = net.nextElement(); 
       Enumeration<InetAddress> addresses = element.getInetAddresses(); 

       while (addresses.hasMoreElements() && element.getHardwareAddress().length > 0 && !isVMMac(element.getHardwareAddress())) { 
        InetAddress ip = addresses.nextElement(); 
        if (ip instanceof Inet4Address) { 

         if (ip.isSiteLocalAddress()) { 
          ipAddress = ip.getHostAddress(); 
          lanIp = InetAddress.getByName(ipAddress); 
         } 

        } 

       } 
      } 

      if (lanIp == null) 
       return null; 

      if (addressType.equals("ip")) { 

       address = lanIp.toString().replaceAll("^/+", ""); 

      } else if (addressType.equals("mac")) { 

       address = getMacAddress(lanIp); 

      } else { 

       throw new Exception("Specify \"ip\" or \"mac\""); 

      } 

     } catch (UnknownHostException ex) { 

      ex.printStackTrace(); 

     } catch (SocketException ex) { 

      ex.printStackTrace(); 

     } catch (Exception ex) { 

      ex.printStackTrace(); 

     } 

     return address; 

    } 

    private static String getMacAddress(InetAddress ip) { 
     String address = null; 
     try { 

      NetworkInterface network = NetworkInterface.getByInetAddress(ip); 
      byte[] mac = network.getHardwareAddress(); 

      StringBuilder sb = new StringBuilder(); 
      for (int i = 0; i < mac.length; i++) { 
       sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : "")); 
      } 
      address = sb.toString(); 

     } catch (SocketException ex) { 

      ex.printStackTrace(); 

     } 

     return address; 
    } 

    private static boolean isVMMac(byte[] mac) { 
     if(null == mac) return false; 
     byte invalidMacs[][] = { 
       {0x00, 0x05, 0x69},    //VMWare 
       {0x00, 0x1C, 0x14},    //VMWare 
       {0x00, 0x0C, 0x29},    //VMWare 
       {0x00, 0x50, 0x56},    //VMWare 
       {0x08, 0x00, 0x27},    //Virtualbox 
       {0x0A, 0x00, 0x27},    //Virtualbox 
       {0x00, 0x03, (byte)0xFF},  //Virtual-PC 
       {0x00, 0x15, 0x5D}    //Hyper-V 
     }; 

     for (byte[] invalid: invalidMacs){ 
      if (invalid[0] == mac[0] && invalid[1] == mac[1] && invalid[2] == mac[2]) return true; 
     } 

     return false; 
    } 

} 

ACTUALIZADO 05/05/2017: Gracias a @mateuscb en la publicación How to Determine Internet Network Interface in Java que desafortunadamente no recibió ningún voto positivo anteriormente, pero ha contribuido a esta actualización.

El método ha sido mejorado para saltar las tarjetas de red de la máquina virtual (VM más popular de software)

+0

¿Qué hago si esto da una excepción 'ArrayIndexOutOfBounds' en' if (invalid [0] == mac [0] && invalid [1] == mac [1] && invalid [2] == mac [2]) devolver verdadero; – Sumit

+0

@Sumit comprobar el número de elementos que están en ambas matrices "inválido" y "mac" porque uno de ellos o ambos tienen menos de tres elementos –

+0

Así que encontré otro código en https://stackoverflow.com/a/ 16449379/3169868 que muestra la primera dirección MAC en blanco y las 3 restantes (incluidas las máquinas virtuales). ¿Se puede modificar este código para manejar esto? – Sumit

Cuestiones relacionadas