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

The following examples show how to use org.apache.mina.core.buffer.IoBuffer#getShort() . 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: ArduinoCodec.java    From neoscada with Eclipse Public License 1.0 6 votes vote down vote up
@Override
public void decode ( final IoSession session, final IoBuffer data, final ProtocolDecoderOutput output ) throws Exception
{
    final short magic = data.getShort ();
    final byte version = data.get ();
    final int sequence = data.getInt ();
    final byte commandCode = data.get ();

    if ( magic != 1202 )
    {
        throw new ProtocolCodecException ( String.format ( "Magic code should be 1202 but is %s", magic ) );
    }
    if ( version != 1 )
    {
        throw new ProtocolCodecException ( String.format ( "Version should be %s but is %s", 1, version ) );
    }

    decodeMessage ( sequence, commandCode, data, output );
}
 
Example 2
Source File: CommandDecoder.java    From mina with Apache License 2.0 6 votes vote down vote up
@Override
protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
    if (in.prefixedDataAvailable(2)) {
        short length = in.getShort();//获取包长

        byte[] bytes = new byte[length];
        in.get(bytes);
        byte[] msgidBytes = new byte[Constants.COMMAND_LENGTH];
        System.arraycopy(bytes, 0, msgidBytes, 0, Constants.COMMAND_LENGTH);
        int msgid = NumberUtils.bytesToInt(msgidBytes);
        if (msgid != 0) {
            //通过工厂方法生成指定消息类型的指令对象
            BaseCommand command = CommandFactory.createCommand(msgid);

            byte[] cmdBodyBytes = new byte[length - Constants.COMMAND_LENGTH];
            System.arraycopy(bytes, Constants.COMMAND_LENGTH, cmdBodyBytes, 0, length - Constants.COMMAND_LENGTH);
            command.bodyFromBytes(cmdBodyBytes);
            out.write(command);
            return true;
        }
    }

    return false;
}
 
Example 3
Source File: CommandDecoder.java    From mina with Apache License 2.0 6 votes vote down vote up
@Override
protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
    if (in.prefixedDataAvailable(2)) {
        short length = in.getShort();//获取包长

        byte[] bytes = new byte[length];
        in.get(bytes);
        byte[] msgidBytes = new byte[Constants.COMMAND_LENGTH];
        System.arraycopy(bytes, 0, msgidBytes, 0, Constants.COMMAND_LENGTH);
        int msgid = NumberUtils.bytesToInt(msgidBytes);
        if (msgid != 0) {
            //通过工厂方法生成指定消息类型的指令对象
            BaseCommand command = CommandFactory.createCommand(msgid);

            byte[] cmdBodyBytes = new byte[length - Constants.COMMAND_LENGTH];
            System.arraycopy(bytes, Constants.COMMAND_LENGTH, cmdBodyBytes, 0, length - Constants.COMMAND_LENGTH);
            command.bodyFromBytes(cmdBodyBytes);
            out.write(command);
            return true;
        }
    }

    return false;
}
 
Example 4
Source File: ShortFieldTypeHandler.java    From CXTouch with GNU General Public License v3.0 5 votes vote down vote up
@Override
public Short decode(IoBuffer inBuffer) {
    if (inBuffer.remaining() < 2) {
        return null;
    } else {
        return inBuffer.getShort();
    }
}
 
Example 5
Source File: ScreenVideo2.java    From red5-io with Apache License 2.0 5 votes vote down vote up
/** {@inheritDoc} */
@Override
public boolean addData(IoBuffer data) {
    if (!this.canHandleData(data)) {
        return false;
    }
    data.get();
    this.updateSize(data);
    int idx = 0;
    int pos = 0;
    byte[] tmpData = new byte[blockDataSize];
    // reserved (6) has iframeimage (1) has palleteinfo (1)
    specInfo1 = data.get();
    int countBlocks = blockCount;
    while (data.remaining() > 0 && countBlocks > 0) {
        short size = data.getShort();
        countBlocks--;
        if (size == 0) {
            // Block has not been modified
            idx += 1;
            pos += blockDataSize;
            continue;
        } else {
            // imageformat
            specInfo2 = data.get();
            size--;
        }
        // Store new block data
        blockSize[idx] = size;
        data.get(tmpData, 0, size);
        System.arraycopy(tmpData, 0, blockData, pos, size);
        idx += 1;
        pos += blockDataSize;
    }
    data.rewind();
    return true;
}
 
