1.IoHandler.sessionClosed 什么时候发生? 
      远程主机强制关闭连接时吗?
  
  2.关于CumulativeProtocolDecoder.doDecode的写法.下面是我写的,不知道有没有什么问题?
   
      @Override
protected boolean doDecode(IoSession session, IoBuffer in,
ProtocolDecoderOutput out) throws Exception {

// 只包含一个完整消息
                // 包含一个完整消息和另一个的一部分
// 包含一个消息的一部分
// 包含两个完整的数据消息或更多,这种情况下时in(IoBuffer)应该是同一个吧

int start = in.position();
if (in.remaining() > 3) { // 长度字段类型为int,4个字节
// int length = in.getInt(in.position());
int length = in.getInt(); if (length < 36) { // 内容长度至少36(type字段)
log.error(" 错误的Message,length" + length + ",内容长度至少36(type字段)");
throw new RuntimeException(" 错误的Message,length" + length
+ ",内容长度至少36(type字段)");
}
if (length > in.remaining()) { // 当前buffer中的数据不够长,返回false,父类方法中继续等待数据
log.debug(" 当前buffer中的数据长度:" + in.remaining() +",期待长度:" + length);
return false;
} ByteBuffer buf = in.buf(); // 完全copy,position等属性与IoBuffer一样
buf.position(0);
buf.position(4); //忽略长度字段

                        // 以下读取消息
String type = MessageWraper.popUUID(buf);
Message msg = MessageFactoryImpl.getMessageFactory().createMessage(type);
buf.position(0); // 指针回到0,为读作准备
msg.fromBuffer(buf);
msg.setReceiveTime(System.currentTimeMillis()); // 设置接收时间戳
out.write(msg);
return true;
} else {
log.debug(" 当前buffer中的数据不足4字节");
in.position(start);
return false; // 当前buffer中的数据不够长,返回false,父类方法中继续等待数据
}

   

解决方案 »

  1.   

    经过debug,
      发现当doDecode返回true时,in(IoBuffer)是同一个对象
                    返回false时,in不是同一个对象  得到结论,对于返回true的情况,要维护好in的position,limit等属性
      

  2.   

    IoBuffer.buf() 返回 ByteBufferIoBuffer底层用的还是nio的ByteBuffer(apache的人聪明,干吗要重造轮子)所以操作IoBuffer.buf()返回的ByteBuffer就是操作IoBuffer只有一个ByteBuffer副本(实现类是HeapByteBuffer)