【MinaFile】【十五】【2.0】多文件处理粘包之客户端接收端

在之前写的客户端接收端太过简单,现在根据服务器的接收端对客户端进行改造。让客户端的解码端也支持粘包

上代码

/**
 * 这是客户端对服务器发来的消息进行解码 消息封装在ByteReturnFileMessage实体中。 在解析完之后,调用客户端定义的Handle
 * handle中的方法messageReceived 在方法中进行处理。
 * 
 * @author king_fu
 * 
 */
public class ByteResultProtocalDecoder extends CumulativeProtocolDecoder {
	private static final Logger LOGGER = LoggerFactory
			.getLogger(ByteResultProtocalDecoder.class);
	private boolean readHead = false; // 是否读取头部信息
	private int NEEDDATA = 8; // 一个文件中需要的字节数
	private boolean isFirst = true; // 是否是第一次进来
	private boolean isFinish = false; // 是否已经处理所有数据(当前)
	private static IoBuffer newIoBuffer = IoBuffer.allocate(0).setAutoExpand(
			true);
	private ByteReturnFileMessage brf = new ByteReturnFileMessage();
	public ByteResultProtocalDecoder() {
	}

	@Override
	protected boolean doDecode(IoSession session, IoBuffer in,
			ProtocolDecoderOutput out) throws Exception {
		LOGGER.info("客户端对服务器返回的消息进行解码。解码开始");
		LOGGER.info("当前pos:" + in.position());
		LOGGER.info("总共limit:" + in.limit());
		LOGGER.info("所有remaining:" + in.remaining());

		try {
			/*
			 * if (in.prefixedDataAvailable(4, MAX_FILE_SIZE)) { } else {
			 * LOGGER.info("【客户端解码】不符合读取条件"); return false; }
			 */
			this.readFile(in);
			if (isFinish) {
				// 解析完成
				out.write(brf);
				dataInit();
			} else {
				return true;
			}
		} catch (Exception e) {
			LOGGER.info("【客户端解码】解码过程中发生错误", e);
			return false;
		}
		return true;
	}

	private void readFile(IoBuffer in)
			throws CharacterCodingException {
		/* CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder(); */
		byte[] byteValue = null;
		IoBuffer bufTmp = null;
		if (isFirst) {
			bufTmp = IoBuffer
					.allocate(newIoBuffer.remaining() + in.remaining())
					.setAutoExpand(true);
			bufTmp.order(newIoBuffer.order());
			if (!readHead && (newIoBuffer.remaining() + in.remaining()) >= 8) {
				// 未读取了头部信息
				brf.setSeq(in.getInt(in.position())); // 序号 (字节)

				brf.setReturnMassage(in.getInt(in.position() + 4)); // 返回消息长度(字节)
				 
				byteValue = new byte[NEEDDATA];

				readHead = true;
			}
			// 判断是否可以读取所有的数据
			if (NEEDDATA > newIoBuffer.remaining() + in.remaining()) {
				bufTmp.put(newIoBuffer);
				bufTmp.put(in);
			} else {
				bufTmp.put(newIoBuffer);
				in.get(byteValue);
				bufTmp.put(byteValue);
			}
			bufTmp.flip();
			newIoBuffer = bufTmp;
		}else {
			bufTmp = IoBuffer
					.allocate(newIoBuffer.remaining() + in.remaining())
					.setAutoExpand(true);
			bufTmp.order(newIoBuffer.order());

			if ( NEEDDATA > newIoBuffer.remaining()
					+ in.remaining()) {
				bufTmp.put(newIoBuffer);
				bufTmp.put(in);
			} else {

				byteValue = new byte[in.remaining()
						- (newIoBuffer.remaining() + in.remaining() - NEEDDATA)];
				bufTmp.put(newIoBuffer);
				in.get(byteValue);
				bufTmp.put(byteValue);
			}
			bufTmp.flip();
			newIoBuffer = bufTmp;
		}
		if (NEEDDATA > (newIoBuffer.remaining())) { // 2.14把limit改成remaining
			/*
			 * bfm.setFileStreamLength(bfm.getFileStreamLength() -
			 * (newIoBuffer.remaining())); // 2.14把limit改成remaining
			 */if (isFirst) { // 第一次
				isFirst = false;
				LOGGER.info("【客户端解码】未解析数据:" + newIoBuffer.remaining() + "字节");
			}
			isFinish = false; // 数据未读取完。
		} else {
			int remainingData = newIoBuffer.remaining(); // 总共多少
			LOGGER.info("【客户端解码】当前数据池中总共多少:" + remainingData + " 字节");
			if (remainingData >= NEEDDATA) {
				//byteValue = new byte[8];
			} else {
				// byteValue = new byte[remainingData];
				LOGGER.info("【客户端解码】数据长度未满足,【退出】");
				return  ; // 退出
			}
			brf.setSeq(newIoBuffer.getInt()); // 序号
			brf.setReturnMassage(newIoBuffer.getInt());  //字节数
			//newIoBuffer.get(byteValue);
			isFinish = true;
			LOGGER.info("【客户端解析】解析完成");
		}

		/*
		 * brf.setReturnMassage(in.getString(brf.getReturnMassageLength(),
		 * decoder)); // 服务器返回的消息。字符串
		 */LOGGER.info("【客户端解码】服务器返回内容:"
				+ (brf.getReturnMassage() == 1 ? "成功"
						: brf.getReturnMassage() == 2 ? "失败" : "其它"));
	}
	
	/**
	 * 处理完成,将所有数据初始化
	 */
	private void dataInit() {
		isFinish = false; // 是否已经处理所有数据
		isFirst = true; // 是否是第一次进来
		brf = new ByteReturnFileMessage(); // 保存对象
		readHead = false;
	}

}

最新代码已经更新在github中,欢迎fork。

项目名:MinaFile


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值