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 楼答案
您没有正确使用ByteToMessageDecoder,因为一旦向列表(out)中添加了某些内容,一旦该方法返回并转发到ChannelPipeline中的下一个ChannelInboundHandler,它就会被删除。如果您需要保留对数据包的引用,直到将其添加到out,请在类中为其使用一个字段
只有当hasArray()返回true时,才能访问array()。否则,缓冲区本身由本机内存支持。在这种情况下,您需要使用它的一个getBytes(…)方法将内容复制到数组。也就是说,如果您只想将缓冲区的内容作为字符串获取,那么可以使用ByteBuf。toString(字符集)用于此