java 通过 Wi-Fi Direct 进行广播
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15524593/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Broadcasting over Wi-Fi Direct
提问by KatoStoelen
I'm looking at the possibility to broadcast over a Wi-Fi Direct connection between multiple Android devices. I've created a simple message broadcasting application to test whether or not it works, but so far I haven't been able to broadcast a message. When I try to send the packet I get a SocketException(Network is unreachable):
我正在研究通过 Wi-Fi Direct 连接在多个 Android 设备之间进行广播的可能性。我创建了一个简单的消息广播应用程序来测试它是否有效,但到目前为止我还无法广播消息。当我尝试发送数据包时,我收到一个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
This is the essence of my code:
这是我的代码的本质:
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);
}
This postsuggests that broadcasting over Wi-Fi Direct should be possible.
这篇文章表明应该可以通过 Wi-Fi Direct 进行广播。
Does anyone know whether broadcasting over Wi-Fi Direct on Androiddevices actually works? If it should work, what am I doing wrong?
有谁知道在Android设备上通过 Wi-Fi Direct 广播是否真的有效?如果它应该工作,我做错了什么?
I'm starting to think the devices does not know where to route the broadcast packets. In my case it needs to work without having to root the device and manually add a route for broadcast packets.
我开始认为设备不知道将广播数据包路由到哪里。在我的情况下,它需要工作而无需根设备并手动添加广播数据包的路由。
Update
更新
After using the getBroadcastAddress()
function suggested by Romain Hippeauthe SocketException disappeared and it seems like the broadcasting is working as intended. However, I'm having problems receiving the broadcast on the second device.
使用Romain HippeaugetBroadcastAddress()
建议的函数后,SocketException 消失了,广播似乎按预期工作。但是,我在第二台设备上接收广播时遇到问题。
I'm using the following code to receive the broadcast:
我正在使用以下代码接收广播:
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();
}
I have also tried to add a wildcard address to the DatagramSocket
by adding InetAddress.getByName("0.0.0.0")
as argument, but no luck.
我还尝试DatagramSocket
通过添加InetAddress.getByName("0.0.0.0")
为参数向 中添加通配符地址,但没有运气。
Suggestions?
建议?
采纳答案by Romain Hippeau
Shamelessly stolen from https://code.google.com/p/boxeeremote/wiki/AndroidUDP
从https://code.google.com/p/boxeeeremote/wiki/AndroidUDP无耻地被盗
Try getting you network connection this way:
尝试通过这种方式获得网络连接:
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);
}
Then try sending a packet this way:
然后尝试以这种方式发送数据包:
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);
Edit: From same page to read try this ...
编辑:从同一页面阅读试试这个......
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);
Remember, that you need the following permission for it to work:
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
请记住,您需要以下权限才能使其工作:
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>