Example 6
Source File: ScreenVideo2.java    From red5-io with Apache License 2.0 5 votes vote down vote up
/**
 * Update total block size
 * 
 * @param data
 *            Byte buffer
 */
private void updateSize(IoBuffer data) {
    widthInfo = data.getShort();
    heightInfo = data.getShort();
    // extract width and height of the frame
    width = widthInfo & 0xfff;
    height = heightInfo & 0xfff;
    // calculate size of blocks
    blockWidth = (widthInfo & 0xf000 >> 12) + 1;
    blockWidth <<= 4;
    blockHeight = (heightInfo & 0xf000 >> 12) + 1;
    blockHeight <<= 4;
    int xblocks = width / blockWidth;
    if ((width % blockWidth) != 0) {
        // partial block
        xblocks += 1;
    }
    int yblocks = height / blockHeight;
    if ((height % blockHeight) != 0) {
        // partial block
        yblocks += 1;
    }
    blockCount = xblocks * yblocks;
    int compressedSize = maxCompressedSize(blockWidth * blockHeight * 3);
    int totalBlockSize = compressedSize * blockCount;
    if (this.totalBlockDataSize != totalBlockSize) {
        log.info("Allocating memory for {} compressed blocks.", blockCount);
        blockDataSize = compressedSize;
        totalBlockDataSize = totalBlockSize;
        blockData = new byte[compressedSize * blockCount];
        blockSize = new int[compressedSize * blockCount];
        // Reset the sizes to zero
        for (int idx = 0; idx < blockCount; idx++) {
            blockSize[idx] = 0;
        }
    }
}
 
Example 7
Source File: RTMPProtocolDecoder.java    From red5-server-common with Apache License 2.0 5 votes vote down vote up
/**
 * Decodes ping event.
 * 
 * @param in
 *            IoBuffer
 * @return Ping event
 */
public Ping decodePing(IoBuffer in) {
    Ping ping = null;
    if (log.isTraceEnabled()) {
        // gets the raw data as hex without changing the data or pointer
        String hexDump = in.getHexDump();
        log.trace("Ping dump: {}", hexDump);
    }
    // control type
    short type = in.getShort();
    switch (type) {
        case Ping.CLIENT_BUFFER:
            ping = new SetBuffer(in.getInt(), in.getInt());
            break;
        case Ping.PING_SWF_VERIFY:
            // only contains the type (2 bytes)
            ping = new Ping(type);
            break;
        case Ping.PONG_SWF_VERIFY:
            byte[] bytes = new byte[42];
            in.get(bytes);
            ping = new SWFResponse(bytes);
            break;
        default:
            //STREAM_BEGIN, STREAM_PLAYBUFFER_CLEAR, STREAM_DRY, RECORDED_STREAM
            //PING_CLIENT, PONG_SERVER
            //BUFFER_EMPTY, BUFFER_FULL
            ping = new Ping(type, in.getInt());
            break;
    }
    return ping;
}
 
Example 8
Source File: ProtobufDecoder.java    From gameserver with Apache License 2.0 5 votes vote down vote up
/**
 * Decode the XinqiMessage from byte array.
 * @param in
 * @return
 * @throws InvalidProtocolBufferException 
 */
public static final XinqiMessage decodeXinqiMessage(IoBuffer in) 
		throws InvalidProtocolBufferException {
	
	// Make sure all the header bytes are ready.
	if ( !in.prefixedDataAvailable(HEADER_LENGTH, MAX_LENGTH) ) {
    return null;
	}
	
	int length = in.getInt() - 6;
	int type = in.getShort();
	XinqiMessage message = new XinqiMessage();
	//XinqiMessage
	message.type = type;
	message.index = in.getInt();
	byte[] array = new byte[length];
	in.get(array);
	if ( logger.isDebugEnabled() ) {
		logger.debug("length:"+length+", type:"+message.type+", index:"+message.index);
	}
	
	MessageLite request = IdToMessage.idToMessage(message.type);
	
	if ( request == null ) {
		logger.warn("No id found for message type. return empty message. ");
		return message;
	}
	
	request = request.newBuilderForType().mergeFrom(array).build();

	message.payload = request;
	
	return message;
}
 
