繁体   English   中英

Netty-正确使用解码器

[英]Netty - Correct usage of a decoder

我再次有一个关于Netty的问题。

我的情况是:

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

我有一个包类,其中包含一些方法的标头和正文。 我的频道管道是:

ProtocolDecoder> SessionHandler

我对ProtocolDecoder的想法是,它接收一条消息,将其拆分并创建一个Packet变量,以传递到管道中的下一个处理程序。

ProtocolDecoder类的代码:

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:直接缓冲区”?

更新:

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

我不确定是否必须将代码放在这里,因为这篇文章会变得很大。 无论如何,现在看来一切正常:)非常感谢!

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

如果hasArray()返回true,则只能访问array()。 否则,缓冲区本身将由本机内存支持。 在这种情况下,您将需要使用其getBytes(...)方法之一将内容复制到数组。 也就是说,如果您只想将缓冲区的内容作为字符串获取,则可以使用ByteBuf.toString(Charset)来实现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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