Android发送udp广播静默失败

Android发送udp广播静默失败

本文介绍了Android发送udp广播静默失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to implement service discovery by using the network's broadcast address. I am sniffing packets with WireShark to confirm that my UDP packets are not being sent. The network code is not being run on the UI thread. The DatagramSocket.send call returns with no exception thrown, but nothing is seen by other programs including WireShark. I have verified that the address returned by getWifiBroadcastAddress actually is the broadcast address of my network.

我已通过编写C#程序并在另一台计算机上运行来验证网络是否支持广播,而WireShark 正在从该程序中检测广播数据包.

I have verified that the network supports broadcast by writing a C# program, run on another machine, and WireShark is detecting broadcast packets from this program.

这是我的Android Java代码:

Here is my Android Java code:

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

The getWifiBroadcastAddress() method is as seen here: https://lab.dyne.org/AndroidUDPBroadcast

有人知道为什么这会无声地失败吗?就像我说的那样,我在另一个盒子上运行的C#程序运行正常,做同样的事情,每5秒发送一次相同的数据,WireShark看到这些数据包,但是从Android手机看不到这些数据包.

Does anyone know why this would fail silently? Like I said my C# program running on another box is working just fine, doing the same thing, sending the same data every 5s, and WireShark sees those packets, but nothing from the Android phone.

推荐答案

以下内容对我有用,我可以在其中将特定的字符串值广播到另一端的指定端口(在您的情况下为Protocol.INQUIRY_PORT) ,本地子网上的所有正在该端口上监视UDP的设备都可以识别该字符串值,并因此可以做出响应.我正在从主线程广播,但是正在异步任务中侦听响应.

The following works for me, where I can broadcast a particular string value to a specified port (in your case Protocol.INQUIRY_PORT) on the other end(s), and all of the devices on the local subnet that are monitoring UDP on that port can recognize that string value, and accordingly can respond. I am broadcasting from the main thread, but listening for responses in an async task.

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响应侦听器代码:

Following is the corresponding UDP response listener code inside an async task class:

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

这篇关于Android发送udp广播静默失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-12 18:19