Java Code Examples for org.apache.mina.core.buffer.IoBuffer#clear()

The following examples show how to use org.apache.mina.core.buffer.IoBuffer#clear() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: MassProtocolDecoder.java    From game-server with MIT License 6 votes vote down vote up
/** {@inheritDoc} */
@Override
protected boolean doDecode(IoSession session, IoBuffer ib, ProtocolDecoderOutput out) throws Exception {
    if (ib.remaining() < 4) {
        return false;
    }
    ib.mark();
    int length = ib.getInt();
    if (length < 1 || length > maxReadSize) {
        int id = ib.getInt();
        ib.clear();
        log.warn("消息解析异常:长度{},id {}, 大于长度 maxReadSize {}", length, id, maxReadSize);
        session.close(true);
        return false;
    }

    if (ib.remaining() < length) {
        ib.reset();
        return false;
    }
    decodeBytes(length, ib, out);
    return true;
}
 
Example 2
Source File: RTMPEIoFilter.java    From red5-client with Apache License 2.0 5 votes vote down vote up
@Override
public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest request) throws Exception {
    RTMPMinaConnection conn = (RTMPMinaConnection) RTMPConnManager.getInstance().getConnectionBySessionId((String) session.getAttribute(RTMPConnection.RTMP_SESSION_ID));
    // filter based on current connection state
    if (conn.getState().getState() == RTMP.STATE_CONNECTED && session.containsAttribute(RTMPConnection.RTMPE_CIPHER_OUT)) {
        Cipher cipher = (Cipher) session.getAttribute(RTMPConnection.RTMPE_CIPHER_OUT);
        IoBuffer message = (IoBuffer) request.getMessage();
        if (!message.hasRemaining()) {
            if (log.isTraceEnabled()) {
                log.trace("Ignoring empty message");
            }
            nextFilter.filterWrite(session, request);
        } else {
            if (log.isDebugEnabled()) {
                log.debug("Encrypting message: {}", message);
            }
            byte[] plain = new byte[message.remaining()];
            message.get(plain);
            message.clear();
            message.free();
            // encrypt and write
            byte[] encrypted = cipher.update(plain);
            IoBuffer messageEncrypted = IoBuffer.wrap(encrypted);
            if (log.isDebugEnabled()) {
                log.debug("Encrypted message: {}", messageEncrypted);
            }
            nextFilter.filterWrite(session, new EncryptedWriteRequest(request, messageEncrypted));
        }
    } else {
        log.trace("Non-encrypted message");
        nextFilter.filterWrite(session, request);
    }
}
 
Example 3
Source File: CachedIoBufferAllocator.java    From jane with GNU Lesser General Public License v3.0 5 votes vote down vote up
@Override
public IoBuffer allocate(int requestedCapacity, boolean direct)
{
	if (requestedCapacity <= 0)
		return direct ? SimpleBufferAllocator.emptyDirectBuffer : SimpleBufferAllocator.emptyBuffer;

	int actualCapacity = Integer.highestOneBit(requestedCapacity);
	if (actualCapacity < requestedCapacity)
	{
		actualCapacity += actualCapacity;
		if (actualCapacity < 0)
			actualCapacity = requestedCapacity; // must be > 0x4000_0000
	}
	IoBuffer buf;
	if (actualCapacity <= maxCachedBufferSize)
	{
		buf = (direct ? directBuffers : heapBuffers).get()[getIdx(actualCapacity)].pollFirst();
		if (buf != null)
		{
			buf.clear();
			buf.buf().order(ByteOrder.BIG_ENDIAN);
			reuseCount.getAndIncrement();
		}
		else
		{
			buf = new CachedBuffer(actualCapacity, direct);
			allocCount.getAndIncrement();
		}
	}
	else
		buf = SimpleBufferAllocator.instance.allocate(actualCapacity, direct);
	buf.limit(requestedCapacity);
	return buf;
}
 
Example 4
Source File: BufferedWriteFilter.java    From neoscada with Eclipse Public License 1.0 5 votes vote down vote up
/**
 * Internal method that actually flushes the buffered data.
 * 
 * @param nextFilter the {@link NextFilter} of this filter
 * @param session the session where buffer will be written
 * @param buf the data to write
 * @throws Exception if a write operation fails
 */
