UDP 套接字未在 Android 6 (M) 上接收数据报

UDP socket does not receive datagrams on Android 6 (M)

我下面的代码 运行 在 Android 5.1.1 上运行良好,显示了我的控制台收到的数据报。

byte[] message = new byte[500];
try {
    String text;
    int server_port = 3421;
    DatagramPacket p = new DatagramPacket(message, message.length);
    DatagramSocket s = new DatagramSocket(server_port);

    s.receive(p);
    Log.d("APP", "After received");

    final String hexMsg = bytesToHex(message);
    Log.d("APP","message:" + hexMsg);

    s.close();
} catch (SocketException e) {
    e.printStackTrace();
} catch (UnknownHostException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} finally {

}

出于某种未知原因,当我 运行 在 Android 6.0.1 上使用相同的代码时,我没有收到任何数据报。控制台上没有显示错误。

我的 UDP 服务器将数据报直接发送到我的 android 设备(因此,这不是广播)。

完整 class 代码:

 public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            if (Build.VERSION.SDK_INT>Build.VERSION_CODES.LOLLIPOP_MR1) {
                String pkg=getPackageName();
                PowerManager pm=getSystemService(PowerManager.class);

            if (!pm.isIgnoringBatteryOptimizations(pkg)) {
                Intent i= new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
                                .setData(Uri.parse("package:" + pkg));

                startActivity(i);
            }
        }

        new myAsync().execute();

    }

    final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
    public static String bytesToHex(byte[] bytes) {
        char[] hexChars = new char[bytes.length * 2];
        for ( int j = 0; j < bytes.length; j++ ) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = hexArray[v >>> 4];
            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
        }
        return new String(hexChars);
    }

    class myAsync extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub
            super.onPreExecute();
        }

        @Override
        protected Void doInBackground(Void... params) {
            // TODO Auto-generated method stub

            byte[] message = new byte[500];
            try {
                String text;
                int server_port = 3421;
                DatagramPacket p = new DatagramPacket(message, message.length);
                DatagramSocket s = new DatagramSocket(server_port);

                s.receive(p);
                Log.d("APP", "After received");

                final String hexMsg = bytesToHex(message);
                Log.d("APP","message:" + hexMsg);


                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(getApplicationContext(),  hexMsg, Toast.LENGTH_LONG).show();
                    }
                });


                s.close();
            } catch (SocketException e) {
                e.printStackTrace();
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {

            }

            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);
            // Handle/Update UI Part
        }
    }
}

对可能出现的问题有什么想法吗?

我通过进行 2 处更改使其工作:

1st) 通过使用允许重用地址:

DatagramSocket s = new DatagramSocket(null);
s.setReuseAddress(true);
s.bind(new InetSocketAddress(server_port));

而不是

DatagramSocket s = new DatagramSocket(server_port);

2nd) 使用 Runnable Thread 而不是 Async 方法。