Pregunta

¿Cómo puedo determinar la IP de mi enrutador/puerta de enlace en Java?Puedo obtener mi IP con bastante facilidad.Puedo obtener mi IP de Internet utilizando un servicio en un sitio web.¿Pero cómo puedo determinar la IP de mi puerta de enlace?

Esto es algo fácil en .NET si conoces el manejo.¿Pero cómo se hace en Java?

¿Fue útil?

Solución

Desafortunadamente, Java no hace que esto sea tan agradable como otros lenguajes.Esto es lo que hice:

import java.io.*;
import java.util.*;

public class ExecTest {
    public static void main(String[] args) throws IOException {
        Process result = Runtime.getRuntime().exec("traceroute -m 1 www.amazon.com");

        BufferedReader output = new BufferedReader(new InputStreamReader(result.getInputStream()));
        String thisLine = output.readLine();
        StringTokenizer st = new StringTokenizer(thisLine);
        st.nextToken();
        String gateway = st.nextToken();
        System.out.printf("The gateway is %s\n", gateway);
    }
}

Esto supone que la puerta de enlace es el segundo token y no el tercero.Si es así, necesitas agregar un extra st.nextToken(); para avanzar el tokenizador un lugar más.

Otros consejos

En Windows, OSX, Linux, etc., la respuesta de Chris Bunch se puede mejorar mucho usando

netstat -rn

en lugar de un traceroute dominio.

La dirección IP de su puerta de enlace aparecerá en el segundo campo de la línea que comienza default o 0.0.0.0.

Esto soluciona una serie de problemas al intentar utilizar traceroute:

  1. en Windows traceroute es en realidad tracert.exe, por lo que no hay necesidad de dependencias de sistema operativo en el código
  2. Es un comando rápido de ejecutar: obtiene información del sistema operativo, no de la red.
  3. traceroute a veces es bloqueado por la red

El único inconveniente es que será necesario seguir leyendo líneas del netstat salida hasta que se encuentre la línea correcta, ya que habrá más de una línea de salida.

EDITAR: La dirección IP de la puerta de enlace predeterminada se encuentra en el segundo campo de la línea que comienza con "predeterminado" si está en una MAC (probado en Lion), o en el tercer campo de la línea que comienza con '0.0.0.0' (probado en Windows 7)

Ventanas:

Métrica de interfaz de puerta de enlace de máscara de red de destino de red

0.0.0.0 0.0.0.0 192.168.2.254 192.168.2.46 10

Mac:

Destino Puerta de enlace Banderas Refs Usar Netif Caducar

por defecto 192.168.2.254 UGSc 104 4 en1

try{
    Process result = Runtime.getRuntime().exec("netstat -rn");

    BufferedReader output = new BufferedReader(new InputStreamReader(result.getInputStream()));

    String line = output.readLine();
    while(line != null){
        if ( line.startsWith("default") == true )
            break;      
        line = output.readLine();
    }

    StringTokenizer st = new StringTokenizer( line );
    st.nextToken();
    gateway = st.nextToken();
    st.nextToken();
    st.nextToken();
    st.nextToken();
    adapter = st.nextToken();

} catch( Exception e ) { 
    System.out.println( e.toString() );
    gateway = new String();
    adapter = new String();
}

En Windows, el análisis de la salida de IPConfig le proporcionará la puerta de enlace predeterminada, sin esperar un rastro.

Quizás sea mejor que utilices algo como checkmyip.org, que determinará tu dirección IP pública, no necesariamente tu enrutador de primer salto:en la Universidad tengo una dirección IP "real", mientras que en casa es la dirección IP pública de mi enrutador local.

Puede analizar la página que regresa o buscar otro sitio que le permita recuperar la dirección IP como única cadena.

(Me refiero a cargar esta URL en Java/lo que sea, y luego obtener la información que necesita).

Esto debería ser totalmente independiente de la plataforma.

Respecto a UPnP:Tenga en cuenta que no todos los enrutadores admiten UPnP.Y si lo hacen, podrían apagarlo (por razones de seguridad).Por lo tanto, es posible que su solución no siempre funcione.

También deberías echar un vistazo a NatPMP.

Puede encontrar una biblioteca sencilla para UPnP en http://miniupnp.free.fr/, aunque está en C...

