views:

738

answers:

3

I'm writing a simple networking app... I need to know the real ip of my machine on the network, like 192.168.1.3 . getLocalHost returns 127.0.0.1 (on Linux, dunno if it is the same on windows) how to do it?;

+1  A: 

Your computer may have multiple IPs. How do you know which one? The way I do it is to have a very simple CGI running on another machine that reports back the IP it's seen, and I hit that when I need to know what my IP looks like to the outside world.

Paul Tomblin
+1  A: 

In my windows,

System.out.println(InetAddress.getLocalHost().getHostAddress());

prints 10.50.16.136

Calm Storm
127.0.1.1 for me (Ubuntu)
sfussenegger
Interesting ... correct answer although it's not working?
sfussenegger
This is very common on SO, the incorrect answered gets marked as answered.
Steve Kuo
@sfussenegger 127.0.1.1 is a Debian thing (which Ubuntu is derived from). IIRC, you will get it if you are using DHCP. This allows reporting a fixed IP address (I believe this is necessary for the smooth running of GNOME). So 127.0.1.1 is a "real IP" address. (BTW: 192.168.* is non-internet IP address.)
Tom Hawtin - tackline
@tom yeah, I know what it is. I'm just wondering how this is the correct answer to the question ("I need to know the real ip of my machine on the network").
sfussenegger
@sfussenegger the *real* answer would be to find a way to query each network interface for its addresses. I don't know a way to do that in Java, but that's how I do it in C.
jdizzle
@jdizzle Why would that be the real answer? The question was how to determine the "the real ip of my machine on the network". How is a list of IPs helpful in answering this question which states that there is only interest in one IP that's used for one specific network?
sfussenegger
@sfussenegger a host can have multiple interfaces and each interface can have multiple IPs. It's just typical that a host usually only has a few intefaces (eg eth0, lo) and it's also typical that each interface only has only one IP. Each IP is just as "real" as the next. The only way to figure out which IP you want is to figure out who you want to talk to and look at the routing table. That's why the google.com hack below is almost good, but, since it leaks information (DNS requests and spurious connects) and is just kind of kludgy, I consider it flawed.
jdizzle
@jdizzle I completely agree. I once made something similar by creating a UDP packat without actually sending it. I think it was C (but might have been Perl), where it was possible to read the source address. Unfortunately, I don't think this is possible in Java though (DatagramPacket doesn't even offer a getSourceAddress() or similar method). I've changed my example to not use DNS though.
sfussenegger
I understand who's perplex about me giving correct to this answer. This is probably because I was more interested in this call results than the actual method of obtaining the IP (of course I know I have to list the interfaces... but I wanted a quick and dirty way). @Tom Hawtin: Real Ip address may mean many things... I meant the INTERFACE address, someone understood a TRANSLATED address. 192.168.* are REAL IP address but they r reserved for LAN use. RTM. Thanks all and sorry for this rubbish question.
gotch4
+4  A: 

As the machine might have multiple addresses, it's hard to determine which one is the one for you. Normally, you want the system to assign an IP based on its routing table. As the result depends on the IP you'd like to connect to, there is a simple trick: Simply create a connection and see what address you've got from the OS:

// instead of google.com, use what makes most sense to you
// output on my machine: "192.168.1.102"
Socket s = new Socket("192.168.1.1", 80);
System.out.println(s.getLocalAddress().getHostAddress());
s.close();

// output on my machine: "127.0.1.1"
System.out.println(InetAddress.getLocalHost().getHostAddress());

I'm not sure whether it's possible to do this without establishing a connection though. I think I've once managed to do it with Perl (or C?), but don't ask me about Java. I think it might be possible to create a UDP socket (DatagramSocket) without actually connecting it.

If there is a NAT router on the way you won't be able to get the IP that remote hosts will see though. However, as you gave 192.* as an example, I think you don't care.

sfussenegger