我正在研究通过多个Android设备之间的Wi-Fi Direct连接进行广播的可能性。我创建了一个简单的消息广播应用程序来测试它是否有效,但是到目前为止,我还无法广播消息。当我尝试发送数据包时,出现 SocketException (网络无法访问):
03-20 13:23:00.148: E/UdpBroadcaster(4180): sendto failed: ENETUNREACH (Network is unreachable) 03-20 13:23:00.148: E/UdpBroadcaster(4180): java.net.SocketException: sendto failed: ENETUNREACH (Network is unreachable) 03-20 13:23:00.148: E/UdpBroadcaster(4180): at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:496) 03-20 13:23:00.148: E/UdpBroadcaster(4180): at libcore.io.IoBridge.sendto(IoBridge.java:465) 03-20 13:23:00.148: E/UdpBroadcaster(4180): at java.net.PlainDatagramSocketImpl.send(PlainDatagramSocketImpl.java:182) 03-20 13:23:00.148: E/UdpBroadcaster(4180): at java.net.DatagramSocket.send(DatagramSocket.java:307) 03-20 13:23:00.148: E/UdpBroadcaster(4180): at com.example.android.wifidirect.UdpBroadcaster.sendMessage(UdpBroadcaster.java:59) 03-20 13:23:00.148: E/UdpBroadcaster(4180): at com.example.android.wifidirect.UdpBroadcaster.run(UdpBroadcaster.java:44) 03-20 13:23:00.148: E/UdpBroadcaster(4180): Caused by: libcore.io.ErrnoException: sendto failed: ENETUNREACH (Network is unreachable) 03-20 13:23:00.148: E/UdpBroadcaster(4180): at libcore.io.Posix.sendtoBytes(Native Method) 03-20 13:23:00.148: E/UdpBroadcaster(4180): at libcore.io.Posix.sendto(Posix.java:146) 03-20 13:23:00.148: E/UdpBroadcaster(4180): at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:177) 03-20 13:23:00.148: E/UdpBroadcaster(4180): at libcore.io.IoBridge.sendto(IoBridge.java:463) 03-20 13:23:00.148: E/UdpBroadcaster(4180): ... 4 more
这是我的代码的本质:
InetAddress broadcastAddress = InetAddress.getByName("255.255.255.255"); int port = 8888; DatagramSocket socket = new DatagramSocket(port); socket.setBroadcast(true); socket.connect(broadcastAddress, port); String message = "Hello"; byte[] buffer = message.getBytes(); DatagramPacket packet = new DatagramPacket( buffer, buffer.length, broadcastAddress, port); try { socket.send(packet); // <----- Causes a SocketException } catch (IOException e) { Log.e(TAG, e.getMessage(), e); }
有谁知道在 Android 设备上通过Wi-Fi Direct广播是否真的有效?如果它可以正常工作,我在做什么错?
我开始认为设备不知道将广播数据包路由到何处。在我的情况下,它需要工作而不必生根设备并手动为广播数据包添加路由。
更新资料
使用 Romain HippeaugetBroadcastAddress()建议的功能后,SocketException消失了,广播似乎按预期工作了。但是,我在第二台设备上接收广播时遇到问题。 __
getBroadcastAddress()
我正在使用以下代码来接收广播:
DatagramSocket socket = null; try { socket = new DatagramSocket(8888); socket.setBroadcast(true); // Not needed? socket.setSoTimeout(200); DatagramPacket packet = null; while (!mStopping) { byte[] buffer = new byte[1024]; packet = new DatagramPacket(buffer, buffer.length); try { socket.receive(packet); if (packet.getData().length > 0) { String receivedString = new String(packet.getData()); Log.i(TAG, "Received string: " + receivedString); } } catch (InterruptedIOException e) { /* Ignore */ } } } catch (IOException e) { Log.e(TAG, e.getMessage(), e); } finally { if (socket != null) socket.close(); }
我也曾尝试DatagramSocket通过添加InetAddress.getByName("0.0.0.0")as参数来向通配符地址添加通配符地址,但是没有运气。
DatagramSocket
InetAddress.getByName("0.0.0.0")
有什么建议吗?
从 https://code.google.com/p/boxeeremote/wiki/AndroidUDP无耻地被盗
尝试通过以下方式获得网络连接:
InetAddress getBroadcastAddress() throws IOException { WifiManager wifi = mContext.getSystemService(Context.WIFI_SERVICE); DhcpInfo dhcp = wifi.getDhcpInfo(); // handle null somehow int broadcast = (dhcp.ipAddress & dhcp.netmask) | ~dhcp.netmask; byte[] quads = new byte[4]; for (int k = 0; k < 4; k++) quads[k] = (byte) ((broadcast >> k * 8) & 0xFF); return InetAddress.getByAddress(quads); }
然后尝试以这种方式发送数据包:
DatagramSocket socket = new DatagramSocket(PORT); socket.setBroadcast(true); DatagramPacket packet = new DatagramPacket(data.getBytes(), data.length(), getBroadcastAddress(), PORT); socket.send(packet); // If you want to listen for a response ... byte[] buf = new byte[1024]; DatagramPacket packet = new DatagramPacket(buf, buf.length); socket.receive(packet);
编辑:从同一页上阅读尝试此…
WifiManager wifi = (WifiManager) this.getSystemService(Context.WIFI_SERVICE); MulticastLock lock = wifi.createMulticastLock("dk.aboaya.pingpong"); lock.acquire(); serverSocket = new DatagramSocket(19876); serverSocket.setSoTimeout(15000); //15 sec wait for the client to connect byte[] data = new byte[UDPBatPositionUpdater.secretWord.length()]; DatagramPacket packet = new DatagramPacket(data, data.length); serverSocket.receive(packet); lock.release(); String s = new String(packet.getData()); System.out.println(s);
请记住,您需要具有以下权限才能工作: < uses-permission android:name =“android.permission.CHANGE_WIFI_MULTICAST_STATE” />