Para superar los problemas mencionados con traceroute (golpe de área amplia basado en ICMP), podría considerar:

  1. traceroute a su IP pública (evita el acceso a un área amplia, pero sigue siendo ICMP)
  2. Utilice una utilidad que no sea ICMP como ifconfig/ipconfig (aunque esto tiene problemas de portabilidad).
  3. Lo que parece la mejor y más portátil solución por ahora es shell y analizar netstat (ver el código de ejemplo aquí)

La salida de netstat -rn es específica de la configuración regional.en mi sistema (locale=de) el resultado se ve así:...Puerta de enlace estándar:10.22.0.1

por lo que no hay ninguna línea que comience con "predeterminado".

por lo que utilizar netstat podría no ser una buena idea.

Esta versión se conecta a www.whatismyip.com, lee el contenido del sitio y busca mediante expresiones regulares la dirección IP y la imprime en el cmd.Es una pequeña mejora del Código MosheElishas.

import java.io.BufferedReader;  
import java.io.IOException;  
import java.io.InputStreamReader; 
import java.net.URL;  
import java.util.regex.Matcher;  
import java.util.regex.Pattern;  

public class Main {

    public static void main(String[] args) {
        BufferedReader buffer = null;
        try {
            URL url = new URL(
                    "http://www.whatismyip.com/tools/ip-address-lookup.asp");
            InputStreamReader in = new InputStreamReader(url.openStream());
            buffer = new BufferedReader(in);
            String line = buffer.readLine();
            Pattern pattern = Pattern
                    .compile("(.*)value=\"(\\d+).(\\d+).(\\d+).(\\d+)\"(.*)");
            Matcher matcher;
            while (line != null) {
                matcher = pattern.matcher(line);
                if (matcher.matches()) {
                    line = matcher.group(2) + "." + matcher.group(3) + "."
                            + matcher.group(4) + "." + matcher.group(5);
                    System.out.println(line);
                }
                line = buffer.readLine();
            }
        } catch (IOException e) {
            e.printStackTrace();

        } finally {
            try {
                if (buffer != null) {
                    buffer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

import java.io.BufferedReader;  
import java.io.IOException;  
import java.io.InputStreamReader; 
import java.net.URL;  
import java.util.regex.Matcher;  
import java.util.regex.Pattern;  

public class Main {

    public static void main(String[] args) {
        BufferedReader buffer = null;
        try {
            URL url = new URL(
                    "http://www.whatismyip.com/tools/ip-address-lookup.asp");
            InputStreamReader in = new InputStreamReader(url.openStream());
            buffer = new BufferedReader(in);
            String line = buffer.readLine();
            Pattern pattern = Pattern
                    .compile("(.*)value=\"(\\d+).(\\d+).(\\d+).(\\d+)\"(.*)");
            Matcher matcher;
            while (line != null) {
                matcher = pattern.matcher(line);
                if (matcher.matches()) {
                    line = matcher.group(2) + "." + matcher.group(3) + "."
                            + matcher.group(4) + "." + matcher.group(5);
                    System.out.println(line);
                }
                line = buffer.readLine();
            }
        } catch (IOException e) {
            e.printStackTrace();

        } finally {
            try {
                if (buffer != null) {
                    buffer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

Eso no es tan fácil como parece.Java es independiente de la plataforma, por lo que no estoy seguro de cómo hacerlo en Java.Soy adivinación que .NET se pone en contacto con algún sitio web que lo informa.Hay un par de caminos por recorrer.En primer lugar, una mirada más profunda al protocolo ICMP puede brindarle la información que necesita.También puedes rastrear la IP por la que pasas (tu ruta).Cuando encuentra una IP que no se encuentra en los siguientes rangos:

  • 10.0.0.0 – 10.255.255.255
  • 172.16.0.0 – 172.31.255.255
  • 192.168.0.0 – 192.168.255.255

es la IP que está a un salto de la suya y probablemente comparte algunos octetos de información con su IP.

Toda la suerte.Tendré curiosidad por escuchar una respuesta definitiva a esta pregunta.

Intente desembolsar traceroute si lo tiene.

'traceroute -m 1 www.amazon.com' emitirá algo como esto:

traceroute to www.amazon.com (72.21.203.1), 1 hops max, 40 byte packets
 1  10.0.1.1 (10.0.1.1)  0.694 ms  0.445 ms  0.398 ms

Analiza la segunda línea.Sí, es feo, pero te mantendrá activo hasta que alguien publique algo mejor.

Mateo:Sí, eso es lo que quise decir con "Puedo obtener mi IP de Internet usando un servicio en un sitio web". Perdón por ser GLIB.

Brian/Nick:Traceroute estaría bien excepto por el hecho de que muchos de estos enrutadores tienen ICMP deshabilitado y, por lo tanto, siempre se bloquea.

Creo que una combinación de traceroute y uPnP funcionará.Eso es lo que estaba planeando hacer, solo esperaba que me estuviera perdiendo algo obvio.

Gracias a todos por sus comentarios, parece que no me estoy perdiendo nada obvio.Comencé a implementar algunos bits de uPnP para descubrir la puerta de enlace.

Puedes consultar la URL "http://whatismyip.com/automation/n09230945.asp".Por ejemplo:

    BufferedReader buffer = null;
    try {
        URL url = new URL("http://whatismyip.com/automation/n09230945.asp");
        InputStreamReader in = new InputStreamReader(url.openStream());
        buffer = new BufferedReader(in);

        String line = buffer.readLine();
        System.out.println(line);
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (buffer != null) {
                buffer.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

En Windows puedes usar el siguiente comando:

ipconfig | findstr /i "Gateway"

Lo que le dará resultados como:

Default Gateway . . . . . . . . . : 192.168.2.1
Default Gateway . . . . . . . . . : ::

Sin embargo, no puedo ejecutar este comando con Java. Publicaré cuando resuelva esto.

Puedes usar netstat -rn comando que está disponible en la plataforma Windows, OSX, Linux, etc.Aquí está mi código:

private String getDefaultAddress() {
        String defaultAddress = "";
        try {
            Process result = Runtime.getRuntime().exec("netstat -rn");

            BufferedReader output = new BufferedReader(new InputStreamReader(
                    result.getInputStream()));

            String line = output.readLine();
            while (line != null) {
                if (line.contains("0.0.0.0")) {

                    StringTokenizer stringTokenizer = new StringTokenizer(line);
                    stringTokenizer.nextElement(); // first element is 0.0.0.0
                    stringTokenizer.nextElement(); // second element is 0.0.0.0
                    defaultAddress = (String) stringTokenizer.nextElement();
                    break;
                }

                line = output.readLine();

            } // while
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return defaultAddress;

} // getDefaultAddress

No estoy seguro de si funciona en todos los sistemas, pero al menos aquí encontré esto:

import java.net.InetAddress;
import java.net.UnknownHostException;
public class Main
{
    public static void main(String[] args)
    {
        try
        {
            //Variables to find out the Default Gateway IP(s)
            String canonicalHostName = InetAddress.getLocalHost().getCanonicalHostName();
            String hostName = InetAddress.getLocalHost().getHostName();

            //"subtract" the hostName from the canonicalHostName, +1 due to the "." in there
            String defaultGatewayLeftover = canonicalHostName.substring(hostName.length() + 1);

            //Info printouts
            System.out.println("Info:\nCanonical Host Name: " + canonicalHostName + "\nHost Name: " + hostName + "\nDefault Gateway Leftover: " + defaultGatewayLeftover + "\n");
            System.out.println("Default Gateway Addresses:\n" + printAddresses(InetAddress.getAllByName(defaultGatewayLeftover)));
        } catch (UnknownHostException e)
        {
            e.printStackTrace();
        }
    }
    //simple combined string out of the address array
    private static String printAddresses(InetAddress[] allByName)
    {
        if (allByName.length == 0)
        {
            return "";
        } else
        {
            String str = "";
            int i = 0;
            while (i < allByName.length - 1)
            {
                str += allByName[i] + "\n";
                i++;
            }
            return str + allByName[i];
        }
    }
}

Para mí esto produce:

Info:
Canonical Host Name: PCK4D-PC.speedport.ip
Host Name: PCK4D-PC
Default Gateway Leftover: speedport.ip

Default Gateway Addresses:
speedport.ip/192.168.2.1
speedport.ip/fe80:0:0:0:0:0:0:1%12

Necesitaría más pruebas en otros sistemas/configuraciones/configuraciones de puerta de enlace de PC para confirmar si funciona en todas partes.Lo dudo un poco, pero esta fue la primera que encontré.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top