Netty在接收数据大于1K时通常会出现TCP的粘包和半包问题,会多次调用channelRead0(ChannelHandlerContext ctx, String msg),全部读完后会调用channelReadComplete(ChannelHandlerContext ctx)。要得到接收到的全部信息,需要建一个缓冲区,把每次读到的数据保存到缓冲区,最后在channelReadComplete中进行合并,比较麻烦。 可利用Netty中已有的LengthFieldPrepender|LengthFieldBasedFrameDecoder来解决这个问题。
在发送端在pipeline中添加如下的Encoder:
ch.pipeline().addLast( new LengthFieldPrepender(4));
在接收端添加如下Decoder:
ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(1024*500,0,4,0,4));
LengthFieldBasedFrameDecoder的第一个参数表示发送数据的最大尺寸,这里是512K,如果发送数据量大于这个值,则会抛出TooLongFrameException异常。后面的参数4和Encoder中的4对应,表示数据长度所占的字节数。
这样处理后在channelRead0()中就可以直接处理完整的msg信息。
网友评论