java InetAddress.getLocalHost (); retorna 127.0.0.1… como obter o IP REAL?

Eu estou escrevendo um aplicativo de rede simples … Eu preciso saber o ip real da minha máquina na rede, como 192.168.1.3. getLocalHost retorna 127.0.0.1 (no Linux, não sei se é o mesmo no windows) como fazê-lo ?;

Se você realmente deseja trabalhar com todos os endereços IP na máquina, pode obtê-los com a class NetworkInterface. Claro, então você precisa saber qual deles você realmente quer usar, mas isso vai ser diferente, dependendo do que você está usando, ou você pode precisar expandir a maneira como você está usando para contabilizar vários endereços.

import java.net.*; import java.util.*; public class ShowInterfaces { public static void main(String[] args) throws Exception { System.out.println("Host addr: " + InetAddress.getLocalHost().getHostAddress()); // often returns "127.0.0.1" Enumeration n = NetworkInterface.getNetworkInterfaces(); for (; n.hasMoreElements();) { NetworkInterface e = n.nextElement(); System.out.println("Interface: " + e.getName()); Enumeration a = e.getInetAddresses(); for (; a.hasMoreElements();) { InetAddress addr = a.nextElement(); System.out.println(" " + addr.getHostAddress()); } } } } 

Como a máquina pode ter vários endereços, é difícil determinar qual deles é o melhor para você. Normalmente, você deseja que o sistema atribua um IP com base em sua tabela de roteamento. Como o resultado depende do IP ao qual você gostaria de se conectar, há um truque simples: basta criar uma conexão e ver qual endereço você tem no sistema operacional:

 // output on my machine: "192.168.1.102" Socket s = new Socket("192.168.1.1", 80); System.out.println(s.getLocalAddress().getHostAddress()); s.close(); // output on my machine: "127.0.1.1" System.out.println(InetAddress.getLocalHost().getHostAddress()); 

Não tenho certeza se é possível fazer isso sem estabelecer uma conexão. Acho que uma vez consegui fazer isso com Perl (ou C?), Mas não me pergunte sobre Java. Eu acho que pode ser possível criar um soquete UDP (DatagramSocket) sem realmente conectá-lo.

Se houver um roteador NAT no caminho, você não conseguirá obter o IP que os hosts remotos verão. No entanto, como você deu 192. * como um exemplo, eu acho que você não se importa.

Para fixar isso:

  1. Encontre o seu nome de host. Digite: hostname . Por exemplo, você acha que seu nome de host é mycomputer.xzy.com

  2. Coloque seu nome de host em seu arquivo de hosts. /etc/hosts . Tal como

     10.50.16.136 mycomputer.xzy.com 

Aqui está uma maneira de evitar os resultados de IPv6 e Loopback.

 public InetAddress getCurrentIp() { try { Enumeration networkInterfaces = NetworkInterface .getNetworkInterfaces(); while (networkInterfaces.hasMoreElements()) { NetworkInterface ni = (NetworkInterface) networkInterfaces .nextElement(); Enumeration nias = ni.getInetAddresses(); while(nias.hasMoreElements()) { InetAddress ia= (InetAddress) nias.nextElement(); if (!ia.isLinkLocalAddress() && !ia.isLoopbackAddress() && ia instanceof Inet4Address) { return ia; } } } } catch (SocketException e) { LOG.error("unable to get current IP " + e.getMessage(), e); } return null; } 

Seu computador pode ter vários IPs. Como você sabe qual deles? O jeito que eu faço é ter um CGI muito simples rodando em outra máquina que reporta o IP que é visto, e eu bato quando preciso saber qual é o meu IP para o mundo externo.

Em vez de usar InetAddress.getHostAddress (), eu chamo a rotina getHost4Address que escrevi para obter o primeiro endereço não loopback …

 /** * Returns this host's non-loopback IPv4 addresses. * * @return * @throws SocketException */ private static List getInet4Addresses() throws SocketException { List ret = new ArrayList(); Enumeration nets = NetworkInterface.getNetworkInterfaces(); for (NetworkInterface netint : Collections.list(nets)) { Enumeration inetAddresses = netint.getInetAddresses(); for (InetAddress inetAddress : Collections.list(inetAddresses)) { if (inetAddress instanceof Inet4Address && !inetAddress.isLoopbackAddress()) { ret.add((Inet4Address)inetAddress); } } } return ret; } /** * Returns this host's first non-loopback IPv4 address string in textual * representation. * * @return * @throws SocketException */ private static String getHost4Address() throws SocketException { List inet4 = getInet4Addresses(); return !inet4.isEmpty() ? inet4.get(0).getHostAddress() : null; } 

Eu escrevi este código:

 import java.net.InterfaceAddress; import java.net.NetworkInterface; import java.util.Collections; import java.util.HashSet; import java.util.Set; private String[] getHostAddresses() { Set HostAddresses = new HashSet<>(); try { for (NetworkInterface ni : Collections.list(NetworkInterface.getNetworkInterfaces())) { if (!ni.isLoopback() && ni.isUp() && ni.getHardwareAddress() != null) { for (InterfaceAddress ia : ni.getInterfaceAddresses()) { if (ia.getBroadcast() != null) { //If limited to IPV4 HostAddresses.add(ia.getAddress().getHostAddress()); } } } } } catch (SocketException e) { } return HostAddresses.toArray(new String[0]); } 

Confira!

Para mim:

  • Não deve ser LoopBack!
  • Deve ser UP!
  • Deve ter o endereço MAC (não é nulo)

Obter o pedido atual da instância atual

 HttpServletRequest httpServletRequest = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest(); 

então pegue o endereço do pedido

 ip = httpServletRequest.getRemoteAddr(); 

Caso você queira obter o endereço IP do seu PC, você tem que usar o object “InetAddress”, que existe na biblioteca “java.net.InetAddress”.

O método a seguir retorna seu IP:

 public String getIp() { String myIp = ""; InetAddress ip; try { ip = InetAddress.getLocalHost(); myIp = ip.getHostAddress(); // This method returns the IP. } catch (UnknownHostException e) { e.printStackTrace(); } return myIp; }