真诚的感谢各路大神帮忙看一下。感谢,感谢,感谢!
是这样的,使用netty与设备通讯,采集设备数据,半双工,一收一发。
现在碰见了偶发性的java.lang.IndexOutOfBoundsException: readerIndex(16) + length(12) exceeds writerIndex(24): PooledUnsafeDirectByteBuf(ridx: 16, widx: 24, cap: 64),实在不知道如何解决,请各位大佬了!发报文没什么问题:ctx.writeAndFlush(elecProtocol);public class FrontMachineServer{
private static final Logger LOG = LoggerFactory.getLogger(FrontMachineServer.class);
@Value("${netty_port}")
private  int port;
@Autowired
private ServerChannelInitializer serverChannelInitializer;    public void init() {
     // 配置客户端NIO线程组
     EventLoopGroup bossGroup = new NioEventLoopGroup(); 
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        ChannelMapManage.class.getInterfaces();
        try {
         LOG.info("netty端口为:"+port);
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class) 
.childHandler(serverChannelInitializer)
//option设置主线程配置,childOption设置工作线程配置
//通过NoDelay禁用Nagle,使消息立即发出去,不用等待到一定的数据量才发出去
.option(ChannelOption.TCP_NODELAY, true)
//不设置默认就是AdaptiveRecvByteBufAllocator
            .option(ChannelOption.RCVBUF_ALLOCATOR, AdaptiveRecvByteBufAllocator.DEFAULT)
             //保持长连接状态
            .childOption(ChannelOption.SO_KEEPALIVE, true);
 //发起同步连接操作
ChannelFuture f = b.bind(port).sync(); 
//当客户端链路关闭
f.channel().closeFuture().sync();
}catch(Exception e){
LOG.error("FrontMachineServer error",e);
}finally{
//优雅退出,释放NIO线程组
 workerGroup.shutdownGracefully();
 bossGroup.shutdownGracefully();
}
    }public class ServerChannelInitializer extends ChannelInitializer<SocketChannel>{
private static final Logger LOG = LoggerFactory.getLogger(ServerChannelInitializer.class);

@Autowired
private AccessHandler accessHandler; @Override
protected void initChannel(SocketChannel ch) {
try {
ch.pipeline().addLast(new LoggingHandler(LogLevel.DEBUG));
ch.pipeline().addLast(new IdleStateHandler(CommonConstant.SERVER_READ_TIME_OUT, CommonConstant.SERVER_WRITE_TIME_OUT, CommonConstant.SERVER_READ_WRITE_TIME_OUT,TimeUnit.SECONDS));
ch.pipeline().addLast("bytescode",new Bytescode());
ch.pipeline().addLast("accessHandler",accessHandler);
} catch (Exception e) {
LOG.error("initChannel error",e);
}

}
}public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
try {
MessageReadUtil messageReadUtil=new MessageReadUtil();
ChannelId channelId=ctx.channel().id();
//读取包头的第一个字节
int beginTag=in.readByte();
if(ProtocolTagConstant.LOGIN_BEGIN_TAG==beginTag||ProtocolTagConstant.HEART_BEAT_BEGIN_TAG==beginTag){
TaskMapManage.addChannelidTaskAmount(ctx.channel().id());
//如果是登录包或者心跳包
LoginAndHeartBeatProtocol loginAndHeartBeatProtocol=messageReadUtil.readLoginAndHeartBeat(in);
if(loginAndHeartBeatProtocol!=null){
loginAndHeartBeatProtocol.setBeginTag(beginTag);
out.add(loginAndHeartBeatProtocol);
}else{
TaskMapManage.removeChannelidTaskAmount(ctx.channel().id());
}
}else if(ProtocolTagConstant.WATER_ELEC_BEGIN_TAG==beginTag){
//测试日志
int sum=in.readableBytes();
LOG.info("可读字节数量"+sum);
//如果不是登录或者心跳包,则根据channelId取出对应的通道协议
String channelType=ChannelMapManage.getChannelType(channelId);
if(ChannelTypeConstant.ELEC_METER_PROTOCOL.equals(channelType)){
ElecProtocol elecProtocol=messageReadUtil.readElec(in);
elecProtocol.setBeginTag(beginTag);
out.add(elecProtocol);
}else if(ChannelTypeConstant.WATER_METER_PROTOCOL.equals(channelType)){
WaterProtocol waterProtocol=messageReadUtil.readWater(in);
waterProtocol.setBeginTag(beginTag);
out.add(waterProtocol);
}
}
} catch (Exception e) {
LOG.error("decode error", e);

}错误打印:
[ERROR][20180711 01:40:06,579][Bytescode:74] decode error
java.lang.IndexOutOfBoundsException: readerIndex(16) + length(12) exceeds writerIndex(24): PooledUnsafeDirectByteBuf(ridx: 16, widx: 24, cap: 64)
at io.netty.buffer.AbstractByteBuf.checkReadableBytes(AbstractByteBuf.java:1138)
at io.netty.buffer.AbstractByteBuf.readBytes(AbstractByteBuf.java:648)
at io.netty.buffer.AbstractByteBuf.readBytes(AbstractByteBuf.java:656)
at com.front.machine.common.core.utils.MessageReadUtil.readElec(MessageReadUtil.java:99)
at com.front.machine.server.code.Bytescode.decode(Bytescode.java:64)
at io.netty.handler.codec.ByteToMessageCodec$1.decode(ByteToMessageCodec.java:42)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:316)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:230)
at io.netty.handler.codec.ByteToMessageCodec.channelRead(ByteToMessageCodec.java:103)
at io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:84)
at io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:153)
at io.netty.channel.PausableChannelEventExecutor.invokeChannelRead(PausableChannelEventExecutor.java:86)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:389)
at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:254)
at io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:84)
at io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:153)
at io.netty.channel.PausableChannelEventExecutor.invokeChannelRead(PausableChannelEventExecutor.java:86)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:389)
at io.netty.handler.logging.LoggingHandler.channelRead(LoggingHandler.java:285)
at io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:84)
at io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:153)
at io.netty.channel.PausableChannelEventExecutor.invokeChannelRead(PausableChannelEventExecutor.java:86)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:389)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:956)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:127)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:514)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:471)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:385)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:351)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116)
at io.netty.util.internal.chmv8.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1412)
at io.netty.util.internal.chmv8.ForkJoinTask.doExec(ForkJoinTask.java:280)
at io.netty.util.internal.chmv8.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:877)
at io.netty.util.internal.chmv8.ForkJoinPool.scan(ForkJoinPool.java:1706)
at io.netty.util.internal.chmv8.ForkJoinPool.runWorker(ForkJoinPool.java:1661)
at io.netty.util.internal.chmv8.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:126)
[DEBUG][20180711 01:40:07,088][ClientCnxn$SendThread:742] Got ping response for sessionid: 0x1646908a7bc000c after 0ms
[DEBUG][20180711 01:40:10,003][DecodeHandler:60]  [DUBBO] Decode decodeable message com.alibaba.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation, dubbo version: 2.5.7, current host: 127.0.0.1