广播通过Wi-Fi直连Wi、Fi

2023-09-04 13:20:29 作者:奶油味的擁抱

我看广播在多个Android设备之间的无线网络直接连接的可能性。我创建了一个简单的消息广播应用程序来测试它是否工作正常,但到目前为止,我还没有能够播出的消息。当我尝试发送我得到的数据包的 SocketException (网络无法访问):

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):

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

这是我的code精华:

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);
}

这个帖子表明,广播通过Wi-Fi直连宜是可能的。

This post suggests that broadcasting over Wi-Fi Direct should be possible.

有谁知道是否广播通过Wi-Fi直连的机器人设备的实际工作?如果它应该工作,我究竟哪里做错了?

Does anyone know whether broadcasting over Wi-Fi Direct on Android devices actually works? If it should work, what am I doing wrong?

我开始觉得设备不知道从哪里路由广播包。在我的情况需要而无需根设备和手动添加路由广播报文的工作。

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.

更新

利用提出的 getBroadcastAddress()功能后的罗曼Hippeau 的的SocketException消失了,好像在广播如预期。然而,我在接收所述第二设备上的广播的问题。

After using the getBroadcastAddress() function suggested by Romain Hippeau the SocketException disappeared and it seems like the broadcasting is working as intended. However, I'm having problems receiving the broadcast on the second device.

我用下面的code接收广播:

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();
}

我也试图加入 InetAddress.getByName(0.0.0.0)作为参数,但没有运气。

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.

建议?

推荐答案

从无耻地窃取https://$c$c.google.com/p/boxeeremote/wiki/AndroidUDP

Shamelessly stolen from https://code.google.com/p/boxeeremote/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);

编辑:从同一页面阅读试试这个...

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);

记住,你需要以下权限为它工作: &LT;使用-权限的Andr​​oid:名称=android.permission.CHANGE_WIFI_MULTICAST_STATE/&GT;

Remember, that you need the following permission for it to work: <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>