private void internalFlush(NextFilter nextFilter, IoSession session, IoBuffer buf) throws Exception {
    IoBuffer tmp = null;
    synchronized (buf) {
        buf.flip();
        tmp = buf.duplicate();
        buf.clear();
    }
    logger.debug("Flushing buffer: {}", tmp);
    nextFilter.filterWrite(session, new DefaultWriteRequest(tmp));
}
 
Example 5
Source File: RTMPProtocolDecoder.java    From red5-server-common with Apache License 2.0 5 votes vote down vote up
/**
 * Decodes the buffer data.
 * 
 * @param conn
 *            RTMP connection
 * @param state
 *            Stores state for the protocol, ProtocolState is just a marker interface
 * @param in
 *            IoBuffer of data to be decoded
 * @return one of three possible values:
 * 
 *         <pre>
 * 1. null : the object could not be decoded, or some data was skipped, just continue 
 * 2. ProtocolState : the decoder was unable to decode the whole object, refer to the protocol state 
 * 3. Object : something was decoded, continue
 * </pre>
 * @throws ProtocolException
 *             on error
 */
public Object decode(RTMPConnection conn, RTMPDecodeState state, IoBuffer in) throws ProtocolException {
    //if (log.isTraceEnabled()) {
    //log.trace("Decoding for {}", conn.getSessionId());
    //}
    try {
        final byte connectionState = conn.getStateCode();
        switch (connectionState) {
            case RTMP.STATE_CONNECTED:
                return decodePacket(conn, state, in);
            case RTMP.STATE_ERROR:
            case RTMP.STATE_DISCONNECTING:
            case RTMP.STATE_DISCONNECTED:
                // throw away any remaining input data:
                in.clear();
                return null;
            default:
                throw new IllegalStateException("Invalid RTMP state: " + connectionState);
        }
    } catch (ProtocolException pe) {
        // raise to caller unmodified
        throw pe;
    } catch (RuntimeException e) {
        throw new ProtocolException("Error during decoding", e);
    } finally {
        //if (log.isTraceEnabled()) {
        //log.trace("Decoding finished for {}", conn.getSessionId());
        //}
    }
}
 
Example 6
Source File: VideoData.java    From red5-server-common with Apache License 2.0 5 votes vote down vote up
/** {@inheritDoc} */
@Override
protected void releaseInternal() {
    if (data != null) {
        final IoBuffer localData = data;
        // null out the data first so we don't accidentally
        // return a valid reference first
        data = null;
        localData.clear();
        localData.free();
    }
}
 
Example 7
Source File: StatusObjectService.java    From red5-server-common with Apache License 2.0 5 votes vote down vote up
/**
 * Cache status objects
 */
public void cacheStatusObjects() {

    cachedStatusObjects = new HashMap<String, byte[]>();

    String statusCode;
    IoBuffer out = IoBuffer.allocate(256);
    out.setAutoExpand(true);

    for (String s : statusObjects.keySet()) {
        statusCode = s;
        StatusObject statusObject = statusObjects.get(statusCode);
        if (statusObject instanceof RuntimeStatusObject) {
            continue;
        }
        serializeStatusObject(out, statusObject);
        out.flip();
        if (log.isTraceEnabled()) {
            log.trace(HexDump.formatHexDump(out.getHexDump()));
        }
        byte[] cachedBytes = new byte[out.limit()];
        out.get(cachedBytes);
        out.clear();
        cachedStatusObjects.put(statusCode, cachedBytes);
    }
    out.free();
    out = null;
}
 
Example 8
Source File: Aggregate.java    From red5-server-common with Apache License 2.0 5 votes vote down vote up
/** {@inheritDoc} */
@Override
protected void releaseInternal() {
    if (data != null) {
        final IoBuffer localData = data;
        // null out the data first so we don't accidentally
        // return a valid reference first
        data = null;
        localData.clear();
        localData.free();
    }
}
 
Example 9
Source File: NullProtocolDecoder.java    From neoscada with Eclipse Public License 1.0 4 votes vote down vote up
@Override
public void decode ( final IoSession session, final IoBuffer in, final ProtocolDecoderOutput out ) throws Exception
{
    in.clear ();
}
 
