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

原创 2013年12月03日 11:19:35

废话不多,直接贴代码

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字段值错误");
		}
	}
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

MINA 中的 协议编解码器

6.协议编解码器: 前面说过,协议编解码器是在使用Mina 的时候你最需要关注的对象,因为在网络传输的数据都是二进制数据(byte),而你在程序中面向的是JAVA 对象,这就需要你实现在发送数据时将...

《从零开始搭建游戏服务器》自定义兼容多种Protobuf协议的编解码器

引言 通过上篇 《从零开始搭建游戏服务器》使用Protobuf定义网络协议 的实践之后,我们知道在设置ChannelPiple的handler时,只能设置一个解码器,即protobufDec...

fix协议封装挑战-数据库脚本

declare @tname varchar(8000) set @tname='' select @tname=@tname+Name+','from sysobjects where xtype=...

fix协议封装挑战-工具类

MsgUtil: /* * @headerAndBody 包含消息头+消息体,包含SOH,不包含checksum域 */ public static String ch...

fix协议封装挑战-数据有效性校验

数据校验要校验每个字段还有头和尾。 校验包过数据类型校验,特殊值校验。 数据类型校验统一写,特殊值校验写在每个消息实体里。 数据校验采用递归的方式,减少代码编写难度。 Tag类(类型校验没写完...

mina自定义编解码器详解

  • 2016年01月27日 17:37
  • 6.12MB
  • 下载

mina简单编解码器示例

下面我们举一个模拟电信运营商短信协议的编解码器实现,假设通信协议如下所示: M sip:wap.fetion.com.cn SIP-C/2.0 S: 1580101xxxx R: 1889020xxx...

《Apache MINA 2.0 用户指南》第九章:编解码器过滤器

本章对 MINA 的协议编解码过滤器进行了深入讨论,先后介绍了协议编解码过滤器的使用原因和如何使用。最后用一个 demo 演示了协议编解码过滤器的具体使用。...
  • defonds
  • defonds
  • 2014年01月13日 16:12
  • 5683

自定义Mina编解码器

协议编解码器是在使用Mina 的时候最需要关注的对象,因为网络传输的数据都是二进制数据(byte),而在程序中面向的是JAVA 对象,这就需要在发送数据时将JAVA 对象编码二进制数据,接收数据时将二...

mina编解码器Demo

  • 2016年04月23日 00:05
  • 37KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:fix协议封装挑战-mina服务器的编解码器
举报原因:
原因补充:

(最多只允许输入30个字)