35

So, I'm trying to get the IP-Address of my machine in my local network (which should be 192.168.178.41).

My first intention was to use something like this:

InetAddress.getLocalHost().getHostAddress();

but it only returns 127.0.0.1, which is correct but not very helpful for me.

I searched around and found this answer https://stackoverflow.com/a/2381398/717341, which simply creates a Socket-connection to some web-page (e.g. "google.com") and gets the local host address from the socket:

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

This does work for my machine (it returns 192.168.178.41), but it needs to connect to the internet in order to work. Since my application does not require an internet connection and it might look "suspicious" that the app tries to connect to google every time it is launched, I don't like the idea of using it.

So, after some more research I stumbled across the NetworkInterface-class, which (with some work) does also return the desired IP-Address:

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

On my machine, this returns the following:

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

It finds both my network interfaces and returns the desired IP, but I'm not sure what the other address (fe80:0:0:0:226:4aff:fe0d:592e%3) means.

Also, I haven't found a way to filter it from the returned addresses (by using the isXX()-methods of the InetAddress-object) other then using RegEx, which I find very "dirty".

Any other thoughts than using either RegEx or the internet?

Community
  • 1
  • 1
Lukas Knuth
  • 25,449
  • 15
  • 83
  • 111

5 Answers5

24

fe80:0:0:0:226:4aff:fe0d:592e is your ipv6 address ;-).

Check this using

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

If you just care for IPv4, then just discard the IPv6 case. But beware, IPv6 is the future ^^.

P.S.: Check if some of your breaks should have been continues.

yankee
  • 38,872
  • 15
  • 103
  • 162
  • 1
    `getHostAddress()` is present in the `InetAddress` base class, there's no need for casting here (http://docs.oracle.com/javase/6/docs/api/java/net/InetAddress.html#getHostAddress()) – skaffman Jan 06 '12 at 23:13
  • That looks pretty nice and it works. Although just to filter them, you don't need the casts. I am aware of IPv6 being the future, but for my current needs, an IPv4 will do just fine ;-) And of course you're right about the `break`s. I corrected that. Thanks till here! – Lukas Knuth Jan 06 '12 at 23:15
  • 1
    @yankee: Point not taken, I think: The `if` isn't necessary either. – skaffman Jan 07 '12 at 09:44
  • 2
    @skaffmann: True, the if is pointless in this example, but for the sake of explaining how to distinguish between IPv4 and IPv6 I am not going to change that. After all the question also seems to be about extracting just the IPv4 address – yankee Jan 07 '12 at 20:00
  • _Disclaimer:_ This doesn't account for multiple network interfaces which are bound to different addresses. It will only retrieve one and ignore all others. – arkon Jun 15 '13 at 22:22
  • @yankee ...no what? I wasn't asking a question. – arkon Jul 02 '13 at 20:38
  • @b1naryatr0phy once merged into the correct place (of the answer's relevant code) it works just fine at differentiating IPv4 from IPv6. For ***all*** interfaces. – Shark Jul 12 '13 at 16:01
13

Here is also a java 8 way of doing it:

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();
}
tsds
  • 8,700
  • 12
  • 62
  • 83
8
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;
}
Ehud Lev
  • 2,461
  • 26
  • 38
5
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
        }


    }

}

Md Ashaduzzaman
  • 4,032
  • 2
  • 18
  • 34
2

Yankee's answer is correct for the first part. To print out the IP address, you can get it as an array of bytes and convert that to the normal string representation like this:

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());
Russell Zahniser
  • 16,188
  • 39
  • 30
  • What would be the advantage over just using `current_addr.getHostAddress()` ? – Lukas Knuth Jan 06 '12 at 23:18
  • @Lukas Knuth: At first I did not have the prints in my answer. I edited them into the post a minute later since I thought that might be quite helpful ;-). Russell probably did not see that version. – yankee Jan 06 '12 at 23:40
  • Oops, my bad - I assumed that getHostAddress was printing out the full text that yankee was having to regex. I didn't notice the earlier print of current. – Russell Zahniser Jan 07 '12 at 00:11