Отримання „зовнішньої” IP-адреси в Java


83

Я не надто впевнений, як дістатись із отриманням зовнішньої IP-адреси машини, як це бачить комп'ютер поза мережею.

Мій наступний клас IPAddress отримує лише локальну IP-адресу машини.

public class IPAddress {

    private InetAddress thisIp;

    private String thisIpAddress;

    private void setIpAdd() {
        try {
            InetAddress thisIp = InetAddress.getLocalHost();
            thisIpAddress = thisIp.getHostAddress().toString();
        } catch (Exception e) {
        }
    }

    protected String getIpAddress() {
        setIpAdd();
        return thisIpAddress;
    }
}

13
Вам відомо, що машина може мати багато публічних адрес одночасно? Вони справді пов'язані з мережевим інтерфейсом, а не з машиною.
Donal Fellows

Відповіді:


168

Я не впевнений, чи можете ви захопити цей IP із коду, який працює на локальній машині.

Однак ви можете створити код, який працює на веб-сайті, скажімо в JSP, а потім використовувати щось, що повертає IP-адресу, звідки надійшов запит:

request.getRemoteAddr()

Або просто скористайтеся вже існуючими службами, які роблять це, а потім проаналізуйте відповідь служби, щоб дізнатися IP.

Використовуйте веб-сервіс, такий як AWS та інші

import java.net.*;
import java.io.*;

URL whatismyip = new URL("http://checkip.amazonaws.com");
BufferedReader in = new BufferedReader(new InputStreamReader(
                whatismyip.openStream()));

String ip = in.readLine(); //you get the IP as a String
System.out.println(ip);

4
Слово попередження: вони налаштували URL-адресу автоматизації
thegrinner

8
Я б запропонував застосувати принаймні два сервери, які обслуговують ваш ip, на випадок, якщо на даний момент один із них не працює (звичайно, з правильною обробкою помилок). Моїм вибором буде externalip.net (натисніть посилання "Потрібен API?"). Користуюся цим сайтом вже більше року, до цього часу не мав жодних проблем, і це швидка послуга, яка завжди повертає швидку реакцію.

Дивовижне посилання; Я буду використовувати це як частину доказу концепції для завдання університетських мереж!
araisbec

Іншою альтернативою може бути, якщо у вас є доступ до веб-сервера або облікового запису хоста, на якому запущений PHP, просто скористайтеся наведеним вище кодом @bakkal і наведіть його на власний файл PHP, який просто містить echo $_SERVER['REMOTE_ADDR'];. Якщо це єдиний або перший вихідний рядок сценарію, ви все готові.
Kingsolmn

7
Здається, Whatsmyip.com більше не підтримує цей тип автоматизації.
Kingsolmn

79

Один із коментарів @stivlo заслуговує на відповідь:

Ви можете скористатися послугою Amazon http://checkip.amazonaws.com

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;

public class IpChecker {

