Send Broadcast UDP but not receive it on other Android devices

ぐ巨炮叔叔 提交于 2019-11-27 18:36:36

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

Here's my receiver:

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

And here's my sender:

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

I came across your post when trying to solve a similar issue. Did you get your stuff working?

In my case, I had been trying to get a Nexus 7 (first gen with Jelly Bean 4.3) and Nexus One (Gingerbread 2.3.6) talking to each other via UDP. Initially my app, running on both devices, would successfully link up but only with one-way communication from the phone to the tablet. I had only one permission in place in the manifest: INTERNET. Communication from the tablet to the phone started working once I had added the ACCESS_NETWORK_STATE permission to the manifest.

So, for some reason, the Nexus 7 is happy with just the INTERNET permission for both sending and receiving UDP packets (well, my particular implementation of it, at least). The Nexus One will send with only the INTERNET permission but will not receive unless the ACCESS_NETWORK_STATE permission is given as well.

Your code looks similar to mine (I don't recognize your "UTILS." calls, however). In my case, though, for the purposes of testing, I've hard-coded the broadcast address (192.168.n.255). I'm on an access point while you're on an adhoc network. Perhaps that has some effect as well.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!