【问题标题】:Android send udp broadcast silently failsAndroid静默发送udp广播失败
【发布时间】:2014-05-14 03:10:31
【问题描述】:

我想通过使用网络的广播地址来实现服务发现。我正在使用 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 手机没有。

【问题讨论】:

  • 你在清单中有什么权限?
  • 我有 INTERNET、ACCESS_NETWORK_STATE 和 ACCESS_WIFI_STATE。但是如果我没有正确的权限,就会抛出异常,而且没有。

标签: android networking udp


【解决方案1】:

以下对我有用,我可以将特定的字符串值广播到另一端的指定端口(在您的情况下为 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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-26
    • 2019-06-17
    • 1970-01-01
    • 2012-11-09
    • 2013-10-14
    • 2020-02-21
    • 2018-11-03
    相关资源
    最近更新 更多