4

I'm working on a simple communication client in-between Windows/Android using Boost-Asio and UDP. When resolving the hostname and ip address on Windows I get my computer name and a valid ip-address. However, the equivalent code on android returns localhost and 127.0.0.1. How can I obtain an ip-address usable from other clients?

Snippet for obtaining local ip address

  auto io_service = asio::io_service();
  auto resolver = asio::ip::udp::resolver(io_service);
  const auto host_name = asio::ip::host_name(); // "localhost" on android
  const auto query = asio::ip::udp::resolver::query(host_name, "");
  const auto begin = resolver.resolve(query);
  const auto end = asio::ip::udp::resolver::iterator{};
  for (
    auto it = resolver.resolve(query);
    it != end;
    ++it
  ) { auto ip = it->endpoint().address(); } // only 127.0.0.1 on android

Android Manifest:

  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

Notes

I do find the correct ip-address via the Java WifiManager. However, I would like to obtain it directly from the C++/boost::asio side of my application where the rest of the network code is.

B--rian
  • 5,578
  • 10
  • 38
  • 89
Viktor Sehr
  • 12,825
  • 5
  • 58
  • 90

1 Answers1

1

I never tried to code in C++ for Android, but rather in ReactJS or directly in Java where a way of obtaining the IP would be e.g.

WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
String ip = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());

What I am saying is that you should most probably be obtaining the IP from the WifiManager as authoritative source under Android - that is what my I keep hearing from Android gurus. Given that you want to stick to boost::asio, let's have a closer look to your library.

If you look into the source code of Boost-Asio, e.g. at boost/asio/ip/host_name.hpp I see a single call of boost::asio::detail::socket_ops::gethostname(name, sizeof(name), ec) which is located within asio/detail/socket_ops.hpp. I was expecting a loop over all possible sockets since there can be multiple interfaces. It is not obvious to me which order the sockets/ interfaces have under Android.

In other words: Maybe under Android your library is just (un)lucky to get the wrong socket which happens to be the loopback interface with 127.0.0.1 as IP. You could now write your own asio::ip::gethostname() function which tries to query the underlying asio::detail::socket_ops::gethostname() more than once.

References

B--rian
  • 5,578
  • 10
  • 38
  • 89