15

複数のAndroidデバイス間でWi-FiDirect接続を介してブロードキャストする可能性を検討しています。動作するかどうかをテストするための簡単なメッセージブロードキャストアプリケーションを作成しましたが、これまでのところメッセージをブロードキャストできませんでした。パケットを送信しようとすると、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);
}

この投稿は、Wi-FiDirectを介したブロードキャストが可能であることを示唆しています。

AndroidデバイスでWi-FiDirectを介したブロードキャストが実際に機能するかどうかを誰かが知っていますか?それがうまくいくはずなら、私は何を間違っていますか?

デバイスがブロードキャストパケットをどこにルーティングするかを知らないと思い始めています。私の場合、デバイスをルート化し、ブロードキャストパケットのルートを手動で追加しなくても機能する必要があります。


アップデート

Romain HippeaugetBroadcastAddress()によって提案された機能を使用した後、SocketExceptionが消え、ブロードキャストが意図したとおりに機能しているようです。ただし、2番目のデバイスでブロードキャストを受信する際に問題が発生します。

ブロードキャストを受信するために次のコードを使用しています。

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

提案?

4

1 に答える 1

12

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"/>

于 2013-03-20T13:31:51.180 に答える