获取运行我的应用程序的 Android 设备 IP 的最可靠方法是啥?不是公网IP
Posted
技术标签:
【中文标题】获取运行我的应用程序的 Android 设备 IP 的最可靠方法是啥?不是公网IP【英文标题】:What is the most reliable way to get the IP of the Android device my app is running on? Not the public IP获取运行我的应用程序的 Android 设备 IP 的最可靠方法是什么?不是公网IP 【发布时间】:2018-11-15 07:33:06 【问题描述】:我有一个应用程序,它有一个网络服务器,用户可以从他们的家庭 LAN 访问该服务器。目前我有两种获取设备 IP 的方法,我不知道哪一种更可能是正确的。
我的正常方式:
List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface intf : interfaces)
List<InetAddress> addrs = Collections.list(intf.getInetAddresses());
for (InetAddress addr : addrs)
if (!addr.isLoopbackAddress())
String sAddr = addr.getHostAddress().toUpperCase();
我的替代方式:
WifiInfo connectionInfo = wifiMgr.getConnectionInfo();
int ip = connectionInfo.getIpAddress();
我认为这一切正常,但我确实有一些统计数据,而且这两个 ip 似乎只有大约 4% 的时间不同。
另外,我刚刚在 Chromebook 上尝试了我的应用程序,替代方式实际上是正确的方式,而不是正常方式。
那么我怎么知道哪种方式更好或者有更好的选择呢?
【问题讨论】:
【参考方案1】:与公共互联网上的某物建立 TCP 连接,然后检查该套接字的源 IP。
/JB
【讨论】:
【参考方案2】:我建议您将 IP 内容移至服务器/后端部分。它更可靠且通常更容易(您不必处理android API)来确定服务器上的此类内容,因为大多数连接属性都以标头字段的形式传递给您。
您可以在以下标头中查找客户端 ip(这取决于您的服务器设置,但在大多数情况下就足够了):
“X-Forwarded-For”, “Proxy-Client-IP”(如果服务器位于代理之后) “WL-代理-客户端-IP”, “HTTP_X_FORWARDED_FOR”, “HTTP_X_FORWARDED”, “HTTP_X_CLUSTER_CLIENT_IP”, “HTTP_CLIENT_IP”, “HTTP_FORWARDED_FOR”, “HTTP_FORWARDED”, “HTTP_VIA”, “REMOTE_ADDR”由于您在其中一些标头中说您仅从本地网络访问您的服务器,因此您将仅获得您的本地 IP
【讨论】:
没有外部服务器,android中的app是服务器,客户端和手机在同一个网络内,所以通信都是在同一个网络内。 好的,当我说服务器/后端部分是指您的后端应用程序时,这将适用于外部或内部网络,因为协议是相同的 我想我应该澄清一下。我的应用程序是 android 上的服务器。它所知道的只是电话,在其他任何地方都没有任何组件。它为用户提供服务器地址(Android 手机地址加上端口),供用户放入将访问我的服务器的客户端。我对客户端没有任何控制权,客户端不是由我控制或编写的。这一切都是在内部网络中完成的,永远不需要外部访问,只需局域网访问。 啊哈,所以您将您的 android 应用程序公开为后端部分? 是的,Android 应用程序是整个事情中唯一的“服务器”。【参考方案3】:我正在使用以下方式从 Android 设备获取本地 IP 地址,这对我来说看起来不错:
public static String getLocalIpAddress()
try
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();)
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();)
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address)
return inetAddress.getHostAddress();
catch (SocketException ex)
ex.printStackTrace();
return null;
这与您的正常方式几乎相同,但有点精致。希望这会有所帮助!
【讨论】:
我没有添加所有代码,我确实检查了 ipv4,而且我更喜欢wlan0
之类的东西,但至少在 chromebook 上,这里返回的 ip 都不是正确的。我猜在这一点上没有正确的答案。【参考方案4】:
扫描网络接口当然可以返回各种结果。您可以通过intf.getName()
了解更多信息,例如:
wlan0
上的 Wifi 连接
3G/4G 连接如rmnet1
lo
上的环回 (127.0.0.1) - 你已经消除了这个
有线以太网连接eth0
- 可以在某些 Chromebook 上使用
还有更多的可能性,比如 *** 连接。
如果可以肯定地说您只想通过 Wifi 连接连接到 Web 服务器,则可以添加检查接口名称是否以 wlan
开头,但您的替代解决方案似乎更简单这种情况。
如果 Chromebook 上也可以进行以太网连接,则网络服务器可能会同时在 wlan0
和 eth0
上提供连接。要么从网络接口中选择首选连接,要么准备同时提供无线和有线 IP。
【讨论】:
感谢这些网络名称。我已经在检查wlan0
。我也会检查eth
。在 Chromebook 上,我认为问题在于 Android 应用程序有点像模拟或其他东西,这就是 wifi 管理器返回正确信息但 NetworkInterfaces 没有的原因。我并不是很想处理 Chromebook 机箱,因为它更容易弄清楚,但所有奇怪的其他设备都在那里。【参考方案5】:
它们非常不可靠,因为您必须处理很多边缘情况。
我更喜欢使用免费的外部服务;进行网络呼叫并获得正确的面向公众的 IP。试试https://www.ipify.org/
【讨论】:
但是我不需要公网IP,我需要用户局域网上的IP。 在这种情况下,也许这可以帮助你:***.com/questions/6064510/… 所以他们用我的主要方式来做,我可能很久以前就复制了他们的代码。但我仍然不知道这是否比我的其他方式更可靠。以上是关于获取运行我的应用程序的 Android 设备 IP 的最可靠方法是啥?不是公网IP的主要内容,如果未能解决你的问题,请参考以下文章
从Android应用程序获取设备的MAC地址和IP地址[重复]
如何将 Android 发件人的 IP 地址获取到 Chromecast 设备?
获取用于从 Android 设备连接到 Firebase 的 IP 地址 [重复]