    public static String getIp() throws Exception {
        URL whatismyip = new URL("http://checkip.amazonaws.com");
        BufferedReader in = null;
        try {
            in = new BufferedReader(new InputStreamReader(
                    whatismyip.openStream()));
            String ip = in.readLine();
            return ip;
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

19

Правда в тому, що "ти не можеш" у тому сенсі, в якому ти поставив питання. NAT відбувається поза протоколом. Ядро вашої машини не може знати, як ваш поле NAT відображає зовнішні на внутрішні IP-адреси. Інші відповіді тут пропонують трюки, що стосуються методів спілкування із зовнішніми веб-сайтами.


3
Або ні, оскільки це не відповідає на вихідне запитання, і це виглядає як академічна вправа
Бруно Боссола

Чесно кажучи, ця відповідь відповідає на запитання, а інші десятки відповідей в основному говорять про одне і те ж, але показують код або URL-адреси, характерні для будь-якого вибраного зовнішнього засобу перевірки ip.
Томас Карлайл,

14

Все це все ще працює і працює безперебійно! (станом на 23 вересня 2019 р.)

Порада: Не залежайте прямо від одного з них; спробуйте використати одне, але розгляньте інші, щоб мати план контингенту! Чим більше ви використовуєте, тим краще!

Удачі!


12

Як писав @Donal Fellows, вам потрібно запитати мережевий інтерфейс замість машини. Цей код з javadocs працював у мене:

У наведеному нижче прикладі програми перераховані всі мережеві інтерфейси та їх адреси на машині:

import java.io.*;
import java.net.*;
import java.util.*;
import static java.lang.System.out;

public class ListNets {

    public static void main(String args[]) throws SocketException {
        Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
        for (NetworkInterface netint : Collections.list(nets))
            displayInterfaceInformation(netint);
    }

    static void displayInterfaceInformation(NetworkInterface netint) throws SocketException {
        out.printf("Display name: %s\n", netint.getDisplayName());
        out.printf("Name: %s\n", netint.getName());
        Enumeration<InetAddress> inetAddresses = netint.getInetAddresses();
        for (InetAddress inetAddress : Collections.list(inetAddresses)) {
            out.printf("InetAddress: %s\n", inetAddress);
        }
        out.printf("\n");
     }
} 

Далі подано зразок вихідних даних з прикладу програми:

Display name: TCP Loopback interface
Name: lo
InetAddress: /127.0.0.1

Display name: Wireless Network Connection
Name: eth0
InetAddress: /192.0.2.0

З docs.oracle.com


1
Дякую! Хоча це рішення не буде працювати, коли програмне забезпечення знаходиться позаду NAT, воно все ще дуже корисно для серверного програмного забезпечення, яке, як ви знаєте, не буде за NAT, або як резервний варіант, якщо програмне забезпечення не може підключитися до іншого сервера, щоб отримати своє власне IP. Зокрема, для програмного забезпечення, призначеного для роботи в локальних мережах, відключених від Інтернету, це шлях.
Павон

6

Зробіть підключення HttpURLC до якогось веб-сайту, такого як www.whatismyip.com, та проаналізуйте його :-)


5

Як щодо цього? Це просто і працювало найкраще для мене :)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;


public class IP {
    public static void main(String args[]) {
        new IP();
    }

    public IP() {
        URL ipAdress;

        try {
            ipAdress = new URL("http://myexternalip.com/raw");

            BufferedReader in = new BufferedReader(new InputStreamReader(ipAdress.openStream()));

            String ip = in.readLine();
            System.out.println(ip);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Це чудово! Я спробую, коли повернусь додому. Це саме той тип вирішення проблем, який я шукав. Не знаю, чому за нього не проголосували вище.
Адам893,

4

http://jstun.javawi.de/ зробить це - за умови, що пристрій шлюзу робить STUN) більшість робить)


1
Досить цікаво, це працює, як очікувалося, без використання зовнішніх служб, а просто спілкуючись із шлюзом. Однак ліцензія GPL, ймовірно, обмежить її прийняття.
Bruno Bossola

Сайт дає мені екран входу. Можливо, не оригінал.
Jus12,

1

Це не так просто, оскільки машина всередині локальної мережі, як правило, не дбає про зовнішній IP свого маршрутизатора до Інтернету .. їй це просто не потрібно!

Я б запропонував вам скористатися цим, відкривши такий веб-сайт, як http://www.whatismyip.com/, і отримавши IP-номер, проаналізувавши результати html .. це не повинно бути так важко!


2
Вам не потрібно аналізувати html. Перший рядок джерела веб-сторінки whatismyip.com - це ваш зовнішній IP.
Martijn Courteaux

0

Якщо ви використовуєте веб-програму, засновану на JAVA, і хочете захопити зовнішній ip клієнта (Той, хто робить запит через браузер), спробуйте розгорнути додаток у загальнодоступному домені та скористайтеся request.getRemoteAddr () для зчитування зовнішньої IP-адреси.



0

Альтернативним рішенням є виконання зовнішньої команди, очевидно, це рішення обмежує портативність програми.

Наприклад, для програми, яка працює в Windows, команда PowerShell може бути виконана через jPowershell, як показано в наступному коді:

public String getMyPublicIp() {
    // PowerShell command
    String command = "(Invoke-WebRequest ifconfig.me/ip).Content.Trim()";
    String powerShellOut = PowerShell.executeSingleCommand(command).getCommandOutput();

    // Connection failed
    if (powerShellOut.contains("InvalidOperation")) {
        powerShellOut = null;
    }
    return powerShellOut;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.