在网络连接后尝试发送UDP数据包时,Android提升EPERM(操作不允许)

tam*_*mul 7 java sockets networking android

响应SUPPLICANT_STATE_CHANGED_ACTION广播并尝试发送UDP数据包时,异常:

java.net.SocketException: sendto failed: EPERM (Operation not permitted)
   at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:542)
   at libcore.io.IoBridge.sendto(IoBridge.java:511)
   at java.net.PlainDatagramSocketImpl.send(PlainDatagramSocketImpl.java:184)
   at java.net.DatagramSocket.send(DatagramSocket.java:305)
   at com.mycompany.app.ServiceClass.discover(ServiceClass.java:355)at com.mycompany.app.ServiceClass.access$600(ServiceClass.java:39)
   at com.mycompany.app.ServiceClass$StateMachine.run(ServiceClass.java:242)
   at java.lang.Thread.run(Thread.java:818)
Caused by: android.system.ErrnoException: sendto failed: EPERM (Operation not permitted)
   at libcore.io.Posix.sendtoBytes(Native Method)
   at libcore.io.Posix.sendto(Posix.java:211)
   at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:278)
   at libcore.io.IoBridge.sendto(IoBridge.java:509)
   at java.net.PlainDatagramSocketImpl.send(PlainDatagramSocketImpl.java:184) 
   at java.net.DatagramSocket.send(DatagramSocket.java:305) 
   at com.mycompany.app.ServiceClass.discover(ServiceClass.java:355) 
   at com.mycompany.app.ServiceClass.access$600(ServiceClass.java:39) 
   at com.mycompany.app.ServiceClass$StateMachine.run(ServiceClass.java:242) 
   at java.lang.Thread.run(Thread.java:818)
Run Code Online (Sandbox Code Playgroud)

是由Android引发的.但是,在调试期间或者Thread.sleep()在尝试发送数据包之前添加了~300ms 的调用时,不会引发异常.这似乎是Socket.send()Android建立网络连接后立即同时访问该方法的问题.调试程序只调用一次send(),所以我相信这个问题与操作系统和我的服务之间的交互有关.

违规代码类似于:

public class ServiceClass extends Service {
    private static final byte[] MSG_BYTES = "My string to send".getBytes();
    private ConnectionMonitor mConnMonitor;

    public void onCreate {
        super.onCreate();
        // Create new thread to handle broadcast and register receiver
        mConnMonitor = new ConnectionMonitor();
        mConnMonitorThread = new HandlerThread("ConnectionMonitor",
                                               Process.THREAD_PRIORITY_BACKGROUND)
        mConnMonitorThread.start();
        Looper connMonitorLooper = mConnMonitorThread.getLooper();
        Handler connMonitorHandler = new Handler(connMonitorLooper);
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)
        registerReceiver(mConnMonitor, netIntentFilter, null, connMonitorHandler);

    private void sendPacket() {
        DatagramSocket sock = new DatagramSocket(); // Actually wrapped in try-catch
        try {
            DatagramPacket packet = new DatagramPacket(MSG_BYTES, MSG_BYTES.length,
                    InetAddress.getByName("239.255.255.250"), 1900);
            sock.send(packet);
        } catch (IOException e) {
             // This is the exception being raised
        }

    public class ConnectionMonitor extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            SupplicantState supplicantState =
                    intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE);
Run Code Online (Sandbox Code Playgroud)

COMPLETED发送请求者广播后网络是否需要花费更多时间进行初始化,或者更可能与我的服务中的线程相关?