Example 10
Source File: FLVWriter.java    From red5-io with Apache License 2.0 4 votes vote down vote up
private Map<String, ?> getMetaData(Path path, int maxTags) throws IOException {
    Map<String, ?> meta = null;
    // attempt to read the metadata
    SeekableByteChannel channel = Files.newByteChannel(path, StandardOpenOption.READ);
    long size = channel.size();
    log.debug("Channel open: {} size: {} position: {}", channel.isOpen(), size, channel.position());
    if (size > 0L) {
        // skip flv signature 4b, flags 1b, data offset 4b (9b), prev tag size (4b)
        channel.position(appendOffset);
        // flv tag header size 11b
        ByteBuffer dst = ByteBuffer.allocate(11);
        do {
            int read = channel.read(dst);
            if (read > 0) {
                dst.flip();
                byte tagType = (byte) (dst.get() & 31); // 1
                int bodySize = IOUtils.readUnsignedMediumInt(dst); // 3
                int timestamp = IOUtils.readExtendedMediumInt(dst); // 4
                int streamId = IOUtils.readUnsignedMediumInt(dst); // 3
                log.debug("Data type: {} timestamp: {} stream id: {} body size: {}", new Object[] { tagType, timestamp, streamId, bodySize });
                if (tagType == ITag.TYPE_METADATA) {
                    ByteBuffer buf = ByteBuffer.allocate(bodySize);
                    read = channel.read(buf);
                    if (read > 0) {
                        buf.flip();
                        // construct the meta
                        IoBuffer ioBuf = IoBuffer.wrap(buf);
                        Input input = new Input(ioBuf);
                        String metaType = Deserializer.deserialize(input, String.class);
                        log.debug("Metadata type: {}", metaType);
                        meta = Deserializer.deserialize(input, Map.class);
                        input = null;
                        ioBuf.clear();
                        ioBuf.free();
                        if (meta.containsKey("duration")) {
                            appendOffset = channel.position() + 4L;
                            break;
                        }
                    }
                    buf.compact();
                }
                // advance beyond prev tag size
                channel.position(channel.position() + 4L);
                //int prevTagSize = dst.getInt(); // 4
                //log.debug("Previous tag size: {} {}", prevTagSize, (bodySize - 11));
                dst.compact();
            }
        } while (--maxTags > 0); // read up-to "max" tags looking for duration
        channel.close();
    }
    return meta;
}
 
Example 11
Source File: RTMPProtocolDecoder.java    From red5-server-common with Apache License 2.0 4 votes vote down vote up
/**
 * Decode all available objects in buffer.
 * 
 * @param conn
 *            RTMP connection
 * @param buffer
 *            IoBuffer of data to be decoded
 * @return a list of decoded objects, may be empty if nothing could be decoded
 */
public List<Object> decodeBuffer(RTMPConnection conn, IoBuffer buffer) {
    final int position = buffer.position();
    //if (log.isTraceEnabled()) {
    //log.trace("decodeBuffer: {}", Hex.encodeHexString(Arrays.copyOfRange(buffer.array(), position, buffer.limit())));
    //}
    // decoded results
    List<Object> result = null;
    if (conn != null) {
        //log.trace("Decoding for connection - session id: {}", conn.getSessionId());
        try {
            // instance list to hold results
            result = new LinkedList<>();
            // get the local decode state
            RTMPDecodeState state = conn.getDecoderState();
            //if (log.isTraceEnabled()) {
            //log.trace("RTMP decode state {}", state);
            //}
            if (!conn.getSessionId().equals(state.getSessionId())) {
                log.warn("Session decode overlap: {} != {}", conn.getSessionId(), state.getSessionId());
            }
            int remaining;
            while ((remaining = buffer.remaining()) > 0) {
                if (state.canStartDecoding(remaining)) {
                    //log.trace("Can start decoding");
                    state.startDecoding();
                } else {
                    log.trace("Cannot start decoding");
                    break;
                }
                final Object decodedObject = decode(conn, state, buffer);
                if (state.hasDecodedObject()) {
                    //log.trace("Has decoded object");
                    if (decodedObject != null) {
                        result.add(decodedObject);
                    }
                } else if (state.canContinueDecoding()) {
                    //log.trace("Can continue decoding");
                    continue;
                } else {
                    log.trace("Cannot continue decoding");
                    break;
                }
            }
        } catch (Exception ex) {
            log.warn("Failed to decodeBuffer: pos {}, limit {}, chunk size {}, buffer {}", position, buffer.limit(), conn.getState().getReadChunkSize(), Hex.encodeHexString(Arrays.copyOfRange(buffer.array(), position, buffer.limit())));
            // catch any non-handshake exception in the decoding; close the connection
            log.warn("Closing connection because decoding failed: {}", conn, ex);
            // clear the buffer to eliminate memory leaks when we can't parse protocol
            buffer.clear();
            // close connection because we can't parse data from it
            conn.close();
        } finally {
            //if (log.isTraceEnabled()) {
            //log.trace("decodeBuffer - post decode input buffer position: {} remaining: {}", buffer.position(), buffer.remaining());
            //}
            buffer.compact();
        }
    } else {
        log.error("Decoding buffer failed, no current connection!?");
    }
    return result;
}
 
