Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get Local IP-Address using Boost.Asio

I'm currently searching for a portable way of getting the local IP-addresses. Because I'm using Boost anyway I thought it would be a good idea to use Boost.Asio for this task.

There are several examples on the net which should do the trick. Examples:

Official Boost.Asio Documentation

Some Asian Page

I tried both codes with just slight modifications. The Code on Boost.Doc was changed to not resolve "www.boost.org" but "localhost" or my hostname instead. For getting the hostname I used boost::asio::ip::host_name() or typed it directly as a string.

Additionally I wrote my own code which was a merge of the above examples and my (little) knowledge I gathered from the Boost Documentation and other examples.

All the sources worked, but they did just return the following IP:
127.0.1.1 (That's not a typo, its .1.1 at the end)
I run and compiled the code on Ubuntu 9.10 with GCC 4.4.1

A colleague tried the same code on his machine and got
127.0.0.2 (Not a typo too...)
He compiled and run on Suse 11.0 with GCC 4.4.1 (I'm not 100% sure)

I don't know if it is possible to change the localhost (127.0.0.1), but I know that neither me or my colleague did it. ifconfig says loopback uses 127.0.0.1. ifconfig also finds the public IP I am searching for (141.200.182.30 in my case, subnet is 255.255.0.0)

So is this a Linux-issue and the code is not as portable as I thought? Do I have to change something else or is Boost.Asio not working as a solution for my problem at all?

I know there are much questions about similar topics on Stackoverflow and other pages, but I cannot find information which is useful in my case. If you got useful links, it would be nice if you could point me to it.

PS: Here is the modified code I used from Boost.Doc:

#include <boost/asio.hpp> using boost::asio::ip::tcp;      boost::asio::io_service io_service; tcp::resolver resolver(io_service); tcp::resolver::query query(boost::asio::ip::host_name(), ""); tcp::resolver::iterator iter = resolver.resolve(query); tcp::resolver::iterator end; // End marker. while (iter != end) {     tcp::endpoint ep = *iter++;     std::cout << ep << std::endl; } 
like image 853
MOnsDaR Avatar asked Apr 20 '10 10:04

MOnsDaR


2 Answers

Here's a trick I learned from python network programming (google) to figure out my machine's ip address. This only works if you have an internet connection and can connect to google.com and does give me my home machine's 192.168.x.x private address.

try {     boost::asio::io_service netService;     udp::resolver   resolver(netService);     udp::resolver::query query(udp::v4(), "google.com", "");     udp::resolver::iterator endpoints = resolver.resolve(query);     udp::endpoint ep = *endpoints;     udp::socket socket(netService);     socket.connect(ep);     boost::asio::ip::address addr = socket.local_endpoint().address();     std::cout << "My IP according to google is: " << addr.to_string() << std::endl;  } catch (std::exception& e){     std::cerr << "Could not deal with socket. Exception: " << e.what() << std::endl;   } 
like image 144
SJL Avatar answered Sep 28 '22 02:09

SJL


You can find "your" address with the code you posted. BUT... it gets complicated. There may be multiple NICs, there may be LAN and WAN addresses, wired and wireless, loopback... On my desktop i had one NIC but two ips here from two diff DHCP servers on my lan...

I found it was better to let the user provide the IP to bind to as a command line parameter. And yes, that's a portable solution! :-)

like image 32
moodboom Avatar answered Sep 28 '22 04:09

moodboom