有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Netty解码器的正确用法

我又一次问了一个关于内蒂的问题

我的设想是:

传入消息(TCP)=标头[字节,整数,字节]正文[字节]

我有一个包类,它保存头&;身体有一些方法。 我的渠道是:

ProtocolDecoder > SessionHandler

我对Protocolder的想法是,它接收一条消息,将其拆分并创建一个数据包变量以传递给管道中的下一个处理程序

ProtocoldCoder类的代码:

public class ProtocolDecoder extends ByteToMessageDecoder {

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {

    int opCode;
    int length;
    boolean encrypt;

    if (in.readableBytes() < 6) {
        return;
    }

    if (out.size() != 1) {
        Packet pa = new Packet();
        opCode = in.readByte();
        length = in.readInt();
        encrypt = in.readByte() == 1;
        pa.setOpcode(opCode);
        pa.setEncrypted(encrypt);
        pa.setLength(length);
        out.add(pa);
        in.discardReadBytes();
    }

    Packet p = (Packet) out.get(0);

    if (in.readableBytes() >= p.getLength()) {
        p.setPayload(in.copy());
    }
    }

}

SessionHandler具有以下代码:

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
Packet p = (Packet) msg;
System.out.println("Packet: " + p.toString());
}

所以我的两个问题是:

  • 这是ByteToMessageDecoder的正确用法吗
  • 当我访问数据包的toString()方法中的直接缓冲区(array()方法)时,如何解决错误:“java.lang.UnsupportedOperationException:direct buffer”

更新:

我重新制作了解码器,这是我的结果:http://pastebin.com/wQz2LbYT

我不确定我是否必须把代码放在这里,因为这篇文章会变得相当大。不管怎样,它现在似乎工作得很好:)非常感谢


共 (1) 个答案

  1. # 1 楼答案

    您没有正确使用ByteToMessageDecoder,因为一旦向列表(out)中添加了某些内容,一旦该方法返回并转发到ChannelPipeline中的下一个ChannelInboundHandler,它就会被删除。如果您需要保留对数据包的引用,直到将其添加到out,请在类中为其使用一个字段

    只有当hasArray()返回true时,才能访问array()。否则,缓冲区本身由本机内存支持。在这种情况下,您需要使用它的一个getBytes(…)方法将内容复制到数组。也就是说,如果您只想将缓冲区的内容作为字符串获取,那么可以使用ByteBuf。toString(字符集)用于此