Example 9
Source File: DSRemotingClient.java    From red5-client with Apache License 2.0 4 votes vote down vote up
/**
 * Process any headers sent in the response.
 * 
 * @param in
 *            Byte buffer with response data
 */
@Override
protected void processHeaders(IoBuffer in) {
    log.debug("RemotingClient processHeaders - buffer limit: {}", (in != null ? in.limit() : 0));
    int version = in.getUnsignedShort(); // skip
    log.debug("Version: {}", version);
    // the version by now, AMF3 is not yet implemented
    int count = in.getUnsignedShort();
    log.debug("Count: {}", count);
    Input input = new Input(in);
    for (int i = 0; i < count; i++) {
        String name = input.getString();
        log.debug("Name: {}", name);
        boolean required = (in.get() == 0x01);
        log.debug("Required: {}", required);
        Object value = null;
        int len = in.getInt();
        log.debug("Length: {}", len);
        // look for junk bytes ff,ff,ff,ff
        if (len == -1) {
            in.get(); //02
            len = in.getShort();
            log.debug("Corrected length: {}", len);
            value = input.readString(len);
        } else {
            value = Deserializer.deserialize(input, Object.class);
        }
        log.debug("Value: {}", value);
        // XXX: this is pretty much untested!!!
        if (RemotingHeader.APPEND_TO_GATEWAY_URL.equals(name)) {
            // Append string to gateway url
            appendToUrl = (String) value;
        } else if (RemotingHeader.REPLACE_GATEWAY_URL.equals(name)) {
            // Replace complete gateway url
            url = (String) value;
            // XXX: reset the <appendToUrl< here?
        } else if (RemotingHeader.PERSISTENT_HEADER.equals(name)) {
            // Send a new header with each following request
            if (value instanceof Map<?, ?>) {
                @SuppressWarnings("unchecked")
                Map<String, Object> valueMap = (Map<String, Object>) value;
                RemotingHeader header = new RemotingHeader((String) valueMap.get("name"), (Boolean) valueMap.get("mustUnderstand"), valueMap.get("data"));
                headers.put(header.getName(), header);
            } else {
                log.error("Expected Map but received {}", value);
            }
        } else {
            log.warn("Unsupported remoting header \"{}\" received with value \"{}\"", name, value);
        }
    }
}
 
Example 10
Source File: MessageUtil.java    From CXTouch with GNU General Public License v3.0 4 votes vote down vote up
public static String readString(IoBuffer buffer, LengthType lenType, CharsetDecoder decoder) throws NoArrayException {
    int length;
    int remain = buffer.remaining();
    buffer.mark();
    if (lenType == LengthType.INT) {
        if (remain < 4) {
            buffer.reset();
            throw new NoArrayException();
        }
        length = buffer.getInt();
    } else if(lenType == LengthType.SHORT) {
        if (remain < 2) {
            buffer.reset();
            throw new NoArrayException();
        }
        length = buffer.getShort();
    } else if (lenType == LengthType.BYTE) {
        if (remain < 1) {
            buffer.reset();
            throw new NoArrayException();
        }
        length = buffer.get();
    } else {
        buffer.reset();
        throw new IllegalArgumentException("Illegal type:" + lenType);
    }

    if (length < 0) {
        return null;
    } if (length == 0) {
        return "";
    } else {
        if (buffer.remaining() < length) {
            buffer.reset();
            throw new NoArrayException();
        }
        try {
            return buffer.getString(length, decoder);
        } catch (CharacterCodingException e) {
            throw new RuntimeException("Reading string failed:" + e.getMessage(), e);
        }
    }
}
 
