我正在尝试构建一个项目,其中必须通过Wifi从智能手机驾驶IoT设备。
该设备集成了SPWF01 Wifi模块,并配置为WEP安全类型的访问点(没有Internet访问)。在此访问点配置上,我们还有一个TCP套接字服务器来拦截智能手机通信。
在智能手机端,我们有部分代码用于扫描并连接到我们设备的访问点(虽然工作正常,但由于没有Internet访问,Wi-Fi图标上出现感叹号)。连接后,我们启动客户端套接字,该套接字连接到我们IoT设备上的服务器(服务器套接字的IP地址实际上是访问点的网关)。这里出现了问题,因为客户端套接字无法启动。以下是代码:
public void SocketInit(String ip, int port) throws IOException {
InetAddress addr = InetAddress.getByName(ip);
SocketAddress sockaddr = new InetSocketAddress(addr, port);
nsocket = new Socket();
nsocket.setReuseAddress(true);
nsocket.setTcpNoDelay(false);
nsocket.setReceiveBufferSize(700); //Must be less than 730byte witch is the module buffer
nsocket.setSendBufferSize(700);
nsocket.connect(sockaddr, 5000); //5 second connection timeout
}
这里是我收到的异常:
java.net.SocketException: socket failed: ENONET (Machine is not on the network)
甚至在达到nsocket.connect()之前,我就遇到了这个错误,准确地说是在setReuseAddress上。
由于我得到的异常是ENONET,我认为这一定是因为接入点没有互联网访问权限,所以我使用了这里提供的解决方案进行测试:
adb shell settings put global captive_portal_detection_enabled 0
这是一个没有根访问权限就无法通过编程实现的解决方案,但我想测试一下是否是问题所在。但虽然Wifi图标上的感叹号消失了,客户端套接字仍然给出相同的异常错误。
有人有这种情况的解决方法吗?谢谢您的帮助!
有时候客户端套接字会成功打开,成功率为20次中1次。但当它成功打开后,通常在发送几条消息后会再次抛出异常:
java.net.SocketException: recvfrom failed: ECONNRESET (Connection reset by peer)
这是我从智能手机连接到接入点所使用的代码:
WifiConfiguration wc=new WifiConfiguration();
wc.SSID= host;
wc.status = WifiConfiguration.Status.ENABLED;
wc.priority = 40;
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
wc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
wc.allowedGroupCiphers.clear();
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
wc.wepKeys[0] = password;
wc.wepTxKeyIndex = 0;
int netId = mainWifi.addNetwork(wc);
try {
//mainWifi.setWifiEnabled(true);
mainWifi.disconnect();
mainWifi.enableNetwork(netId, true);
mainWifi.reconnect();
startConnectionCheck = true;
System.out.println("enabled network");
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
访问点的安全类型为WEP。这是因为Wifi模块无法实现WPA。
在Marshmallow上进行的测试。