Как я могу определить IP-адрес моего маршрутизатора/шлюза в Java?

StackOverflow https://stackoverflow.com/questions/11930

  •  08-06-2019
  •  | 
  •  

Вопрос

Как я могу определить IP-адрес моего маршрутизатора/шлюза в Java?Я могу получить свой IP достаточно легко.Я могу получить свой IP-адрес в Интернете, используя услугу на веб-сайте.Но как я могу определить IP моего шлюза?

В .NET это довольно просто, если вы разбираетесь в этом.Но как это сделать на Java?

Это было полезно?

Решение

К сожалению, в Java это не так приятно, как в других языках.Вот что я сделал:

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

Это предполагает, что шлюзом является второй токен, а не третий.Если это так, вам нужно добавить дополнительный st.nextToken(); чтобы продвинуть токенизатор еще на одну позицию.

Другие советы

В Windows, OSX, Linux и т. д. ответ Криса Банча можно значительно улучшить, используя

netstat -rn

вместо traceroute команда.

IP-адрес вашего шлюза появится во втором поле строки, которая начинается либо default или 0.0.0.0.

Это позволяет обойти ряд проблем, связанных с попыткой использования traceroute:

  1. в Windows traceroute на самом деле tracert.exe, поэтому нет необходимости в зависимостях ОС в коде
  2. это быстрая команда для запуска — она получает информацию от операционной системы, а не из сети
  3. traceroute иногда блокируется сетью

Единственным недостатком является то, что придется постоянно читать строки из netstat выводить до тех пор, пока не будет найдена правильная строка, поскольку выводимых строк будет более одной.

РЕДАКТИРОВАТЬ: IP-адрес шлюза по умолчанию указан во втором поле строки, которая начинается с «по умолчанию», если вы используете MAC (протестировано на Lion) или в третье поле строки, которая начинается с «0.0.0.0» (проверено в Windows 7)

Окна:

Сетевая маска назначения Метрика интерфейса шлюза

0.0.0.0 0.0.0.0 192.168.2.254 192.168.2.46 10

Мак:

Флаги шлюза назначения. Ссылки используют Netif Expire.

по умолчанию 192.168.2.254 УГСк 104 4 ен1

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

В Windows анализ результатов IPConfig предоставит вам шлюз по умолчанию, не дожидаясь трассировки.

Возможно, вам лучше использовать что-то вроде checkmyip.org, который определит ваш общедоступный IP-адрес — не обязательно ваш маршрутизатор первого перехода:в Uni у меня есть «настоящий» IP-адрес, тогда как дома это общедоступный IP-адрес моего локального маршрутизатора.

Вы можете проанализировать возвращаемую страницу или найти другой сайт, который позволит вам просто получить обратно IP-адрес в виде единственной строки.

(Я имею в виду загрузить этот URL-адрес в Java или что-то еще, а затем получить необходимую информацию).

Это должно быть полностью независимо от платформы.

По поводу UPnP:имейте в виду, что не все маршрутизаторы поддерживают UPnP.А если и сделают, то его можно будет отключить (по соображениям безопасности).Поэтому ваше решение может не всегда работать.

Вам также следует взглянуть на NatPMP.

Простую библиотеку для UPnP можно найти по адресу http://miniupnp.free.fr/, хотя это на C...

Чтобы преодолеть проблемы, упомянутые с помощью трассировки (обширный охват на основе ICMP), вы можете рассмотреть:

  1. трассировка вашего общедоступного IP-адреса (избегает широкого распространения, но все же ICMP)
  2. Используйте утилиту, не поддерживающую ICMP, например ifconfig/ipconfig (хотя при этом возникают проблемы с переносимостью).
  3. На данный момент лучшим и наиболее переносимым решением является обработка и анализ netstat (см. пример кода). здесь)

Вывод netstat -rn зависит от локали.в моей системе (locale=de) вывод выглядит так:...Стандартный шлюз:10.22.0.1

поэтому нет строки, начинающейся с «по умолчанию».

поэтому использование netstat может быть не очень хорошей идеей.

Эта версия подключается к www.whatismyip.com, считывает содержимое сайта, ищет с помощью регулярных выражений IP-адрес и печатает его в cmd.Это небольшое улучшение Кодекса МошеЭлишаса.

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

Это не так просто, как кажется.Java не зависит от платформы, поэтому я не знаю, как это сделать на Java.Я угадывание что .NET связывается с каким-то веб-сайтом, который сообщает об этом.Есть несколько способов пойти.Во-первых, более глубокое изучение протокола ICMP может дать вам необходимую информацию.Вы также можете отслеживать IP-адрес, через который вы проходите (ваш маршрут).Когда вы сталкиваетесь с IP-адресом, который не находится в следующих диапазонах:

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

это IP-адрес, находящийся на расстоянии одного шага от вашего, и, вероятно, он разделяет несколько октетов информации с вашим IP-адресом.

Удачи.Мне будет интересно услышать окончательный ответ на этот вопрос.

Попробуйте использовать трассировку, если она у вас есть.

'traceroute -m 1 www.amazon.com' выдаст что-то вроде этого:

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

Разберите вторую строку.Да, это некрасиво, но это поможет вам двигаться дальше, пока кто-нибудь не опубликует что-нибудь получше.

Мэтью:Да, это то, что я имел в виду, «я могу получить свой интернет -IP с помощью услуги на веб -сайте». Извините за то, что он глиб.

Брайан/Ник:С Traceroute все было бы в порядке, за исключением того факта, что на многих из этих маршрутизаторов ICMP отключен, и поэтому он всегда зависает.

Я думаю, что комбинация трассировки и uPnP сработает.Это то, что я планировал сделать, я просто надеялся, что упустил что-то очевидное.

Спасибо всем за ваши комментарии, похоже, я не упускаю ничего очевидного.Я начал внедрять некоторые элементы uPnP, чтобы обнаружить шлюз.

Вы можете запросить URL-адрес "http://whatismyip.com/automation/n09230945.asp".Например:

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

В Windows вы можете просто использовать следующую команду:

ipconfig | findstr /i "Gateway"

Что даст вам такой результат:

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

Однако я не могу запустить эту команду с Java, опубликую, когда выясню это.

Вы можете использовать netstat -rn команда, доступная на платформах Windows, OSX, Linux и т. д.Вот мой код:

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

Я не уверен, что это работает на каждой системе, но, по крайней мере, здесь я нашел это:

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

Для меня это производит:

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

Мне бы потребовалось больше тестов на других системах/конфигурациях/настройках ПК-шлюза, чтобы подтвердить, работает ли он везде.Немного сомневаюсь, но это было первое, что я нашел.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top