mina 粘包解决方案之一

public class CharsetDecoder implements ProtocolDecoder {
	public final  Logger log = Logger.getLogger(this.getClass());
	private final static Charset charset = Charset.forName("GBK");
	// 创建一个不会发生得重复的键值,用来存储一次tcp传输中没有解析完的字节
	private final static AttributeKey surplus = new AttributeKey(
			CharsetDecoder.class, "surplusBuffer");

	@Override
	public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out)
			throws Exception {
		// TODO Auto-generated method stub
		IoBuffer buff = null;
		//查看是否有上次没有用完的字节
		IoBuffer bytebuf = (IoBuffer) session.getAttribute(surplus);
		if (bytebuf == null || bytebuf.remaining() == 0) {
			buff = in;
		} else {
			buff = IoBuffer.allocate(bytebuf.remaining() + in.remaining());
			buff.setAutoExpand(true);
			buff.put(bytebuf);
			buff.put(in);
			buff.flip();
		}
		if(buff == null)
			return ;
			if (buff.remaining() >= 4) {				
				try {
					while (buff.hasRemaining()) {
						//标记一下读取的位置,如果不对,还要回来
						buff.mark();
						//读取字节的总长度
						int byteLength = buff.getInt();
						//判断一下剩下的字节是否满足读取的字节总长度
						if (byteLength <= buff.remaining()) {
							byte[] bys = new byte[byteLength];
							buff.get(bys);
							msg = new String(bys, charset);
							out.write(msg);
						} else {
						//如果读取字节不足,保到内存中,下次获取的时候加上。
							IoBuffer temp = IoBuffer.allocate(1024)
									.setAutoExpand(true);
							buff.reset();
							temp.put(buff);
							temp.flip();
							buff.clear();
							buff.flip();
							session.setAttribute(surplus, temp);
							break;
						}
					}
				} catch (OutOfMemoryError e) {
					buff.clear();
					buff.flip();
					session.removeAttribute(surplus);
					log.error("字节包异常:" + e.getMessage() + " :" + e.getCause());
					return;
				}

			}
			if (buff.hasRemaining()) {
				IoBuffer temp = IoBuffer.allocate(1024).setAutoExpand(true);
				temp.put(buff);
				temp.flip();
				buff.clear();
				session.setAttribute(surplus, temp);
			}
	}

	@Override
	public void dispose(IoSession arg0) throws Exception {
		// TODO Auto-generated method stub

	}

	@Override
	public void finishDecode(IoSession arg0, ProtocolDecoderOutput arg1)
			throws Exception {
		// TODO Auto-generated method stub

	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wgslucky

各位都是我的衣食父母

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值