在Android上使用Boost Asio如何获取本地UDP IP地址?

4
我正在开发一个简单的通讯客户端,它在Windows/Android之间使用Boost-Asio和UDP。当在Windows上解析主机名和IP地址时,我得到的是计算机名称和有效的IP地址。然而,在Android上相应的代码返回localhost127.0.0.1。如何获取其他客户端可用的IP地址?
获取本地IP地址的片段:
  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清单文件:

  <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" />

注释

我通过Java WifiManager找到了正确的IP地址。然而,我希望直接从我的应用程序的C++/boost::asio部分获取它,因为我的网络代码的其余部分都在那里。


我想了解一件小事,你是否在真实设备或Android模拟器上测试过你的应用程序? - seal2002
在真实设备上 :) - Viktor Sehr
1个回答

1
我从未尝试在Android上使用C++编程,而是使用ReactJS或直接使用Java,在那里获得IP的方法可以是:

WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
String ip = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());
我想说的是,在Android系统下,您应该从WifiManager中获取IP地址作为权威来源,这是我从Android专家那里听到的。鉴于您想坚持使用boost::asio,让我们仔细看看您的库。
如果您查看Boost-Asio的源代码,例如boost/asio/ip/host_name.hpp,我看到一个单一的调用boost::asio::detail::socket_ops::gethostname(name, sizeof(name), ec),它位于asio/detail/socket_ops.hpp内。我原以为会有一个循环遍历所有可能的套接字,因为可能有多个接口。在Android下,套接字/接口的顺序对我来说并不明显。
换句话说:也许在Android中,你的库运气不佳,只获取到了错误的套接字,它恰好是使用127.0.0.1作为IP的环回接口。现在,你可以编写自己的asio::ip::gethostname()函数,它尝试多次查询基础的asio::detail::socket_ops::gethostname()

参考资料


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接