发送广播 UDP 但在其他 Android 设备上不接收

Send Broadcast UDP but not receive it on other Android devices(发送广播 UDP 但在其他 Android 设备上不接收)

本文介绍了发送广播 UDP 但在其他 Android 设备上不接收的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试开发一个应用程序来发送一些广播消息并从其他 android 设备接收一些答案.我在接收来自其他设备的 UDP 消息时遇到了一些问题.我应该提到,这段代码在 Gingerbread 上有效,但在 JellyBean 上它不再有效,我不知道可能是什么问题.

I am trying to develop an app that sends some broadcast messages and receives some answers from the other android devices. I am having some trouble receiving the UDP messages from the other devices. I should mention that this code worked on Gingerbread but on JellyBean it's not working anymore and I do not know what might be the problem.

这里是我发送广播消息的地方(我知道其他设备侦听端口 5000):

Here is where I send the broadcast message (I know the other devices listen on port 5000) :

 private void sendUDPMessage(String msg) {

    try {
        DatagramSocket clientSocket = new DatagramSocket();

        clientSocket.setBroadcast(true);
        InetAddress address = InetAddress.getByName(Utils.getBroadcastAddress());

        byte[] sendData;

        sendData = msg.getBytes();
        DatagramPacket sendPacket = new DatagramPacket(sendData,
                sendData.length, address, 5000);
        clientSocket.send(sendPacket);

        clientSocket.close();
    } catch (Exception e) {
        e.printStackTrace();
    }

}

这是我收到它的地方:

private void start_UDP()
{
    try {
            serverSocketUDP = new DatagramSocket(5000);
        }
    catch (Exception e) {

        Log.i(LOGTAG, "Exception opening DatagramSocket UDP");
    }

    final byte[] receiveData = new byte[1024];


    while(runningUDP) {
        Log.d(LOGTAG, "Waiting for Broadcast request in ServerUDP.");

        final DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);

        serverSocketUDP.receive(receivePacket);


                byte[] sendData = new byte[1024];
                InetAddress address = receivePacket.getAddress();
                int port = receivePacket.getPort();
                if(!receivePacket.getAddress().getHostAddress().equals(Utils.getLocalIpAddress()))
                {
                    String req = new String(receivePacket.getData(), 0, receivePacket.getLength());


                    Log.d(LOGTAG, "Received UDP message : "+req+" from: "+receivePacket.getAddress().getHostAddress());
                }
                      }// while ends
       }//method ends

我应该提到,这 2 个函数在 2 个不同的线程中是分开的,所以我可以同时发送和接收.

I should mention that these 2 functions are separate in 2 different threads so I can send and receive simultaneously.

我还获得了以下锁:

    powerManager =(PowerManager)context.getSystemService(Context.POWER_SERVICE);
    wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK ,LOGTAG); // PARTIAL_WAKE_LOCK Only keeps CPU on
    wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
    wifiLock = wifiManager.createWifiLock(3, LOGTAG);
    multicastLock = wifiManager.createMulticastLock(LOGTAG);

    wakeLock.acquire();
    multicastLock.acquire();
    wifiLock.acquire();

以及 Manifest 文件的权限:

And the permissions on the Manifest file :

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>

我已经测试了消息是否使用wireshark和tcpdump发送并且它们被发送.而且,更奇怪的是,我收到了我发送的广播消息(但我丢弃它们,因为我不需要处理自己发送的消息)但我没有收到从其他设备发送的广播消息(应该有格式相同,只是源地址和包含的消息不同,任何一种方式都不会影响广播消息).

I have tested if the messages are sent using wireshark and tcpdump and they are sent. Moreover, what is even more strange, I receive the broadcast messages that I send (but I discard them because I dont need to process the messages sent from myself) but I dont receive the broadcast messages sent from the other devices (which should have the same format, only the source address would be different and the message contained, either way should not affect the broadcast message).

如果您有任何想法,请告诉我,因为我真的没有其他可以尝试的方法了.任何帮助,将不胜感激.谢谢!

Please let me know if you have any ideas because I really ran out of anything else I could try. Any help would be appreciated. Thanks!

我已经进行了一些测试,即使当我在每部手机上运行 ifconfig wlan0 时,它也会显示类似

