Подтвердить что ты не робот

Получить локальный IP-адрес без подключения к Интернету

Итак, я пытаюсь получить IP-адрес моего компьютера в своей локальной сети (который должен быть 192.168.178.41).

Мое первое намерение состояло в том, чтобы использовать что-то вроде этого:

InetAddress.getLocalHost().getHostAddress();

но возвращает только 127.0.0.1, что является правильным, но не очень полезным для меня.

Я обыскал и нашел этот ответ qaru.site/info/134804/..., который просто создает соединение Socket на какой-либо веб-странице (например, "google.com" ) и получает локальный адрес узла из сокета:

Socket s = new Socket("google.com", 80);
System.out.println(s.getLocalAddress().getHostAddress());
s.close();

Это работает для моей машины (она возвращает 192.168.178.41), но для ее работы необходимо подключиться к Интернету. Поскольку мое приложение не требует подключения к Интернету и может выглядеть "подозрительным", что приложение пытается подключиться к Google при каждом запуске, мне не нравится идея его использования.

Итак, после нескольких исследований я наткнулся на класс NetworkInterface, который (с некоторой работой) также возвращает желаемый IP-адрес:

Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()){
    NetworkInterface current = interfaces.nextElement();
    System.out.println(current);
    if (!current.isUp() || current.isLoopback() || current.isVirtual()) continue;
    Enumeration<InetAddress> addresses = current.getInetAddresses();
    while (addresses.hasMoreElements()){
        InetAddress current_addr = addresses.nextElement();
        if (current_addr.isLoopbackAddress()) continue;
        System.out.println(current_addr.getHostAddress());
    }
}

На моей машине это возвращает следующее:

name:eth1 (eth1)
fe80:0:0:0:226:4aff:fe0d:592e%3
192.168.178.41
name:lo (lo)

Он находит оба моих сетевых интерфейса и возвращает желаемый IP-адрес, но я не уверен, что означает другой адрес (fe80:0:0:0:226:4aff:fe0d:592e%3).

Кроме того, я не нашел способ отфильтровать его из возвращаемых адресов (используя методы isXX() объекта InetAddress -object), а затем использовать RegEx, который я считаю очень "грязным".

Любые другие мысли, чем использование RegEx или интернет?

4b9b3361

Ответ 1

fe80: 0: 0: 0: 226: 4aff: fe0d: 592e - ваш адрес ipv6; -).

Проверьте это, используя

if (current_addr instanceof Inet4Address)
  System.out.println(current_addr.getHostAddress());
else if (current_addr instanceof Inet6Address)
  System.out.println(current_addr.getHostAddress());

Если вы просто заботитесь о IPv4, просто отбросьте IPv6. Но будьте осторожны, IPv6 - это будущее ^^.

P.S.: Проверьте, были ли некоторые из ваших break continue s.

Ответ 2

Здесь также есть способ java 8:

public static String getIp() throws SocketException {

    return Collections.list(NetworkInterface.getNetworkInterfaces()).stream()
            .flatMap(i -> Collections.list(i.getInetAddresses()).stream())
            .filter(ip -> ip instanceof Inet4Address && ip.isSiteLocalAddress())
            .findFirst().orElseThrow(RuntimeException::new)
            .getHostAddress();
}

Ответ 3

public static String getIp(){
    String ipAddress = null;
    Enumeration<NetworkInterface> net = null;
    try {
        net = NetworkInterface.getNetworkInterfaces();
    } catch (SocketException e) {
        throw new RuntimeException(e);
    }

    while(net.hasMoreElements()){
        NetworkInterface element = net.nextElement();
        Enumeration<InetAddress> addresses = element.getInetAddresses();
        while (addresses.hasMoreElements()){
            InetAddress ip = addresses.nextElement();
            if (ip instanceof Inet4Address){

                if (ip.isSiteLocalAddress()){

                    ipAddress = ip.getHostAddress();
                }

            }

        }
    }
    return ipAddress;
}

Ответ 4

import java.net.*;

public class Get_IP
{
    public static void main(String args[])
    {
        try
        {
            InetAddress addr = InetAddress.getLocalHost();
            String hostname = addr.getHostName();
            System.out.println(addr.getHostAddress());
            System.out.println(hostname);
        }catch(UnknownHostException e)
        {
             //throw Exception
        }


    }

}

Ответ 5

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

StringBuilder ip = new StringBuilder();
for(byte b : current_addr.getAddress()) {
    // The & here makes b convert like an unsigned byte - so, 255 instead of -1.
    ip.append(b & 0xFF).append('.');
}
ip.setLength(ip.length() - 1); // To remove the last '.'
System.out.println(ip.toString());