[英]How should I handle packets in Java?
我想通过 java 中的 Socket 发送数据包。 但是我应该如何处理它以获得最佳性能和最小的失败风险?
我已经尝试过分离线程。 一个是接收,第二个是处理分组数据。 但是处理队列正在迅速填满,我备份了 1 个线程。 所以最后我认为应该有更好的方法,因为如果应用程序要长时间处理数据包,其他数据包也需要等待..
while(!isInterrupted()) {
try {
byte[] data = new byte[2];
is.readFully(data);
//GET PACKET ID
short id = ByteBuffer.wrap(data).getShort();
data = new byte[4];
is.readFully(data);
//GET PACKET SIZE
int size = ByteBuffer.wrap(data).getInt();
data = new byte[size];
is.readFully(data);
//GET DATA
Main.getInstance().getPacketHandler().handle(id, data);
} catch (IOException e) {
e.printStackTrace();
break;
}
}
public void handle(short id, byte[] b) {
//GET PACKET TYPE BY ID
PacketType type = PacketType.getById(id);
//CREATE EVENT FROM PACKET
Event event = type.getPacket(b).createEvent();
//EXECUTE EVENT TO EVERY REGISTERED LISTENER TO PROCESS DATA
for(PacketListenerInfo listener : listeners) {
for(Method method : listener.methods) {
if(method.getParameterTypes()[0].isInstance(event)) {
try {
method.invoke(listener.listener, event);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
}
正如我之前提到的,我已经尝试过这样做,但queue
列表很快就会被填满:
private Queue<HandlePacket> queue = new LinkedList<>();
public void handle(short id, byte[] b) {
queue.add(new HandlePacket(id, b));
synchronized (this) {
notify();
}
}
private class HandlePacket{
short id;
byte[] b;
public HandlePacket(short id, byte[] b) {
this.id = id;
this.b = b;
}
}
@Override
public void run() {
while(!isInterrupted()) {
if(queue == null || queue.isEmpty()) {
try {
synchronized (this) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
HandlePacket hp = queue.poll();
if(hp != null) {
PacketType type = PacketType.getById(hp.id);
Event event = type.getPacket(hp.b).createEvent();
for(PacketListenerInfo listener : listeners) {
for(Method method : listener.methods) {
if(method.getParameterTypes()[0].isInstance(event)) {
try {
method.invoke(listener.listener, event);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
}
}
}
最后,最好的解决方案(对我个人而言)是:
public void handle(short id, byte[] b) {
data.add(new HandlePacket(id, b));
executor.execute(new Processor(data));
}
class Processor implements Runnable {
private BlockingQueue<HandlePacket> dataSource;
public Processor(BlockingQueue<HandlePacket> dataSource) {
this.dataSource = dataSource;
}
@Override
public void run() {
HandlePacket hp = null;
while ((hp = dataSource.poll()) != null) {
if(hp != null) {
PacketType type = PacketType.getById(hp.id);
if(type == null) {
continue;
}
Event event = type.getPacket(hp.b).createEvent();
for(PacketListenerInfo listener : listeners) {
for(Method method : listener.methods) {
if(method.getParameterTypes()[0].isInstance(event)) {
try {
method.invoke(listener.listener, event);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.