1. 程式人生 > >解決MINA中xml斷包粘包問題

解決MINA中xml斷包粘包問題

package com;

import java.nio.charset.Charset;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
import org.apache.mina.filter.codec.ProtocolEncoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@SuppressWarnings(value="all")
public class MsgRequestDecoder extends CumulativeProtocolDecoder {
	private static final Logger logger = (Logger) LoggerFactory.getLogger(ProtocolEncoder.class);
	private final Charset charset;

	public MsgRequestDecoder(Charset charset) {
		this.charset = charset;
	}

	@Override
	protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
		if (in.remaining() > 0) {
			int length = in.limit()-in.position();
			
//			System.out.println("tcp data length:"+length);
			in.mark();
			if(in.remaining()<4){
				in.reset();
				return false;
			}
			byte[] bytes = new byte[length];
			in.get(bytes);
			String aString=new String(bytes,"UTF-8");
			int start=aString.indexOf("<?xml");
			int end=aString.indexOf("</Message>");
			//等於-1下面程式碼報錯
			if(end==-1){
				in.reset();
				return false;
			}
			//防止start到end之間可能有中文字元,導致長度不對
			int len2=aString.substring(0, end).getBytes().length;
			if(start==0){
				if(end<start){
					in.reset();
					in.get(new byte[start]);
					return false;
				}
				if(end!=-1){
					in.reset();
					byte[] bytes1 = new byte[len2+10];//這裡不能使用end+10,因為start到end之間可能有中文字元,導致長度不對
					in.get(bytes1);
					String bString=new String(bytes1,"UTF-8");
					out.write(bString);
					if (in.remaining() > 0) {
						return true;
					}
				}else{
					in.reset();
					return false;
				}
			}else if(start!=-1){
				in.reset();
				in.get(new byte[start]);
				return true;
			}else{
				in.reset();
				return false;
			}
		}
		return false;
	}
}