Framedecoder缓冲区在高tps时损坏

时间:2012-07-17 07:44:13

标签: java tcp netty

我有一个非常简单的解码器,它扩展了FrameDecoder。

它将解码一个简单的文本协议(总是可变长度),并将读取缓冲区,直到找到'\ r',然后返回ChannelBuffer(包含1个已解码的消息)。

示例文本协议/消息:

XXXX,YYYY,ZZZZ \ r

我总是将解码器和stringdecoder结合起来,如下所示:

p.addLast("stdDecoder", new SimpleTextDecoder()); //extends FrameDecoder

p.addLast("stringDecoder", new StringDecoder(CharsetUtil.UTF_8));

一切正常,直到我达到更高的tps(+/- 200tps),然后ChannelBuffer偶尔开始返回这样的缓冲区:

> xxxx,yyyxxxx,yyyy,zzzz \ r

或者:

> y,zzzz \ r 等。

解码器:

   public static final char END_MESSAGE = 13;

   if (buffer.readableBytes() < 6) {
          return null;
   }
   buffer.markReaderIndex();
   if (1 <= buffer.readableBytes()) {
        byte bite = buffer.readByte();
        if (bite != END_MESSAGE) {
           /* Create a new ChannelBuffer which is used for the cumulation. */
           ChannelBuffer frameBuffer = buffer.factory().getBuffer(buffer.capacity());

           /* Write  byte */
           frameBuffer.writeByte(bite);

           while (buffer.readable()) {
               /* read next byte */
               bite = buffer.readByte();
               if (bite != END_MESSAGE) {
                   frameBuffer.writeByte(bite);
               } else {
                   /* Write end message and return buffer */
                   frameBuffer.writeByte(bite);
                  return frameBuffer;
               }
           }
       } else {
           return null;
       }
    }

    /* not readable bytes return null*/
    return null;
}

编辑:好的新版本,现在正在运行..如果可能的话,想要一些反馈:)

public class xxxxDecoder extends FrameDecoder {
    private static final Logger log = LoggerFactory.getLogger(xxxxDecoder.class);
    public static final char END_MESSAGE = 13;
    public static final char START_MESSAGE = 83;

    //Decodes the received packets so far into a frame.
    @Override
    protected Object decode(ChannelHandlerContext ctx,
                            Channel channel,
                            ChannelBuffer buffer) throws Exception {

        /* Shortest known xxx message\r
         * 8 bytes
         */
        if (buffer.readableBytes() < 8) {
            if (Consts.DEBUG_ENABLED) {
                log.debug("YAWN... data Smaller than 8 bytes,waiting for more," + buffer.readableBytes());
            }
            /*If null is returned, it means there's not enough data yet.*/
            buffer.resetReaderIndex();
            return null;
        } else {
            log.debug("Readable bytes=" + buffer.readableBytes() + ",buffersize=" + buffer.capacity());
        }


        /* Mark the "end, i think?" of this buffer  */
        buffer.markReaderIndex();

        if (1 <= buffer.readableBytes()) {

            byte bite = buffer.readByte();
            if (bite != END_MESSAGE) {
                if (Consts.DEBUG_ENABLED) {
                    log.debug("Yipee...Found new message," + bite + ",buffersize=" + buffer.capacity());
                }

                /* Create a new ChannelBuffer which is used for the cumulation. */
                ChannelBuffer frameBuffer = buffer.factory().getBuffer(buffer.capacity());

                /* Write  byte */
                frameBuffer.writeByte(bite);

                while (buffer.readable()) {
                    /* read next byte */
                    bite = buffer.readByte();
                    if (bite != END_MESSAGE) {
                        frameBuffer.writeByte(bite);
                    } else {
                        /* Write end message and return buffer */
                        frameBuffer.writeByte(bite);
                        if (Consts.DEBUG_ENABLED) {
                            log.debug("Aha...Found end message=" + bite + ", returning complete message");
                        }
                        return frameBuffer;
                    }
                }
            } else {
                /*If null is returned, it means there's not enough data yet.*/
                buffer.resetReaderIndex();
                return null;
            }
        }

        /* not readable bytes return null*/
        buffer.resetReaderIndex();
        return null;
    }

0 个答案:

没有答案