太多带有 UDP (DatagramSocket) 的 AsyncTask 在执行时抛出异常
Too many AsyncTask's with UDP (DatagramSocket) throwing Exception when executed
我的 "Remote" 应用程序有问题。我想做的是使用我的 phone 作为触摸屏来控制我的 PC 的鼠标光标,到目前为止它可以工作,但有一个小问题,即在移动光标太多之后,我得到一个异常。
以下代码只有最重要的片段。
在我的 phone 上,我有以下 "Touchscreen"-区域:
RelativeLayout mouse = (RelativeLayout) findViewById(R.id.relative_layout_mouse);
mouse.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent e) {
int action = e.getAction();
if (action == MotionEvent.ACTION_MOVE) {
int historySize = e.getHistorySize();
if(historySize > 0){
//calculations on how to get x and y differences between current x/y and previous (historySize-1) x/y
new ClientUDPTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new String[]{difference_x, difference_y});
}
}
return true;
}
});
它在移动鼠标时将许多小的协调更改发送到我的 AsyncTask:
public class ClientUDPTask extends AsyncTask<String,String,String> {
@Override
protected String doInBackground(String[] params) {
ByteBuffer buffer = ByteBuffer.wrap(new byte[7]);
//put the coordinates into the ByteBuffer...
byte[] bytes = buffer.array();
InetAddress adress = null;
DatagramSocket socket = null;
try {
socket = new DatagramSocket();
adress = InetAddress.getByName("192.168.1.108");
DatagramPacket packet = new DatagramPacket(bytes, bytes.length, adress, 9000);
socket.send(packet);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
然后在我的服务器上,我使用它们来移动光标:
public class UDPServer {
private DatagramSocket socket;
public void listen() {
try {
socket = new DatagramSocket(9000);
byte[] buffer = new byte[7];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
while (true) {
try {
socket.receive(packet);
byte[] data = packet.getData();
//get coordinates out of bytearray...
Robot robot = new Robot();
int newX = x - Integer.valueOf(x);
int newY = y - Integer.valueOf(y);
robot.mouseMove(newX, newY);
} catch (AWTException e) {
e.printStackTrace();
}
}
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
现在,您可以猜到,当鼠标四处移动时,会创建许多任务,将这些数据片段发送到服务器,直到出现此异常:
java.net.SocketException: socket failed: EMFILE (Too many open files)
at libcore.io.IoBridge.socket(IoBridge.java:623)
at java.net.PlainDatagramSocketImpl.create(PlainDatagramSocketImpl.java:93)
at java.net.DatagramSocket.createSocket(DatagramSocket.java:157)
at java.net.DatagramSocket.<init>(DatagramSocket.java:80)
at java.net.DatagramSocket.<init>(DatagramSocket.java:65)
at com.example.johnsmith.remote.ClientUDPTask.doInBackground(ClientUDPTask.java:31)
at com.example.johnsmith.remote.ClientUDPTask.doInBackground(ClientUDPTask.java:15)
at android.os.AsyncTask.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: android.system.ErrnoException: socket failed: EMFILE (Too many open files)
at libcore.io.Posix.socket(Native Method)
at libcore.io.BlockGuardOs.socket(BlockGuardOs.java:282)
at libcore.io.IoBridge.socket(IoBridge.java:608)
... 11 more
这个异常指向:
socket = new DatagramSocket();
在ClientUDPTask.java
在移动过程中 LogCat 显示 ~1 KB/s 的网络使用情况。这一切都通过我的 WiFi 工作。
我以前使用 TCP 而不是 UDP 时就遇到过这个问题。尽管我也没有使用 .executeOnExecutor(...)
,但速度非常慢。
Playstore 上有无数应用程序可以执行此 Remote-Thingie,而且非常流畅,但他们是怎么做到的?
我的错误是什么?
尝试在客户端使用单个 DatagramSocket,而不是为要发送的每个 DatagramPacket 创建一个新的。或者在使用 socket.close();
完成后关闭套接字。我认为您只是打开了太多套接字。
我的 "Remote" 应用程序有问题。我想做的是使用我的 phone 作为触摸屏来控制我的 PC 的鼠标光标,到目前为止它可以工作,但有一个小问题,即在移动光标太多之后,我得到一个异常。
以下代码只有最重要的片段。
在我的 phone 上,我有以下 "Touchscreen"-区域:
RelativeLayout mouse = (RelativeLayout) findViewById(R.id.relative_layout_mouse);
mouse.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent e) {
int action = e.getAction();
if (action == MotionEvent.ACTION_MOVE) {
int historySize = e.getHistorySize();
if(historySize > 0){
//calculations on how to get x and y differences between current x/y and previous (historySize-1) x/y
new ClientUDPTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new String[]{difference_x, difference_y});
}
}
return true;
}
});
它在移动鼠标时将许多小的协调更改发送到我的 AsyncTask:
public class ClientUDPTask extends AsyncTask<String,String,String> {
@Override
protected String doInBackground(String[] params) {
ByteBuffer buffer = ByteBuffer.wrap(new byte[7]);
//put the coordinates into the ByteBuffer...
byte[] bytes = buffer.array();
InetAddress adress = null;
DatagramSocket socket = null;
try {
socket = new DatagramSocket();
adress = InetAddress.getByName("192.168.1.108");
DatagramPacket packet = new DatagramPacket(bytes, bytes.length, adress, 9000);
socket.send(packet);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
然后在我的服务器上,我使用它们来移动光标:
public class UDPServer {
private DatagramSocket socket;
public void listen() {
try {
socket = new DatagramSocket(9000);
byte[] buffer = new byte[7];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
while (true) {
try {
socket.receive(packet);
byte[] data = packet.getData();
//get coordinates out of bytearray...
Robot robot = new Robot();
int newX = x - Integer.valueOf(x);
int newY = y - Integer.valueOf(y);
robot.mouseMove(newX, newY);
} catch (AWTException e) {
e.printStackTrace();
}
}
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
现在,您可以猜到,当鼠标四处移动时,会创建许多任务,将这些数据片段发送到服务器,直到出现此异常:
java.net.SocketException: socket failed: EMFILE (Too many open files)
at libcore.io.IoBridge.socket(IoBridge.java:623)
at java.net.PlainDatagramSocketImpl.create(PlainDatagramSocketImpl.java:93)
at java.net.DatagramSocket.createSocket(DatagramSocket.java:157)
at java.net.DatagramSocket.<init>(DatagramSocket.java:80)
at java.net.DatagramSocket.<init>(DatagramSocket.java:65)
at com.example.johnsmith.remote.ClientUDPTask.doInBackground(ClientUDPTask.java:31)
at com.example.johnsmith.remote.ClientUDPTask.doInBackground(ClientUDPTask.java:15)
at android.os.AsyncTask.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: android.system.ErrnoException: socket failed: EMFILE (Too many open files)
at libcore.io.Posix.socket(Native Method)
at libcore.io.BlockGuardOs.socket(BlockGuardOs.java:282)
at libcore.io.IoBridge.socket(IoBridge.java:608)
... 11 more
这个异常指向:
socket = new DatagramSocket();
在ClientUDPTask.java
在移动过程中 LogCat 显示 ~1 KB/s 的网络使用情况。这一切都通过我的 WiFi 工作。
我以前使用 TCP 而不是 UDP 时就遇到过这个问题。尽管我也没有使用 .executeOnExecutor(...)
,但速度非常慢。
Playstore 上有无数应用程序可以执行此 Remote-Thingie,而且非常流畅,但他们是怎么做到的?
我的错误是什么?
尝试在客户端使用单个 DatagramSocket,而不是为要发送的每个 DatagramPacket 创建一个新的。或者在使用 socket.close();
完成后关闭套接字。我认为您只是打开了太多套接字。