Example 11
Source File: DSRemotingClient.java    From red5-client with Apache License 2.0 4 votes vote down vote up
/**
 * Decode response received from remoting server.
 * 
 * @param data
 *            Result data to decode
 * @return Object deserialized from byte buffer data
 */
private Object decodeResult(IoBuffer data) {
    log.debug("decodeResult - data limit: {}", (data != null ? data.limit() : 0));
    processHeaders(data);

    Input input = new Input(data);
    String target = null;

    byte b = data.get();
    //look for SOH
    if (b == 0) {
        log.debug("NUL: {}", b); //0
        log.debug("SOH: {}", data.get()); //1
    } else if (b == 1) {
        log.debug("SOH: {}", b); //1			
    }

    int targetUriLength = data.getShort();
    log.debug("targetUri length: {}", targetUriLength);
    target = input.readString(targetUriLength);

    log.debug("NUL: {}", data.get()); //0

    //should be junk bytes ff, ff, ff, ff
    int count = data.getInt();
    if (count == -1) {
        log.debug("DC1: {}", data.get()); //17
        count = 1;
    } else {
        data.position(data.position() - 4);
        count = data.getShort();
    }

    if (count != 1) {
        throw new RuntimeException("Expected exactly one result but got " + count);
    }

    String[] targetParts = target.split("[/]");
    if (targetParts.length > 1) {
        log.debug("Result sequence number: {}", targetParts[1]);
        target = targetParts[2];
    } else {
        target = target.substring(1);
    }
    log.debug("Target: {}", target);
    if ("onResult".equals(target)) {
        //read return value
        return input.readObject();
    } else if ("onStatus".equals(target)) {
        //read return value
        return input.readObject();
    }
    //read return value
    return Deserializer.deserialize(input, Object.class);
}
 
Example 12
Source File: ScreenVideo.java    From red5-io with Apache License 2.0 4 votes vote down vote up
/**
 * Update total block size
 * 
 * @param data
 *            Byte buffer
 */
private void updateSize(IoBuffer data) {
    this.widthInfo = data.getShort();
    this.heightInfo = data.getShort();
    // extract width and height of the frame
    this.width = this.widthInfo & 0xfff;
    this.height = this.heightInfo & 0xfff;
    // calculate size of blocks
    this.blockWidth = this.widthInfo & 0xf000;
    this.blockWidth = (this.blockWidth >> 12) + 1;
    this.blockWidth <<= 4;

    this.blockHeight = this.heightInfo & 0xf000;
    this.blockHeight = (this.blockHeight >> 12) + 1;
    this.blockHeight <<= 4;

    int xblocks = this.width / this.blockWidth;
    if ((this.width % this.blockWidth) != 0) {
        // partial block
        xblocks += 1;
    }

    int yblocks = this.height / this.blockHeight;
    if ((this.height % this.blockHeight) != 0) {
        // partial block
        yblocks += 1;
    }

    this.blockCount = xblocks * yblocks;

    int blockSize = maxCompressedSize(this.blockWidth * this.blockHeight * 3);
    int totalBlockSize = blockSize * this.blockCount;
    if (this.totalBlockDataSize != totalBlockSize) {
        log.info("Allocating memory for {} compressed blocks.", this.blockCount);
        this.blockDataSize = blockSize;
        this.totalBlockDataSize = totalBlockSize;
        this.blockData = new byte[blockSize * this.blockCount];
        this.blockSize = new int[blockSize * this.blockCount];
        // Reset the sizes to zero
        for (int idx = 0; idx < this.blockCount; idx++) {
            this.blockSize[idx] = 0;
        }
    }
}
 
