fix协议封装挑战-mina服务器的编解码器

废话不多,直接贴代码

package cs.mina.codec;

import java.nio.charset.Charset;

import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolEncoder;

/*
 *@author(huangxiaoping)
 *@date 2013-10-24
 */
public class CsFixProtocolCodecFactory implements ProtocolCodecFactory {
	private CsFixProtocolDecoder decoder;
	private CsFixProtocolEncoder encoder;
	
	public CsFixProtocolCodecFactory(Charset charset){
		decoder= new CsFixProtocolDecoder(charset);
		encoder=new CsFixProtocolEncoder(charset);
	}
	@Override
	public ProtocolDecoder getDecoder(IoSession arg0) throws Exception {
		
		return decoder;
	}

	@Override
	public ProtocolEncoder getEncoder(IoSession arg0) throws Exception {
		
		return encoder;
	}

}

package cs.mina.codec;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolDecoderAdapter;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;

import cs.mina.SeqenceNum;
import cs.mina.codec.msg.BaseMsg;
import cs.mina.codec.msg.MsgFactory;
import cs.mina.codec.msg.MsgUtil;
import cs.mina.codec.msg.decoder.MsgDecoderFactory;
import cs.mina.exception.InValidDataException;

/*
 *@author(huangxiaoping)
 *@date 2013-10-24
 */
public class CsFixProtocolDecoder  extends ProtocolDecoderAdapter {
	private final Charset charset;
	private List<String> incorrectMsgList=new ArrayList<String>();
	private boolean isChunked=false;
	public CsFixProtocolDecoder(Charset charset){
		this.charset=charset;
	}
	@Override
	public void decode(IoSession arg0, IoBuffer arg1, ProtocolDecoderOutput arg2)
			throws Exception {
		String input=arg1.getString(charset.newDecoder());
		System.out.println(input);
		int index=input.indexOf(BaseMsg.SOH, input.indexOf(BaseMsg.SOH+"10=")+1);
		List<String> msgList=new ArrayList<String>();
		
		synchronized (this) {
			if(input.lastIndexOf(BaseMsg.SOH+"10=")!=(input.length()-8)||!input.endsWith(BaseMsg.SOH)){
				isChunked=true;
				incorrectMsgList.add(input);
			}else if(input.lastIndexOf(BaseMsg.SOH+"10=")==(input.length()-8)&&input.startsWith("8=")&&input.indexOf("9=")<15&&input.indexOf("35=")<25){
				msgList.add(input.substring(0, index+1));
				while((index+1)!=input.length()){
					input=input.substring(index+1);
					index=input.indexOf(BaseMsg.SOH, input.indexOf(BaseMsg.SOH+"10=")+1);
					msgList.add(input.substring(0, index+1));
				}
			}else if(isChunked){
				isChunked=false;
				String concat="";
				for(int i=0;i<incorrectMsgList.size();i++){
					concat+=incorrectMsgList.get(i);
				}
				concat+=input;
				int indexIncorrect=concat.indexOf(BaseMsg.SOH, concat.indexOf(BaseMsg.SOH+"10=")+1);
				msgList.add(concat.substring(0, indexIncorrect+1));
				while((indexIncorrect+1)!=concat.length()){
					concat=concat.substring(indexIncorrect+1);
					indexIncorrect=concat.indexOf(BaseMsg.SOH, concat.indexOf(BaseMsg.SOH+"10=")+1);
					msgList.add(concat.substring(0, indexIncorrect+1));
					
				}
				for(int i=0;i<incorrectMsgList.size();i++){
					incorrectMsgList.remove(i);
				}
			}else{
				throw new Exception("数据包错误"+input);
			}
		}
		
	    if(!isChunked){
	    	for(int i=0;i<msgList.size();i++){
				SeqenceNum.increaseNextSeqNum();
				String str=msgList.get(i);
				input=str;
				str=str.substring(0, str.indexOf(BaseMsg.SOH+"10=")+1);
				String checkSum=MsgUtil.checkSum(str);
				String msgType=input.substring(input.indexOf(BaseMsg.SOH+"35=")+1);
				msgType=msgType.substring(msgType.indexOf("=")+1,msgType.indexOf(BaseMsg.SOH));
				String type=msgType;
				BaseMsg baseMessage=MsgFactory.getMsg(type);
				String[]msgArray=MsgUtil.seperate(input);
				baseMessage.setHead(msgArray[0]);
				baseMessage.setBody(msgArray[1]);
				baseMessage.setTailer(msgArray[2]);
				baseMessage.decode();
				baseMessage.validate();
				if(!checkSum.equals(baseMessage.getTailerEntity().getCheckSum().getTagValue())){
					throw new InValidDataException("checksum字段值错误");
				}
				
				arg2.write(baseMessage);
			}
	    }
		
		
		
	}

}

package cs.mina.codec;

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.ProtocolEncoderAdapter;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;

import cs.mina.MessageMap;
import cs.mina.SeqenceNum;
import cs.mina.codec.msg.BaseMsg;
import cs.mina.codec.msg.MsgUtil;
import cs.mina.codec.msg.decoder.MsgDecoder;
import cs.mina.codec.msg.decoder.MsgDecoderFactory;
import cs.mina.codec.msg.encoder.MsgEncoder;
import cs.mina.codec.msg.encoder.MsgEncoderFactory;
import cs.mina.exception.InValidDataException;

/*
 *@author(huangxiaoping)
 *@date 2013-10-24
 */
public class CsFixProtocolEncoder extends ProtocolEncoderAdapter {
	private final Charset charset;
	public CsFixProtocolEncoder(Charset charset){
		this.charset=charset;
	}
	@Override
	public void encode(IoSession arg0, Object arg1, ProtocolEncoderOutput arg2)
			throws Exception {
		//SeqenceNum.increaseSeqNum();
		BaseMsg message=(BaseMsg)arg1;
		MessageMap.addMsg(message);
		message.validate();
		//MsgEncoder encoder=MsgEncoderFactory.getEncoder(message.getHeadEntity().getMsgType().getTagValue());
		String str=message.encode();
		message.getHeadEntity().getBodyLength().setTagValue(getBodyLength(str));
		str=message.encode();
		String result=str;
		validateLen(str);
		str=str.substring(0, str.indexOf(BaseMsg.SOH+"10=")+1);
		String checkSum=MsgUtil.checkSum(str);
		message.getTailerEntity().getCheckSum().setTagValue(checkSum);
		result=message.encode();
		System.out.println(result);
		IoBuffer io = IoBuffer.allocate(result.getBytes().length);
		io.put(result.getBytes());
		io.flip();
		arg2.write(io);

	}

	private String getBodyLength(String msg){
		String m1=msg.substring(msg.indexOf(BaseMsg.SOH+"9=")+1);
		String m2=m1.substring(m1.indexOf(BaseMsg.SOH)+1);
		String m3=m2.substring(0,m2.indexOf(BaseMsg.SOH+"10=")+1);
		return m3.length()+"";
	}
	
	private void validateLen(String msg){
		String m1=msg.substring(msg.indexOf(BaseMsg.SOH+"9=")+1);
		String r1=m1.substring(2, m1.indexOf(BaseMsg.SOH));
		String m2=m1.substring(m1.indexOf(BaseMsg.SOH)+1);
		String m3=m2.substring(0,m2.indexOf(BaseMsg.SOH+"10=")+1);
		if( !(m3.length()==Integer.parseInt(r1))){
			throw new InValidDataException("BodyLength字段值错误");
		}
	}
}


你可能感兴趣的:(fix协议封装挑战-mina服务器的编解码器)