2010-05-22 102 views
0
public class CustomProtocolDecoder extends CumulativeProtocolDecoder{ 
byte currentCmd = -1; 
int currentSize = -1; 
boolean isFirst = false; 
@Override 
protected boolean doDecode(IoSession is, ByteBuffer bb, ProtocolDecoderOutput pdo) throws Exception { 
     if(currentCmd == -1) 
     { 
      currentCmd = bb.get(); 
      currentSize = Packet.getSize(currentCmd); 
      isFirst = true; 
     } 
     while(bb.remaining() > 0) 
     { 
      if(!isFirst) 
      { 
       currentCmd = bb.get(); 
       currentSize = Packet.getSize(currentCmd); 
      } 
      else 
       isFirst = false; 
      //System.err.println(currentCmd + " " + bb.remaining() + " " + currentSize); 
      if(bb.remaining() >= currentSize - 1) 
      { 
       Packet p = PacketDecoder.decodePacket(bb, currentCmd); 
       pdo.write(p); 
      } 
      else 
      { 
       bb.flip(); 
       return false; 
      } 
     } 
     if(bb.remaining() == 0) 
      return true; 
     else 
      return false; 
} 

}这是在MINA中编写ProtocolDecoder的正确方法吗?

任何人看到什么毛病此代码?当一次接收到大量数据包时,即使只连接了一个客户端,其中一个数据包可能会在最后被切断(例如12个字节,而不是15个字节),这显然很糟糕。

回答

1

我发现有点难以理解你在这里尝试解码的协议。这是肯定看起来有点困惑在那里;)

你写的东西,期望在同一连接上的许多请求?如果是这样,那么很好,这就是米娜的擅长...

通常,我希望MINA解码器检查它是否有一个完整的消息,然后,如果没有,将IoBuffer的指针返回到它在方法开始时保持的位置。

正常情况下,完整的消息将由定界符或消息开始处的长度字段确定。

api文档中提供的示例非常好。 它寻找回车+换行分隔符:

http://mina.apache.org/report/trunk/apidocs/org/apache/mina/filter/codec/CumulativeProtocolDecoder.html

心连心

0

从例如一些帮助想通了 - 我有真假混淆,并没有意识到我应该跟踪输入缓冲区的位置。最重要的是,我不知道我不需要while循环。谢谢!

protected boolean doDecode(IoSession is, ByteBuffer bb, ProtocolDecoderOutput pdo) throws Exception { 
    int start = bb.position(); 
    currentCmd = bb.get(); 
    currentSize = Packet.getSize(currentCmd); 
    //System.err.println(currentCmd + " " + bb.remaining() + " " + currentSize); 
    if(bb.remaining() >= currentSize - 1) 
    { 
     Packet p = PacketDecoder.decodePacket(bb, currentCmd); 
     pdo.write(p); 
     if(bb.remaining() == 0) 
      return false; 
     else 
      return true; 
    } 
    else 
    { 
     bb.position(start); 
     return false; 
    } 
}