web-dev-qa-db-ja.com

インターネットに接続せずにローカルIPアドレスを取得する

だから、ローカルネットワークでマシンのIPアドレスを取得しようとしています(_192.168.178.41_でなければなりません)。

私の最初の意図は、次のようなものを使用することでした:

_InetAddress.getLocalHost().getHostAddress();
_

しかし、それは_127.0.0.1_のみを返します。これは正しいですが、私にとってはあまり役に立ちません。

私は周りを検索し、この答えを見つけました https://stackoverflow.com/a/2381398/717341 、これは単にいくつかのWebページ(たとえば、「google.com」へのSocket-)接続を作成します")そして、ソケットからローカルホストアドレスを取得します。

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

これは私のマシンでは動作します(_192.168.178.41_を返します)が、動作するにはインターネットに接続する必要があります。私のアプリケーションはインターネット接続を必要とせず、起動するたびにアプリがグーグルに接続しようとするのは「疑わしい」ように見えるかもしれないので、私はそれを使用するという考えが好きではありません。

そのため、さらに調査した後、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_)の意味がわかりません。

また、(InetAddress- objectのisXX()- methodsを使用して)返されたアドレスからフィルタリングする方法を見つけていませんが、RegExを使用しています。 「。

RegExまたはインターネットを使用する以外の考えはありますか?

34
Lukas Knuth

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は未来です^^。

追伸:breaksの一部がcontinuesであったかどうかを確認します。

24
yankee

また、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();
}
13
tsds
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;
}
8
Ehud Lev
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
Ashad Shanto

ヤンキーの答えは、最初の部分については正しいです。 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());
2