如何将套接字绑定到Android上的本地wifi网络地址?

时间:2016-07-05 19:41:30

标签: java android sockets

我想将套接字绑定到本地wifi网络地址,以确保请求不通过3g或其他网络运行。我试过这段代码:

public static String getIpAddress(WifiManager wifiManager) {
    WifiInfo wifiInfo = wifiManager.getConnectionInfo();
    int ipAddress = wifiInfo.getIpAddress();
    return String.format("%d.%d.%d.%d", (ipAddress & 0xff),(ipAddress >> 8 & 0xff),
            (ipAddress >> 16 & 0xff),(ipAddress >> 24 & 0xff));
}

Socket socket = new Socket();
String localIpAddress = getIpAddress(wifiManager);
socket.bind(new InetSocketAddress(localIpAddress, 80));
socket.connect(new InetSocketAddress(serverHostname, serverPort), (int)   timeoutMs);

它抛出: java.net.BindException: bind failed: EACCES (Permission denied) 我在Manifest中检查了权限。看起来所有需要的权限都被授予:

<!-- Uses: show 'disconnected' message when not connected to the internet -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

<!-- Uses: record wifi network name when setting up a device -->
<!-- Uses: device wifi setup -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

<!-- Uses: device wifi setup -->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.INTERNET" />

2 个答案:

答案 0 :(得分:4)

如果没有超级用户访问权限,则无法绑定到1024以下的端口。所以Socket.bind()到端口80就是抛出异常。选择一个大于1024的自定义端口。例如,大多数用户启动的Web服务器使用端口8080。

答案 1 :(得分:0)

棉花糖后,您可以使用 NetworkCapabilities 将套接字绑定到wifi,并通过 Wifi 绑定套接字

注意:将套接字与wifi绑定后,应用程序的所有其他网络操作也将绑定到Wifi。

private ConnectivityManager connectivityManager;
connectivityManager = (ConnectivityManager) 
 getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);

    for (Network network : connectivityManager.getAllNetworks()) {

        NetworkCapabilities x = connectivityManager.getNetworkCapabilities(network);

        if (x.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
            Log.d(TAG, "Wifi Found with" + x.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) + "" + network.toString());
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                connectivityManager.bindProcessToNetwork(network);
            }
        }
    }

注意:如果您要取消与Wifi网络的绑定, 将网络设置为空。

connectivityManager.bindProcessToNetwork(null);