gpt4 book ai didi

java - Android,在网络共享和连接到接入点时检测 WiFi 的本地 IP 和子网掩码

转载 作者:太空宇宙 更新时间:2023-11-03 13:20:44 25 4
gpt4 key购买 nike

我需要在 Android 设备上检测 WiFi 网络上的本地 IP 地址和子网掩码(以便严格地为本地子网正确计算 UDP 广播地址)。

当设备连接到接入点时,以下各项正常工作:

// Only works when NOT tethering
WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);

DhcpInfo dhcp = wifi.getDhcpInfo();
if (dhcp == null)
throw new IOException("No DHCPInfo on WiFi side.");

foo(dhcp.ipAddress, dhcp.netmask);

但是当 Android 设备通过网络共享提供接入点时它不起作用:当 Android 设备是它的客户端时,DhcpInfo 似乎包含 DCHP 服务器设置的信息,而不是当它是 Android 设备本身提供DHCP 服务。在网络共享中,我能找到的最有希望的解决方案是:

// No way to get subnet mask
WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);

WifiInfo info = wifi.getConnectionInfo();
if (info == null)
throw new IOException("No connection info on WiFi side.");

foo(info.getIpAddress(), info.??? /* netmask*/ );

编辑:错误,在我的测试中,即使这仅在未绑定(bind)时才有效。绑定(bind)时 IP 始终为 0。

但是没有像 WifiInfo.getNetMask() 这样的东西,在那种情况下我怎样才能得到子网掩码? (这种缺失让我觉得很奇怪,因为那里还有很多其他信息。我是否遗漏了一些明显的东西?)

此外,理想情况下,我想要一个不需要区分 Android 设备是否提供网络共享的解决方案,并且只需在 WiFi 网络上获取本地 IP 地址和子网掩码,无论如何,当Android 设备正在提供接入点或作为接入点的客户端。

即使是标准 Java(即非 Android 专用)NetworkInterface.getNetworkInterfaces(),似乎也没有办法获取子网掩码(除了不允许区分哪个对应于无线上网)。我错过了什么?

最佳答案

我目前找到的最佳解决方案:

让我感到困惑的是,有关网络共享的信息/界面获取起来如此麻烦/隐藏,而且当您从 WifiManagerConnectivityManager 获取信息时却没有考虑到Wifi 类型:它仅在不处于网络共享状态时才有效。我实际上迷失了调查的那个分支。

我目前找到的最佳解决方案是使用标准 Java NetworkInterface.getNetworkInterfaces(),而不是任何 Android API。

根据实验,Android 似乎足够聪明,可以将网络接口(interface)设置为空广播到外部移动网络。这实际上很有意义,因为 Android 会默默地丢弃涉及外部移动网络的 UDP 广播。

    // This works both in tethering and when connected to an Access Point

Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();

while (interfaces.hasMoreElements())
{
NetworkInterface networkInterface = interfaces.nextElement();

if (networkInterface.isLoopback())
continue; // Don't want to broadcast to the loopback interface

for (InterfaceAddress interfaceAddress : networkInterface.getInterfaceAddresses())
{
InetAddress broadcast = interfaceAddress.getBroadcast();

// InetAddress ip = interfaceAddress.getAddress();
// interfaceAddress.getNetworkPrefixLength() is another way to express subnet mask

// Android seems smart enough to set to null broadcast to
// the external mobile network. It makes sense since Android
// silently drop UDP broadcasts involving external mobile network.
if (broadcast == null)
continue;

... // Use the broadcast
}
}

至于子网掩码,getNetworkPrefixLength() 的结果可以强制转换为子网掩码。我直接使用了 getBroadcast(),因为那是我的最终目标。

此代码似乎不需要特殊权限(没有ACCESS_WIFI_STATE 也没有NETWORK,只是INTERNET)。

代码 fragment 的主要引用:http://enigma2eureka.blogspot.it/2009/08/finding-your-ip-v4-broadcast-address.html

关于java - Android,在网络共享和连接到接入点时检测 WiFi 的本地 IP 和子网掩码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28283915/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com