Android发送udp广播无声失败

时间:2014-05-14 03:10:31

标签: android networking udp

我想通过使用网络的广播地址来实现服务发现。我正在使用WireShark嗅探数据包以确认我的UDP数据包未被发送。网络代码未在UI线程上运行。 DatagramSocket.send调用返回时没有抛出任何异常,但其他程序(包括WireShark)都看不到任何内容。我已经验证了getWifiBroadcastAddress返回的地址实际上是我网络的广播地址。

我已经验证网络支持通过编写C#程序进行广播,在另一台计算机上运行,​​而WireShark 正在检测来自此程序的广播数据包

这是我的Android Java代码:

try {
    DatagramSocket socket = new DatagramSocket(Protocol.INQUIRY_PORT);
    socket.setBroadcast(true);
    InetAddress broadcastAddr = getWifiBroadcastAddress();

    byte[] data = new byte[10];
    for(int i = 0; i < data.length; i++) {
        data[i] = (byte) i;
    }

    DatagramPacket packet = new DatagramPacket(data, data.length,
            broadcastAddr, Protocol.INQUIRY_PORT);
    while(true) {
        // Loops indefinitely, no errors/exceptions
        socket.send(packet);
        try {
            Thread.sleep(5000);
        } catch(InterruptedException ie) {
            break;
        }
    }
} catch(IOException ioe) {
    // Not logged
    Log.d("Broadcast", "Error sending inquiry.");
}

getWifiBroadcastAddress()方法如下所示:https://lab.dyne.org/AndroidUDPBroadcast

有谁知道为什么这会无声地失败?就像我说我在另一个盒子上运行的C#程序工作得很好,做同样的事情,每5秒发送相同的数据,WireShark看到这些数据包,但没有来自Android手机。

1 个答案:

答案 0 :(得分:0)

以下适用于我,我可以将特定字符串值广播到指定端口(在您的情况下为Protocol.INQUIRY_PORT),以及本地子网上监视该端口上识别该字符串的UDP的所有设备价值,会回应。我正在从主线程广播,但在异步任务中侦听响应。

public void sendBroadcast(String messageStr) {
    // Hack Prevent crash (sending should be done using an async task)
    StrictMode.ThreadPolicy policy = new   StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
    byte[] sendData = messageStr.getBytes();
    try {
        sendSocket = new DatagramSocket(null);
        sendSocket.setReuseAddress(true);
        sendSocket.bind(new InetSocketAddress(Protocol.INQUIRY_PORT));
        sendSocket.setBroadcast(true);

        //Broadcast to all IP addresses on subnet
        try {
            DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, InetAddress.getByName("255.255.255.255"), Protocol.INQUIRY_PORT);
            sendSocket.send(sendPacket);
            System.out.println(getClass().getName() + ">>> Request packet sent to: 255.255.255.255 (DEFAULT)");
        } catch (Exception e) {
        }
    } catch (IOException e) {
        Log.e(TAG, "IOException: " + e.getMessage());
    }
}

以下是异步任务类中对应的UDP响应侦听器代码:

protected String doInBackground(String... params) {
        serverIP = "";
        try {
            //Keep a socket open to listen to all the UDP trafic that is destined for this port
            InetAddress myHostAddr = InetAddress.getByName("0.0.0.0");
            rcvSocket = new DatagramSocket(null);
            rcvSocket.setReuseAddress(true);
            rcvSocket.bind(new InetSocketAddress("0.0.0.0",Protocol.INQUIRY_PORT));
            rcvSocket.setBroadcast(true);

            while (true) {
                Log.i("VIS","Ready to receive broadcast packets!");
                //Receive a packet
                byte[] recvBuf = new byte[15000];
                DatagramPacket packet = new DatagramPacket(recvBuf, recvBuf.length);
                rcvSocket.receive(packet);
                //Packet received
                serverIP = packet.getAddress().getHostAddress();
                Log.i("VIS", "Packet received from: " + serverIP);
                String data = new String(packet.getData()).trim();
                Log.i("VIS", "Packet received; data: " + data);
                if (!data.equals("") && !data.equals(myInquiryString)) {
                    //break while loop and return IP address of server
                    break;
                }
            }
        } catch (IOException ex) {
            Log.i("VIS", "ServerDiscovery" + ex.getMessage());
        }
        return serverIP;
}