Pergunta

Como posso determinar o IP do meu roteador/gateway em Java?Posso obter meu IP com bastante facilidade.Posso obter meu IP de Internet usando um serviço em um site.Mas como posso determinar o IP do meu gateway?

Isso é um tanto fácil no .NET se você souber o que fazer.Mas como você faz isso em Java?

Foi útil?

Solução

Java não faz isso tão agradável quanto outros idiomas, infelizmente. Aqui está o que eu fiz:

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);
    }
}

Isso pressupõe que o gateway é o segundo token e não o terceiro. Se for, você precisa adicionar um st.nextToken(); extra para avançar o tokenizer mais um ponto.

Outras dicas

No Windows, OSX, Linux, etc, em seguida, a resposta de Chris Bunch pode ser muito melhorado usando

netstat -rn

no lugar de um comando traceroute.

O endereço IP da gateway irá aparecer no segundo campo da linha que começa quer default ou 0.0.0.0.

Este fica em torno de uma série de problemas com a tentativa de uso traceroute:

  1. no Windows traceroute é realmente tracert.exe, por isso não há necessidade de O / S dependências no código
  2. é um comando rápido para correr - ele recebe informações do O / S, não a partir da rede
  3. traceroute às vezes é bloqueada pela rede

A única desvantagem é que será necessário para manter a leitura linhas da saída netstat até a linha certa é encontrada, uma vez que haverá mais de uma linha de saída.

EDIT: O padrão do Gateway Endereço IP é no segundo campo da linha que começa com 'default' se você estiver em uma MAC (testado em Lion), ou na terceiro campo da linha que começa com '0.0.0.0' (testado em Windows 7)

Windows:

Rede de Destino Máscara de rede Gateway Interface Metric

0.0.0.0 0.0.0.0 192.168.2.254 192.168.2.46 10

Mac:

Destinos gateway Flags Refs Use Netif expirar

padrão 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();
}

No windows analisando a saída de IPConfig você irá obter o gateway padrão, sem esperar por um traço.

Você pode ser melhor fora de usar algo como checkmyip.org, o que vai determinar o seu endereço IP público - não necessariamente o seu primeiro roteador hop: a Uni Eu tenho um endereço IP "real", enquanto que em casa é pública do meu roteador local endereço IP.

Você pode analisar a página que os retornos, ou encontrar um outro local que permite que você apenas obter o endereço IP de volta como a única string.

(estou significando carga esta URL em Java / whatever, e, em seguida, obter a informação que você precisa).

Este deve ser totalmente independente de plataforma.

Em relação UPnP: estar ciente de que nem todos os roteadores suportam UPnP. E se eles fazem isso pode ser desligado (por razões de segurança). Então, a solução pode nem sempre trabalho.

Você também deve ter um olhar para NatPMP.

Uma biblioteca simples para UPnP podem ser encontradas em http://miniupnp.free.fr/ , embora seja em C ...

Para superar os problemas mencionados com traceroute (baseado em ICMP, área de ocorrência de largura) você poderia considerar:

  1. traceroute para o seu IP público (hit evita de área ampla, mas ainda ICMP)
  2. Use um utilitário não-ICMP como ifconfig / ipconfig (problemas de portabilidade com este embora).
  3. O que parece ser a solução melhor e mais portátil para agora é que desembolsar & netstat parse (veja o exemplo de código aqui )

saída do -rn netstat é específico do idioma. no meu sistema (locale = de) os olhares de saída como: ... Standardgateway: 10.22.0.1

então não há nenhuma linha iniciada com 'default'.

portanto, usando netstat pode haver boa idéia.

Esta versão se conecta a www.whatismyip.com, lê o conteúdo do site e pesquisas via expressões regulares o endereço IP eo imprime ao cmd. É um pouco melhoria do 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();
            }
        }
    }
}

Isso não é tão fácil quanto parece. Java é uma plataforma independente, então eu não sei como fazê-lo em Java. Estou adivinhação que os contactos .NET algum site que informa-lo de volta. Existem algumas maneiras de ir. Primeiro, um olhar mais profundo sobre o protocolo ICMP pode lhe dar a informação que você precisa. Você também pode rastrear o IP que você passar por (sua rota). Quando você encontrar um IP que não é nos seguintes intervalos:

  • 10.0.0.0 - 10.255.255.255
  • 172.16.0.0 - 172.31.255.255
  • 192.168.0.0 - 192.168.255.255

é o IP de um salto de distância da sua, e provavelmente compartilha algumas octetos de informações com o seu IP.

O melhor de sorte. Eu vou estar curioso para ouvir uma resposta definitiva para esta questão.

Tente descascar para fora para traceroute se você tê-lo.

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

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

Parse a segunda linha. Sim, é feio, mas vou tirar você vai até alguém postar algo mais agradável.

Mateus: Sim, isso é o que eu quis dizer com "eu posso conseguir o meu IP internet usando um serviço em um site." Desculpe por ser simplista.

Brian / Nick:. Traceroute seria muito bem, exceto pelo fato de que muitos desses roteadores têm ICMP desativado e, portanto, sempre barracas

Eu acho que uma combinação de traceroute e uPnP vai dar certo. Isso é o que eu estava pensando em fazer, eu como apenas esperando que eu estava faltando alguma coisa óbvia.

Obrigado a todos por seus comentários, por isso soa como se eu não estou faltando alguma coisa óbvia. I começaram a implementar alguns pedaços de uPnP, a fim de descobrir o gateway.

Você pode consultar o URL " http://whatismyip.com/automation/n09230945.asp". Por exemplo:

    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();
        }
    }

No windows você pode apenas usar o seguinte comando:

ipconfig | findstr /i "Gateway"

O que vai lhe dar uma saída como:

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

No entanto, eu não pode executar este comando com Java, vou postar quando eu descobrir isso.

Você pode usar o comando netstat -rn que está disponível no Windows, OSX, Linux, etc plataforma. Aqui está o meu 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

Eu não tenho certeza se ele funciona em todos os sistemas, mas pelo menos aqui eu encontrei isto:

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 mim, este produz:

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

Eu exigem mais testes em outros sistemas / Configurações / PC-gateway-configurações para confirmar se ele funciona em todos os lugares. Tipo de dúvida, mas esta foi a primeira que eu encontrei.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top