2018-07-18

相关变量

    private final int maxLength;//要解析帧的最大长度
    /** Whether or not to throw an exception as soon as we exceed maxLength. */
    private final boolean failFast;//如果设置成true,当发现解析的数据超过maxLenght就立马报错,否则当整个帧的数据解析完后才报错
    private final boolean stripDelimiter; //解码时是否去掉分隔符

    /** True if we're discarding input because we're already over maxLength.  */
    private boolean discarding;//如果没有找到分隔符且读取的数据超过最大长度,我们将将其设置为true
    private int discardedBytes;

    /** Last scan position. */
    private int offset;
discarding:如果没有找到分隔符且读取的数据超过最大长度,我们将将其设置为true
    private int findEndOfLine(final ByteBuf buffer) {
        int totalLength = buffer.readableBytes();//可读的字节长度
        //遍历从buffer.readerIndex() + offset到 buffer.readerIndex() + totalLength之间的数据,是否匹配ByteProcessor.FIND_LF
        int i = buffer.forEachByte(buffer.readerIndex() + offset, totalLength - offset, ByteProcessor.FIND_LF);
        if (i >= 0) {
            offset = 0;
            //匹配\r\n
            if (i > 0 && buffer.getByte(i - 1) == '\r') {
                i--;
            }
        } else {
            //下次处理的时候跳过上次没匹配的数据
            offset = totalLength;
        }
        return i;
    }

LineBasedFrameDecoderdecode(ChannelHandlerContext ctx, ByteBuf buffer)方法

 protected Object decode(ChannelHandlerContext ctx, ByteBuf buffer) throws Exception {
  //匹配到第一个结束符的位置\r的位置
 final int eol = findEndOfLine(buffer);
        if (!discarding) {
            //第一次肯定走这里
            if (eol >= 0) {
                final ByteBuf frame;
                final int length = eol - buffer.readerIndex();//匹配到的数据长度
                final int delimLength = buffer.getByte(eol) == '\r'? 2 : 1;//界定长度

                if (length > maxLength) {
                    buffer.readerIndex(eol + delimLength);//读取数据,移动readIndex
                    fail(ctx, length);
                    return null;
                }

                if (stripDelimiter) {
                    frame = buffer.readRetainedSlice(length);//读取数据并移动readIndex
                    buffer.skipBytes(delimLength);//有界定符的话,在buffer中跳过界定符               
                } else {
                    frame = buffer.readRetainedSlice(length + delimLength);
                }

                return frame;
            } else {//匹配失败,并且缓冲区可读的数据大于MaxLength。(说明这一段数据时无效的)设置readerIndex,discading=true
                final int length = buffer.readableBytes();
                if (length > maxLength) {
                    discardedBytes = length;
                    buffer.readerIndex(buffer.writerIndex());//设置readerIndex
                    discarding = true;
                    offset = 0;
                    if (failFast) {
                        fail(ctx, "over " + discardedBytes);
                    }
                }
                return null;
            }
        } else {
            if (eol >= 0) {
                final int length = discardedBytes + eol - buffer.readerIndex();
                final int delimLength = buffer.getByte(eol) == '\r'? 2 : 1;
                //下一次从上面开始,这样设置读指针会不会导致丢弃了一个有效帧?
                buffer.readerIndex(eol + delimLength);
                discardedBytes = 0;
                discarding = false;
                if (!failFast) {
                    fail(ctx, length);
                }
            } else {
                discardedBytes += buffer.readableBytes();
                buffer.readerIndex(buffer.writerIndex());
            }
            return null;
        }
    }

你可能感兴趣的:(2018-07-18)