Example 12
Source File: MyTextLineCodecDecoder.java    From java-study with Apache License 2.0 4 votes vote down vote up
private void decodeNormal(Context ctx, IoBuffer in, ProtocolDecoderOutput out) throws CharacterCodingException {
   
    // 取出未完成任务中已经匹配的文本换行符的个数
    int matchCount = ctx.getMatchCount();
		   
    // 设置匹配文本换行符的IoBuffer变量
    if (delimBuf == null) {
        IoBuffer tmp = IoBuffer.allocate(2).setAutoExpand(true);
        tmp.putString(delimiter, charset.newEncoder());
        tmp.flip();
        delimBuf = tmp;
    }

    //解码的IoBuffer中数据的原始信息
    int oldPos = in.position();  //输出值为0
    int oldLimit = in.limit();   //输出值为1
           
    logger.info("******************************************************************************");       
    logger.info("开始进入解码方法-----------------------------------------------------------------");
    logger.info("");
    logger.info("init Start--------------------------------------------------------------------");
    logger.info("in.postion() = "+oldPos);
    logger.info("in.Limit() = "+oldLimit);
    logger.info("in.capacity() = "+in.capacity());
    logger.info("matchCount = "+matchCount);
    logger.info("init End---------------------------------------------------------------------");
    logger.info("");
   
    //变量解码的IoBuffer
    while (in.hasRemaining()) {           
       
        byte b = in.get();           
        logger.info("");
        logger.info("输入进来的字符为 = "+(char)b+",对应的ascii值 = "+b);
        logger.info("in.position() = "+in.position()+",in.limit() = "+in.limit());
        logger.info("");
       
        //当b的ascii值为13,10 即为\r,\n时,会进入下述if语句
        if (delimBuf.get(matchCount) == b) {
           
            // b='\r'时,matchCount=1, b='\n'时,matchCount=2
            matchCount++;   
           
            logger.info("matchCount = "+matchCount);
            //当前匹配到字节个数与文本换行符字节个数相同,即 b='\n'时
            //此时matchCount=2, delimBuf.limit()=2
           
            if (matchCount == delimBuf.limit()) {                       
               
                    // 获得当前匹配到的position(position前所有数据有效)
                    int pos = in.position();    //值为2           
                    logger.info("pos = "+pos);
                   
                    in.limit(pos); //值为2
                    // position回到原始位置
                    in.position(oldPos); //值为0
                   
                    // 追加到Context对象未完成数据后面
                    ctx.append(in); //将 \r\n这两个字符添加到 ctx.getBuf()中
                   
                    // in中匹配结束后剩余数据
                    in.limit(oldLimit); //值为2
                    in.position(pos); //值为2
                                       
                    IoBuffer buf = ctx.getBuf(); //此时是得到  he\r\n                       
                    buf.flip(); //此时 buf.position=0,buf.limit()=4            
                   
                    buf.limit(buf.limit() - matchCount);  //4-2 = 2
                    try{
                        // 输出解码内容 ,即 he
                        out.write(buf.getString(ctx.getDecoder()));
                    }
                    finally {
                        buf.clear(); // 释放缓存空间
                    }       
               
                    matchCount = 0;
                   
                }
        }else { //h字符,e字符时,均会进入 此else逻辑判断中   

            //把in中未解码内容放回buf中
            //下面会在 输入的字符不是 \r\n时会需要保存使用
            in.position(oldPos);
            ctx.append(in);
            ctx.setMatchCount(matchCount);
        }
    }           
}
 
Example 13
Source File: TextLineDecoder.java    From neoscada with Eclipse Public License 1.0 4 votes vote down vote up
/**
 * Decode a line using the delimiter defined by the caller
 */
