views:

984

answers:

7

I am writing a program in C++ which uses network sockets. I need to find out what the computer's IP address is, so I can display it to the user. The program must run on Windows and Linux.

I have heard somewhere that a computer can have multiple IP addresses. I want the one that other programs on different computers can use to connect to the computer.

Here is the relevant code I already have (the variables are declared in other places):

master = new fd_set;
FD_ZERO(master);
struct sockaddr_in my_addr;

listener = socket(PF_INET, SOCK_STREAM, 0);

my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(port);
my_addr.sin_addr.s_addr = INADDR_ANY;
memset(my_addr.sin_zero, '\0', sizeof my_addr.sin_zero);

bind(listener, (struct sockaddr *)&my_addr, sizeof my_addr);

listen(listener, 10);

FD_SET(listener, master);

fdmax = listener;
+5  A: 

I have heard somewhere that a computer can have multiple IP addresses. I want the one that other programs on different computers can use to connect to the computer.

Well... that could be any of them. If a computer has multiple IP addresses it can be accessed on any one of them. Of course one of them could be subject to different firewall rules or they could be on two completely different segments but there's no way to detect any and all of these circumstances.

Spencer Ruport
This is not true.One computer A belongs to network 1 and 2, and computer B belongs only on network 2, then computer B must use the IP Address for Computer A that is on network 2.
Alan
How is it not true? You're right, of course, that computer B would have to use the network 2 address, but that's basically reiterating Spencer's point about different network segments. There's simply no way, programmatically, of determining which IP address the end user is going to need.
Rob
@Rob: Whoops you're right, I must have missed that part about different segments.
Alan
To complicate the issue, the machine in question may be behind a router or load balancer that is performing NAT.
Darron
A: 

It depends if you're trying to get your LAN IP address (i.e. the address of your computer within the set of your computers) or the IP address your service provider gives to you every time you connect to the internet. The latter can be identified with a query (I guess that you would find a proper C++ library that does that with little Googling) to some IP detecting web services.

If you want a quick and dirty solution you could try to wget http://www.whatismyip.org and read back the contents.

tunnuz
This works if you want the IP address that is seen on the Internet. But unless the computer is Internet facing, this is usually a NAT'ed address handled by a firewall and not actually reflective of the actual IP of the computer system itself.
K. Brian Kelley
You're right, but this somehow falls in the first option I pointed out. In that case you probably want your LAN address since you share your WAN address with other systems.
tunnuz
+2  A: 

I believe you can use getaddrinfo() with your listener socket, to obtain the IP Address of the socket you bound to.

Alan
+5  A: 

I posted a similar question, but on OS X recently. The answer that I received was to use either 0.0.0.0 or INADDR_ANY. This will cause your socket to listen on all available addresses, so you don't need to figure out which one is the "right" one.

Andy
Of course if you're on OSX you'll not want to do this, because listening on some of the tunneling sockets are CPU expensive even when idle. Getaddrinfo() with a specific IP version...
ceretullis
That's fair. I'm just writing a small app for me, but your point is taken.
Andy
+4  A: 

On Windows, you want to use GetAdaptersAddresses - this lists all of the adapters in your machine and the IP addresses bound to them. It supports IPv6 addresses too. You can also use gethostbyname, but that doesn't support IPv6.

On Linux, we read /proc/net/dev and /proc/net/if_inet6 and parse the results of that.

Graeme Perrow
A: 

You can use the light-weighted client/server socket class in C++ project for reference.

Igor Oks
A: 

It is not advisable to use software rather we can use link text for finding the Ip-details easily and quickly

If you are behind a router doing NAT, it will return the router address, not your own. The OP states "I want the one that other programs on different computers can use to connect to the computer.". I won't help for computers behind the router, as they can't connect anyway. And for machines in the local network, it doesn't work either. So it won't help the OP.
Frank