我再次提出一个关于Netty的问题。
我的情景是:
传入消息(TCP)=头[byte,int,byte] body [bytes]
我有一个包含标题和数据包的数据包类。身体有一些方法。 我的频道管道是:
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());
}
所以我的两个问题是:
array()
方法中访问直接缓冲区(toString()
方法)时,如何解决错误:“java.lang.UnsupportedOperationException:direct buffer”?更新
我重新设计了解码器,这是我的结果:http://pastebin.com/wQz2LbYT
我不确定是否必须将代码放在此处,因为这篇文章会变得非常大。无论如何它现在似乎工作正常:)非常感谢!
答案 0 :(得分:4)
你没有正确使用ByteToMessageDecoder,因为一旦你向List添加了东西(out),一旦方法返回并转发到ChannelPipeline中的下一个ChannelInboundHandler,它将被删除。如果您需要保留对数据包的引用,直到将其添加到其中,请使用类中的字段。
如果hasArray()返回true,则只能访问array()。否则缓冲区本身由本机内存支持。在这种情况下,您需要使用其中一个getBytes(...)方法将内容复制到数组中。也就是说,如果您只想将缓冲区的内容作为字符串获取,则可以使用ByteBuf.toString(Charset)。