private void decodeNormal(Context ctx, IoSession session, IoBuffer in, ProtocolDecoderOutput out)
        throws CharacterCodingException, ProtocolDecoderException {
    int matchCount = ctx.getMatchCount();

    // Try to find a match
    int oldPos = in.position();
    int oldLimit = in.limit();

    while (in.hasRemaining()) {
        byte b = in.get();

        if (delimBuf.get(matchCount) == b) {
            matchCount++;

            if (matchCount == delimBuf.limit()) {
                // Found a match.
                int pos = in.position();
                in.limit(pos);
                in.position(oldPos);

                ctx.append(in);

                in.limit(oldLimit);
                in.position(pos);

                if (ctx.getOverflowPosition() == 0) {
                    IoBuffer buf = ctx.getBuffer();
                    buf.flip();
                    buf.limit(buf.limit() - matchCount);

                    try {
                        writeText(session, buf.getString(ctx.getDecoder()), out);
                    } finally {
                        buf.clear();
                    }
                } else {
                    int overflowPosition = ctx.getOverflowPosition();
                    ctx.reset();
                    throw new RecoverableProtocolDecoderException("Line is too long: " + overflowPosition);
                }

                oldPos = pos;
                matchCount = 0;
            }
        } else {
            // fix for DIRMINA-506 & DIRMINA-536
            in.position(Math.max(0, in.position() - matchCount));
            matchCount = 0;
        }
    }

    // Put remainder to buf.
    in.position(oldPos);
    ctx.append(in);

    ctx.setMatchCount(matchCount);
}
 
Example 14
Source File: TextLineDecoder.java    From neoscada with Eclipse Public License 1.0 4 votes vote down vote up
/**
 * Decode a line using the default delimiter on the current system
 */
private void decodeAuto(Context ctx, IoSession session, IoBuffer in, ProtocolDecoderOutput out)
        throws CharacterCodingException, ProtocolDecoderException {
    int matchCount = ctx.getMatchCount();

    // Try to find a match
    int oldPos = in.position();
    int oldLimit = in.limit();

    while (in.hasRemaining()) {
        byte b = in.get();
        boolean matched = false;

        switch (b) {
        case '\r':
            // Might be Mac, but we don't auto-detect Mac EOL
            // to avoid confusion.
            matchCount++;
            break;

        case '\n':
            // UNIX
            matchCount++;
            matched = true;
            break;

        default:
            matchCount = 0;
        }

        if (matched) {
            // Found a match.
            int pos = in.position();
            in.limit(pos);
            in.position(oldPos);

            ctx.append(in);

            in.limit(oldLimit);
            in.position(pos);

            if (ctx.getOverflowPosition() == 0) {
                IoBuffer buf = ctx.getBuffer();
                buf.flip();
                buf.limit(buf.limit() - matchCount);

                try {
                    byte[] data = new byte[buf.limit()];
                    buf.get(data);
                    CharsetDecoder decoder = ctx.getDecoder();

                    CharBuffer buffer = decoder.decode(ByteBuffer.wrap(data));
                    String str = new String(buffer.array());
                    writeText(session, str, out);
                } finally {
                    buf.clear();
                }
            } else {
                int overflowPosition = ctx.getOverflowPosition();
                ctx.reset();
                throw new RecoverableProtocolDecoderException("Line is too long: " + overflowPosition);
            }

            oldPos = pos;
            matchCount = 0;
        }
    }

    // Put remainder to buf.
    in.position(oldPos);
    ctx.append(in);

    ctx.setMatchCount(matchCount);
}
 
Example 15
Source File: MinaProtocolDecoder.java    From jforgame with Apache License 2.0 4 votes vote down vote up
@Override
public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
	// 必须保证每一个数据包的字节缓存都和session绑定在一起,不然就读取不了上一次剩余的数据了
	CodecContext context = SessionManager.INSTANCE.getSessionAttr(session, MinaSessionProperties.CODEC_CONTEXT,
			CodecContext.class);
	if (context == null) {
		context = new CodecContext();
		session.setAttribute(MinaSessionProperties.CODEC_CONTEXT, context);
	}

	IoBuffer ioBuffer = context.getBuffer();
	ioBuffer.put(in);

	IMessageDecoder msgDecoder = SerializerHelper.getInstance().getDecoder();

	// 在循环里迭代,以处理数据粘包
	for (;;) {
		ioBuffer.flip();
		// 消息元信息常量3表示消息body前面的两个字段,一个short表示module,一个byte表示cmd,
		final int metaSize = 3;
		if (ioBuffer.remaining() < metaSize) {
			ioBuffer.compact();
			return;
		}
		// ----------------消息协议格式-------------------------
		// packetLength | moduleId | cmd  | body
		// int            short      byte byte[]
		int length = ioBuffer.getInt();
		// int packLen = length + metaSize;
		// 大于消息body长度,说明至少有一条完整的message消息
		if (ioBuffer.remaining() >= length) {
			short moduleId = ioBuffer.getShort();
			byte cmd = ioBuffer.get();
			int msgbodyLen = length - metaSize;
			byte[] body = new byte[msgbodyLen];
			ioBuffer.get(body);
			Message msg = msgDecoder.readMessage(moduleId, cmd, body);

			if (moduleId > 0) {
				out.write(msg);
			} else { // 属于组合包
				CombineMessage combineMessage = (CombineMessage) msg;
				List<Packet> packets = combineMessage.getPackets();
				for (Packet packet : packets) {
					// 依次拆包反序列化为具体的Message
					out.write(Packet.asMessage(packet));
				}
			}
			if (ioBuffer.remaining() == 0) {
				ioBuffer.clear();
				break;
			}
			ioBuffer.compact();
		} else {
			// 数据包不完整,继续等待数据到达
			ioBuffer.rewind();
			ioBuffer.compact();
			break;
		}
	}
}
 
