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;
    }
}

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

4

2 回答 2

1

我发现很难在这里理解您要解码的协议。那里肯定看起来有点困惑;)

你在写一些期望在同一个连接上有很多请求的东西吗?如果是这样,那就太好了,这就是米娜擅长的……

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

通常,完整的消息将由分隔符确定,或者可能由消息开头的长度字段确定。

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

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

hth

于 2010-05-22T18:41:22.753 回答
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;
    }
}
于 2010-05-22T21:43:13.707 回答