Example 13
Source File: ProtobufDecoder.java    From gameserver with Apache License 2.0 4 votes vote down vote up
/**
	 * Decode the XinqiMessage from byte array.
	 * @param in
	 * @return
	 * @throws InvalidProtocolBufferException 
	 */
	public static final XinqiMessage decodeXinqiMessage(IoBuffer in) 
			throws InvalidProtocolBufferException {
		
		// Make sure all the header bytes are ready.
		if ( !in.prefixedDataAvailable(HEADER_LENGTH, MAX_LENGTH) ) {
	    return null;
		}
		
		int length = in.getInt() - 6;
		int type = in.getShort();
		XinqiMessage message = new XinqiMessage();
		//XinqiMessage
		message.type = type;
		message.index = in.getInt();
		byte[] array = new byte[length];
		in.get(array);
		if ( log.isDebugEnabled() ) {
			log.debug("length:"+length+", type:"+message.type+", index:"+message.index);
		}
		
		MessageLite request = IdToMessage.idToMessage(message.type);
		
		if ( request == null ) {
			if ( log.isWarnEnabled() ) {
				log.warn("No id found for message type. return empty message. ");
			}
			//Note: return an empty message rather than null so that
			//next messages can be parsed.
			return message;
		}
		
		request = request.newBuilderForType().mergeFrom(array).build();

//			in.skip(length);
		if ( log.isDebugEnabled() ) {
			log.debug("DecodedMessage:"+request.getClass().getName()+"[\n"+request+"]");
		}
		message.payload = request;
		if ( log.isDebugEnabled() ) {
			log.debug("XinqiMessage:[\n"+message.toString()+"]");
		}
		
		return message;
	}
 
Example 14
Source File: SessionMessageRawDecoder.java    From gameserver with Apache License 2.0 4 votes vote down vote up
/**
 * Decode the message.
 */
@Override
protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
	SessionRawMessage sessionMessage = (SessionRawMessage) session.getAttribute(DECODER_STATE_KEY);
	DecoderStage stage = (DecoderStage) session.getAttribute(DECODER_STAGE_KEY);
	if ( sessionMessage == null ) {
		sessionMessage = new SessionRawMessage();
		session.setAttribute(DECODER_STATE_KEY, sessionMessage);
	}
	if ( stage == null ) {
		stage = DecoderStage.DECODE_SESSION_KEY;
		session.setAttribute(DECODER_STAGE_KEY, stage);
	}
	
	switch ( stage ) {
		case DECODE_SESSION_KEY:
			// Make sure the sessionkey in the header bytes are ready.
			if ( !in.prefixedDataAvailable(SESSION_LENGTH, MAX_LENGTH) ) {
		    return false;
			}
			int sessionKeyLength = in.getShort() & 0xFFFF;
			byte[] sessionRawBytes = new byte[sessionKeyLength];
			in.get(sessionRawBytes);
			SessionKey sessionKey = SessionKey.createSessionKey(sessionRawBytes);
			sessionMessage.setSessionkey(sessionKey);
			session.setAttribute(DECODER_STAGE_KEY, DecoderStage.DECODE_RAW);
			
		case DECODE_RAW:
			// Make sure the xinqimessage in the header bytes are ready.
			if ( !in.prefixedDataAvailable(RAW_LENGTH, RAW_MAX_LENGTH) ) {
		    return false;
			}
			int rawLength = in.getInt();
			if ( log.isDebugEnabled() ) {
				log.debug("RawMessage length:"+rawLength);
			}
			byte[] rawMessage = new byte[rawLength];
			in.get(rawMessage);
			
			sessionMessage.setRawMessage(rawMessage);
			out.write(sessionMessage);
			
			session.setAttribute(DECODER_STATE_KEY, null);
			session.setAttribute(DECODER_STAGE_KEY, null);
			return true;
		default:
			break;
	}
	
	return false;
}
 
Example 15
Source File: SessionMessageDecoder.java    From gameserver with Apache License 2.0 4 votes vote down vote up
/**
 * Decode the message.
 */
