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