I have made some tests and even if when I run on each of the phones ifconfig wlan0 and it says something like

  ifconfig wlan0
  wlan0: ip 169.254.17.28 mask 255.255.0.0 flags [up broadcast multicast]

这意味着接口处于活动状态并且IP已设置并且可以接收广播消息和多播消息但是当我使用时

which means that the interface is active and the IP is set and can receive broadcast messages and multicast msgs but when I use

                 InetAddress in=InetAddress.getByName("169.254.17.28");
            if (in.isReachable(1000))
                Log.i(LOGTAG, "host is reachable");
            else
                Log.i(LOGTAG, "host is not reachable");

它在日志中显示主机不可访问.

It shows in the logs host is not reachable.

这是我打开 Wi-fi 的地方

This is where I turn on the Wi-fi

    private void startWifiAdhoc() {

    WifiManager wifiManager =     (WifiManager)SharingFileService.context.getSystemService(Context.WIFI_SERVICE);
    String command="";
    if (condWifiAdhoc == false) {

        condWifiAdhoc=true;
        wifiInterface = Utils.getWifiInterface();


        wifiManager.setWifiEnabled(true);
        localIP = Utils.getLinkLocalAddress();
    }
    else
    {
        wifiManager.setWifiEnabled(true);
        localIP = Utils.getLinkLocalAddress();
    }
        // Set wifi ad-hoc
        command = context.getFilesDir().getPath()
                + "/iwconfig " + wifiInterface + " mode ad-hoc essid "
                + "mcp" + " channel " + "1" + " commit
";

        Log.i(LOGTAG, command);
        Utils.rootExec(command);


        Log.i(LOGTAG, "Ip address used :" + localIP);
        command = context.getFilesDir().getPath()
                + "/ifconfig " + wifiInterface + " " + localIP
                + " netmask 255.255.0.0 up
";



        Log.i(LOGTAG, command);
        Utils.rootExec(command);

}

推荐答案

我通过使用此处描述的方法来计算广播地址得到了这个工作:https://code.google.com/p/boxeeeremote/wiki/AndroidUDP

I got this working by using a method described here to calculate the broadcast address: https://code.google.com/p/boxeeremote/wiki/AndroidUDP

这是我的接收器:

try {
  //Keep a socket open to listen to all the UDP trafic that is destined for this port
  socket = new DatagramSocket(Constants.PORT, InetAddress.getByName("0.0.0.0"));
  socket.setBroadcast(true);

  while (true) {
    Log.i(TAG,"Ready to receive broadcast packets!");

    //Receive a packet
    byte[] recvBuf = new byte[15000];
    DatagramPacket packet = new DatagramPacket(recvBuf, recvBuf.length);
    socket.receive(packet);

    //Packet received
    Log.i(TAG, "Packet received from: " + packet.getAddress().getHostAddress());
    String data = new String(packet.getData()).trim();
    Log.i(TAG, "Packet received; data: " + data);

    // Send the packet data back to the UI thread
    Intent localIntent = new Intent(Constants.BROADCAST_ACTION)
            // Puts the data into the Intent
            .putExtra(Constants.EXTENDED_DATA_STATUS, data);
    // Broadcasts the Intent to receivers in this app.
    LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent);
  }
} catch (IOException ex) {
  Log.i(TAG, "Oops" + ex.getMessage());
}

这是我的发件人:

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

    try {
      //Open a random port to send the package
      DatagramSocket socket = new DatagramSocket();
      socket.setBroadcast(true);
      byte[] sendData = messageStr.getBytes();
      DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, getBroadcastAddress(), Constants.PORT);
      socket.send(sendPacket);
      System.out.println(getClass().getName() + "Broadcast packet sent to: " + getBroadcastAddress().getHostAddress());
    } catch (IOException e) {
      Log.e(TAG, "IOException: " + e.getMessage());
    }
  }

  InetAddress getBroadcastAddress() throws IOException {
    WifiManager wifi = (WifiManager) 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);
  }

这篇关于发送广播 UDP 但在其他 Android 设备上不接收的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:发送广播 UDP 但在其他 Android 设备上不接收

基础教程推荐