解決MINA中xml斷包粘包問題
阿新 • • 發佈:2019-02-18
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; } }