繁体   English   中英

我应该如何处理 Java 中的数据包?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM