我正在使用LengthFieldBasedFrameDecoder
发送和接收功能,byte[]
但是客户端java.nio.channels.ClosedChannelException
在写入后会出错。
这是管道工厂;
@Override
public ChannelPipeline getPipeline() throws Exception {
String charSet = EvamProperties.charSet.get();
ChannelPipeline pipeline = Channels.pipeline();
pipeline.addLast("framer", new LengthFieldBasedFrameDecoder(1000000,0,4,0,4));//16KB
pipeline.addLast("decoder", new OneToOneDecoder() {
@Override
protected Object decode(ChannelHandlerContext channelHandlerContext, Channel channel, Object o) throws Exception {
if (!(o instanceof ChannelBuffer)) {
return o;
}
ChannelBuffer buffer = (ChannelBuffer) o;
int length = buffer.readInt();
byte[] bytes = new byte[length];
buffer.readBytes(bytes);
return bytes;
}
});
pipeline.addLast("encoder", new OneToOneEncoder() {
@Override
protected Object encode(ChannelHandlerContext channelHandlerContext, Channel channel, Object o) throws Exception {
if(!(o instanceof byte[])) {
return o;
}
ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
buffer.writeInt(((byte[]) o).length);
buffer.writeBytes((byte[])o);
return buffer;
}
});
pipeline.addLast("handler", new RawEventServerHandler());
return pipeline;
}
客户以这种方式编写;
channel.write(eventStr.getBytes());
在此代码中,出于调试目的,要发送的数据是String,但我不能使用StringDecoder。
请问LenghtFieldBasedDecoder
是正确的发送和接收方法byte[]
,如果没有,我该怎么办?
编辑:
我发现实际上关闭了该通道的另一个线程java.nio.channels.ClosedChannelException
已解决,但是我仍然渴望学习此类工作的最佳实践。
根据您的问题,我看到了3种不同的用例:
length
存储在帧中的某些特定帧,您需要捕获一个帧byte[length]
并将其传输给用户length
帧,您需要捕获一个帧byte[length]
并将其传输给用户byte[]
数组在(1)的情况下,LengthFieldBasedFrameDecoder
正确的选择是,它允许您根据存储在帧中的长度来捕获帧。在(2)的情况下,FixedLengthFrameDecoder
如果您知道所有框架的大小均应足够。在(3)的情况下,您不需要任何特殊的解码器,所有可读的字节都可以从传入的数据中提取ByteBuf
并传输到下一个处理程序,但是我不确定这种方法在实际应用中有多有用,因为您很可能会Netty不处理某些特定类型/大小的消息,Netty不保证将如何精确分割消息,一条消息可以N个不同的块的形式到达。
也有是ReplayingDecoder
那是,如果你想进入的解码字节,跳过捕捉步骤例(1-2)是有用的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句