Это правильный способ написать ProtocolDecoder в MINA? - PullRequest
0 голосов
/ 22 мая 2010
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 байт), что явно плохо.

Ответы [ 2 ]

1 голос
/ 22 мая 2010

Мне трудно понять, какой протокол вы пытаетесь здесь декодировать. Это определенно выглядит немного запутанным там;)

Вы пишете что-то, что ожидает много запросов по одному соединению? Если так, то отлично, вот в чем Мина хороша ...

Обычно я ожидаю, что декодер MINA проверит, получило ли оно полное сообщение, а затем, если нет, вернет указатель IoBuffer обратно в положение, которое он занимал в начале метода.

Обычно полное сообщение определяется разделителем или, возможно, полем длины в начале сообщения.

Пример, приведенный в api docs, довольно хорош. Он ищет разделитель возврата каретки + разрыв строки:

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

НТН

0 голосов
/ 23 мая 2010

Понял это с некоторой помощью из примера - я перепутал истину и ложь и не понял, что должен был отслеживать положение входного буфера.И вдобавок ко всему, я не знал, что мне не нужен цикл 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;
    }
}
...