@Override
protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
	SessionMessage sessionMessage = (SessionMessage) session.getAttribute(DECODER_STATE_KEY);
	if ( sessionMessage == null ) {
		sessionMessage = new SessionMessage();
		session.setAttribute(DECODER_STATE_KEY, sessionMessage);
	}
	
	// Make sure the sessionkey in the header bytes are ready.
	if ( !in.prefixedDataAvailable(HEADER_LENGTH, MAX_LENGTH) ) {
    return false;
	}
	int sessionKeyLength = in.getShort();
	byte[] sessionRawBytes = new byte[sessionKeyLength];
	in.get(sessionRawBytes);
	SessionKey sessionKey = SessionKey.createSessionKey(sessionRawBytes);
	sessionMessage.setSessionkey(sessionKey);
	
	// Make sure the xinqimessage in the header bytes are ready.
	if ( !in.prefixedDataAvailable(HEADER_LENGTH, MAX_LENGTH) ) {
    return false;
	}
	
	int xinqiMessageLength = in.getShort()-6;
	XinqiMessage message = new XinqiMessage();
	
	message.type = in.getShort();
	message.index = in.getInt();
	if ( log.isDebugEnabled() ) {
		log.debug("XinqiMessage length:"+xinqiMessageLength+", type:"+message.type+", index:"+message.index);
	}
	
	MessageLite request = IdToMessage.idToMessage(message.type);
	if ( request == null ) {
		if ( log.isWarnEnabled() ) {
			log.warn("No id found for message type. return null. ");
		}
		return false;
	}
	
	request = request.newBuilderForType().mergeFrom(in.slice().array(), sessionKeyLength + 10 , xinqiMessageLength).build();

	in.skip(xinqiMessageLength);
	if ( log.isDebugEnabled() ) {
		log.debug("Message:"+request.getClass().getName()+"["+request+"]");
	}
	message.payload = request;
	if ( log.isDebugEnabled() ) {
		log.debug("Response["+message.toString()+"]");
	}
	
	sessionMessage.setMessage(message);
	
	out.write(sessionMessage);
	return true;
}
 
Example 16
Source File: Int16Accessor.java    From neoscada with Eclipse Public License 1.0 4 votes vote down vote up
@Override
public Short get ( final IoBuffer data, final int index )
{
    return data.getShort ( index );
}
 
Example 17
Source File: WebMessageDecoder.java    From cim with Apache License 2.0 4 votes vote down vote up
@Override
public void decode(IoSession iosession, IoBuffer in, ProtocolDecoderOutput out) throws InvalidProtocolBufferException{
	
	/*
	 * 判断是否是握手请求
	 */

	if(isHandShakeRequest(iosession,in)) {
		handleHandshake(iosession,in, out);
		return;
	}

	
	in.mark();
	
	/*
	 * 接下来判断fin标志位是否是1 如果是0 则等待消息接收完成
	 */
	byte tag = in.get();
	int frameFin = tag  > 0 ?  0 : 1;
	if(frameFin == 0) {
		in.reset();
		return;
	}
	
	/*
	 * 获取帧类型,因为使用了protobuf,所以只支持二进制帧 OPCODE_BINARY,以及客户端关闭连接帧通知 OPCODE_CLOSE
	 */
	int frameCode = tag & TAG_MASK;
	
	if(OPCODE_BINARY == frameCode) {
		
		byte head = in.get();
		byte dataLength = (byte) (head & PAYLOADLEN);
		int realLength;
		
		/*
		 *Payload len,7位或者7+16位或者7+64位,表示数据帧中数据大小,这里有好几种情况。
		 *如果值为0-125,那么该值就是payload data的真实长度。
		 *如果值为126,那么该7位后面紧跟着的2个字节就是payload data的真实长度。
		 *如果值为127,那么该7位后面紧跟着的8个字节就是payload data的真实长度。
		 */
		if (dataLength == HAS_EXTEND_DATA) {
			realLength = in.getShort();
		} else if (dataLength == HAS_EXTEND_DATA_CONTINUE) {
			realLength = (int) in.getLong();
		}else {
			realLength = dataLength;
		}

		boolean masked = (head >> 7 & MASK) == 1;
		if (masked) {
			byte[] mask = new byte[4];
			in.get(mask);
			
			byte[] data = new byte[realLength];
			in.get(data);
			for (int i = 0; i < realLength; i++) {
				data[i] = (byte) (data[i] ^ mask[i % 4]);
			}
			
			handleMessage(data,out);
		}
		
	}else if(OPCODE_CLOSE == frameCode) {
       	handleClose(iosession,in);
	}else {
		in.get(new byte[in.remaining()]);
	}

}
 
