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

发布于 2024-09-02 08:24:41 字数 1411 浏览 5 评论 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 字节),这显然是不好的。

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

Anyone see anything wrong with this code? When a lot of packets are received at once, even when only one client is connected, one of them might get cut off at the end (12 bytes instead of 15 bytes, for example) which is obviously bad.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

她说她爱他 2024-09-09 08:24:42

在示例的帮助下弄清楚了——我对真假感到困惑,并且没有意识到我应该跟踪输入缓冲区的位置。最重要的是,我不知道我不需要 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;
    }
}

Figured it out with some help from the example -- I had true and false confused, and didn't realize I was supposed to keep track of the position of the input buffer. And on top of that, I didn't know that I didn't need the while loop. Thanks!

    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;
    }
}
我喜欢麦丽素 2024-09-09 08:24:41

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

您是否正在编写一些需要在同一连接上发出许多请求的内容?如果是这样,那就太好了,这就是 Mina 所擅长的......

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

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

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

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

hth

I'm finding it a bit difficult to understand what protocol you're trying to decode here. It's definitely looking a bit confused in there ;)

Are you writing something which expects many requests on the same connection? If so, then great, that's what Mina's good at ...

Normally, I'd expect a MINA decoder to be checking whether it's got a complete message, and then, if not, to return the IoBuffer's pointer back to the position it held at the start of the method.

Normally a complete message would be determined by a delimiter, or perhaps a length field at the start of the message.

The example provided in the api docs is pretty good.
It's looking for a delimiter of Carriage Return + Line Break:

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

hth

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文