Example 16
Source File: ConnectorTest.java    From game-server with MIT License 4 votes vote down vote up
private void testConnector0(IoSession session) throws InterruptedException {
    EchoConnectorHandler handler = (EchoConnectorHandler) session
            .getHandler();
    IoBuffer readBuf = handler.readBuf;
    readBuf.clear();
    WriteFuture writeFuture = null;
    
    for (int i = 0; i < COUNT; i++) {
        IoBuffer buf = IoBuffer.allocate(DATA_SIZE);
        buf.limit(DATA_SIZE);
        fillWriteBuffer(buf, i);
        buf.flip();

        writeFuture = session.write(buf);

        if (session.getService().getTransportMetadata().isConnectionless()) {
            // This will align message arrival order in connectionless transport types
            waitForResponse(handler, (i + 1) * DATA_SIZE);
        }
    }

    writeFuture.awaitUninterruptibly();

    waitForResponse(handler, DATA_SIZE * COUNT);

    // Assert data
    //// Please note that BufferOverflowException can be thrown
    //// in SocketIoProcessor if there was a read timeout because
    //// we share readBuf.
    readBuf.flip();
    LOGGER.info("readBuf: " + readBuf);
    assertEquals(DATA_SIZE * COUNT, readBuf.remaining());
    IoBuffer expectedBuf = IoBuffer.allocate(DATA_SIZE * COUNT);
    
    for (int i = 0; i < COUNT; i++) {
        expectedBuf.limit((i + 1) * DATA_SIZE);
        fillWriteBuffer(expectedBuf, i);
    }
    
    expectedBuf.position(0);

    isEquals(expectedBuf, readBuf);
}
 
Example 17
Source File: ClientProtocolDecoder.java    From game-server with MIT License 4 votes vote down vote up
/** {@inheritDoc} */
@Override
protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
	int readAbleLen = in.remaining();
	if (readAbleLen < 2) {
		return false;
	}
	in.mark(); // 标记阅读位置
	byte[] bs = new byte[2];
	in.get(bs, 0, 2);
	short packageLength = IntUtil.bigEndianByteToShort(bs, 0, 2);
	if (packageLength < 1 || packageLength > maxReadSize) {
		LOGGER.warn("消息包长度为:{}", packageLength);
		in.clear();
		session.closeNow();
		return false;
	}

	if (in.remaining() < packageLength) { // 消息长度不够,重置位置
		in.reset();
		return false;
	}
	// 消息Id(4字节)+protobufLength(4字节)+消息体+时间戳(8字节)+签名数据长度(4字节)+签名数据+截取签名长度(4字节)
	bs = new byte[packageLength];
	in.get(bs);
	int protobufLength = IntUtil.bigEndianByteToInt(bs, 4, 4);
	if (packageLength > protobufLength + 8) {
		LOGGER.debug("消息签名验证");
		if (checkMsgSign(bs, protobufLength)) {
			byte[] datas = new byte[8 + protobufLength];
			System.arraycopy(bs, 0, datas, 0, datas.length);
			out.write(bs);
		} else {
			session.closeNow();
			return false;
		}
	} else {
		out.write(bs);
	}

	// decodeBytes(packageLength, in, out);

	if (!checkMsgFrequency(session)) {
		return false;
	}

	return true;
}