Example 18
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 19
Source File: WebSocketDecoder.java    From game-server with MIT License 4 votes vote down vote up
private static IoBuffer buildWSDataBuffer(IoBuffer in, IoSession session) {

        IoBuffer resultBuffer = null;
        do{
            byte frameInfo = in.get();            
            byte opCode = (byte) (frameInfo & 0x0f);
            if (opCode == 8) {
                // opCode 8 means close. See RFC 6455 Section 5.2
                // return what ever is parsed till now.
                session.close(true);
                return resultBuffer;
            }        
            int frameLen = (in.get() & (byte) 0x7F);
            if(frameLen == 126){
                frameLen = in.getShort();
            }
            
            // Validate if we have enough data in the buffer to completely
            // parse the WebSocket DataFrame. If not return null.
            if(frameLen+4 > in.remaining()){                
                return null;
            }
            byte mask[] = new byte[4];
            for (int i = 0; i < 4; i++) {
                mask[i] = in.get();
            }

            /*  now un-mask frameLen bytes as per Section 5.3 RFC 6455
                Octet i of the transformed data ("transformed-octet-i") is the XOR of
                octet i of the original data ("original-octet-i") with octet at index
                i modulo 4 of the masking key ("masking-key-octet-j"):

                j                   = i MOD 4
                transformed-octet-i = original-octet-i XOR masking-key-octet-j
            * 
            */
             
            byte[] unMaskedPayLoad = new byte[frameLen];
            for (int i = 0; i < frameLen; i++) {
                byte maskedByte = in.get();
                unMaskedPayLoad[i] = (byte) (maskedByte ^ mask[i % 4]);
            }
            
            if(resultBuffer == null){
                resultBuffer = IoBuffer.wrap(unMaskedPayLoad);
                resultBuffer.position(resultBuffer.limit());
                resultBuffer.setAutoExpand(true);
            }
            else{
                resultBuffer.put(unMaskedPayLoad);
            }
        }
        while(in.hasRemaining());
        
        resultBuffer.flip();
        return resultBuffer;

    }
 
Example 20
Source File: NTGCodec.java    From sailfish-core with Apache License 2.0 4 votes vote down vote up
public boolean decodable(IoSession session, IoBuffer inputBuffer)
{
	inputBuffer.order(ByteOrder.LITTLE_ENDIAN);

       boolean isDecodable = false;

       if(inputBuffer.remaining() < MINIMAL_CAPACITY) {
		return false;
	}

	inputBuffer.order(ByteOrder.LITTLE_ENDIAN);
	inputBuffer.mark();
	byte messageStartByte  = inputBuffer.get();

	// Implementation of SEVRER_START_OF_MESSAGE_INDICATOR need to be qualified.
       if(messageStartByte != CLIENT_START_OF_MESSAGE_INDICATOR
	/* && SEVRER_START_OF_MESSAGE_INDICATOR != messageStartByte */ )
	{
           inputBuffer.reset();

           logger.error("Unexpected start of message: {} (expected: {})", messageStartByte, CLIENT_START_OF_MESSAGE_INDICATOR);
           logger.error("Buffer hexdump:{}{}", System.lineSeparator(), HexDumper.getHexdump(inputBuffer, inputBuffer.remaining()));

           throw new EPSCommonException("Unexpected start of message: " + messageStartByte);
	}

       short messageLength = inputBuffer.getShort();

	if( messageLength < 0 )
	{
		throw new EPSCommonException( "Message length cannot be negative." );
	}

	if( inputBuffer.remaining() >= messageLength )
	{
		isDecodable = true;
	}

       byte messageType = inputBuffer.get();
	inputBuffer.reset();

	if(logger.isDebugEnabled())
	{
		messageLength += messageLength == 0 ? 0 : 3;
		logger.debug("decodable() result [{}].", isDecodable);
		logger.debug("decodable() message length [{}], message type [{}]", messageLength, messageType);
           //logger.debug( String.format(" decodable() as hex    [%s]", NTGUtility.getHexdump( inputBuffer, messageLength )));
		inputBuffer.reset();
		logger.debug(MINAUtil.getHexdumpAdv(inputBuffer, messageLength));
		inputBuffer.reset();
	}
	return isDecodable;
}