`

apache mina 自定义编码解码

    博客分类:
  • mina
阅读更多
mina允许自定义数据传输的编码和解码方式

需要
实现ProtocolCodecFactory接口的工厂类
实现ProtocolDecoder接口的解码类
实现ProtocolEncoder接口的编码类

本例以client和server端都是java实现

首先定义传输的数据格式:
编码和解码都是针对数据字节。
数据格式:A+B+C+D
A:固定长度 6个字节,用来简单表示时间戳,
  月日年,时分秒每个一字节,年取后两位
B:内容(C+D)的length,固定长度,4个字节
C:请求指令:固定长度,4个字节
D:传递内容:不固定,json格式

这样针对上面的数据结构定义一个bean

public class MyMessage implements Serializable {
	
	/****/
	private static final long serialVersionUID = 5570201892267872279L;
	private Date date;//时间
	private int command;//指令
	private byte[] contents;//内容
	public int getCommand() {
		return command;
	}
	public void setCommand(int command) {
		this.command = command;
	}
	public byte[] getContents() {
		return contents;
	}
	public void setContents(byte[] contents) {
		this.contents = contents;
	}
	
	public int length(){
		return contents.length;
	}
	public Date getDate() {
		return date;
	}
	public void setDate(Date date) {
		this.date = date;
	}
}


编码类,继承org.apache.mina.filter.codec.CumulativeProtocolDecoder
重新encode方法即可

public class MyEncoder implements ProtocolEncoder {
	@Override
	public void encode(IoSession session, Object message,
			ProtocolEncoderOutput out) throws Exception {
		MyMessage msg = (MyMessage) message;
		IoBuffer buffer = IoBuffer.allocate(1024);
		buffer.setAutoExpand(true);
		//编码数据结构的A,时间戳
		buffer.put(getTimeTag(msg.getDate()));
		//数据结构的B
		buffer.putInt(msg.length()+4);
		//数据结构的C
		buffer.putInt(msg.getCommand());
		//数据结构的D
		buffer.put(msg.getContents());
		buffer.flip();
		
		out.write(buffer);
	}

	@Override
	public void dispose(IoSession session) throws Exception {
		
	}

	public static byte[] getTimeTag(Date date){
		if(date == null){
			date = new Date();
		}
		Calendar c = Calendar.getInstance();
		c.get(Calendar.YEAR);
		String dateStr = sdf.format(date);
		String[] dates = dateStr.split("-");
		byte[] bt = new byte[dates.length];
		for(int a=0;a<dates.length;a++){
			bt[a] = Byte.parseByte(dates[a]);
		}
		return bt;
	}
}

解码类,继承自org.apache.mina.filter.codec.CumulativeProtocolDecoder
重新decode方法

public class MyDecoder extends CumulativeProtocolDecoder {

	@Override
	protected boolean doDecode(IoSession session, IoBuffer in,
			ProtocolDecoderOutput out) throws Exception {
			//读取数据结构A
			byte[] dateTag = new byte[6];
			in.get(dateTag);
			//读取数据结构B
			int length =in.getInt();
			//读取数据结构C
			int command = in.getInt();
			//读取数据结构D
			byte[] bytes = new byte[length-4];
			in.get(bytes);
			//提取出数据结构对象
			MyMessage msg = new MyMessage();
			msg.setCommand(command);
			msg.setContents(bytes);
			out.write(msg);
			return true;
	}
}


工厂类,很简单。主要是给server端和client端提供使用
public class MyCodeFactory implements ProtocolCodecFactory{
	
	private ProtocolDecoder decoder;
	private ProtocolEncoder encoder;
	
	public MyCodeFactory() {
		decoder = new MyDecoder();
		encoder = new MyEncoder();
	}

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

	@Override
	public ProtocolDecoder getDecoder(IoSession session) throws Exception {
		return decoder;
	}
}


写到这里基本上自定义编码解码部分就完成了,下面使用就和其他已有mina提供的
编码解码filter一样使用了

首先还是要定义两个handler

server端handler:

public class MyServerHandler extends IoHandlerAdapter {
	   @Override
	    public void exceptionCaught( IoSession session, Throwable cause ) throws Exception
	    {
	        cause.printStackTrace();
	        session.close(true);
	    }
	    @Override
	    public void messageReceived( IoSession session, Object message ) throws Exception
	    {	
	     //收到了上面解码后的消息
	    	MyMessage msg = (MyMessage) message;
	    	if(message == null){
	    		//TODO 
	    	}
	    		
	    	int cmd = msg.getCommand();
	    	String body = new String(msg.getContents());
	    	String result = "";
		//TODO
		/**
		  根据请求指令的不同,调用后续的业务,
		  然后响应内容到client
		*/
	    	System.out.println(msg.getCommand()+"-----"+new String(msg.getContents()));
	        session.write(msg);
	    }
}


client端handler

public class MyClientHandler extends IoHandlerAdapter {
	@Override
	public void sessionOpened(IoSession session) throws Exception {
		//session.write(obj);
	}
	
	@Override
	public void messageReceived(IoSession session, Object message)
			throws Exception {
			//收到消息,。。。
		MyMessage gm = (MyMessage) message;
		System.out.println(gm.getCommand()+":"+new String(gm.getContents()));
	}
	
	@Override
	public void exceptionCaught(IoSession session, Throwable cause)
			throws Exception {
		session.close(true);
	}
}


server端配置:

	IoAcceptor accepter = new NioSocketAcceptor();
	ProtocolCodecFilter coderFilter = 
	//使用自定义的编码解码filter
	  new ProtocolCodecFilter(new MyCodeFactory());
	accepter.getFilterChain().addLast("a", new LoggingFilter());
	accepter.getFilterChain().addLast("b",coderFilter);
	//绑定handler
	accepter.setHandler(new MyServerHandler());
	
	accepter.getSessionConfig().setReadBufferSize(2048);
	accepter.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
	accepter.bind(new InetSocketAddress(8484));

client端配置:

		NioSocketConnector connector = new NioSocketConnector();
		connector.setConnectTimeoutMillis(20000);
		connector.getFilterChain().addLast("codes", new ProtocolCodecFilter(
				new MyCodeFactory()));
		connector.setHandler(new MyClientHandler());
		ConnectFuture future = connector.connect(new InetSocketAddress("localhost", 8484));
		future.awaitUninterruptibly();
		IoSession session = null;
		session = future.getSession();
		
		MyMessage gm = new MyMessage();
		Map<String, String> map = new HashMap<String, String>();
		gm.setCommand(101);
		map.put("name", "bird");
		map.put("age", "7");
		//JsonUtil json工具类,map转json,随便找个就行
		gm.setContents(JsonUtil.objectToStr(map).getBytes());
		session.write(gm);
		
		connector.dispose();


运行后server端会打印:1001-----{"name":"c","age":"7"}
client:1001:{"name":"c","age":"7"}

都能正确获取到传递的内容。

0
0
分享到:
评论

相关推荐

    mina自定义编码解码器

    本文将深入探讨如何在Mina中自定义编码解码器,这对于实现特定的网络通信协议至关重要。 首先,了解Mina的编码解码器架构是必要的。Mina使用了Chain of Responsibility设计模式,通过Filter链来处理进来的数据。...

    mina自定义编码器-自行做会话累积

    本项目是关于如何自定义编码器来实现会话累积功能的实践。 首先,我们需要理解Mina中的编码器接口`org.apache.mina.core.session.IoSession`。`IoSession`代表了客户端和服务器之间的一个连接,它包含了会话的状态...

    mina自定义编码器-固定位置指定消息的长度

    7. **配置MINA**:在你的MINA服务端或客户端配置中,注册你的自定义编码器,这样MINA在处理数据时会自动调用你的编码逻辑。 通过这种方式,自定义编码器可以让你更灵活地控制数据在网络上的传输形式,以适应各种...

    apache-mina-2.0.4.rar_apache mina_mina

    过滤器可以实现特定功能,如数据编码解码、安全验证、性能监控等。 2. **Session**:Session对象代表了客户端与服务器之间的连接。它负责管理会话状态,并提供读写操作接口。 3. **IoHandler**:IoHandler是处理...

    Apache mina2学习笔记DEMO

    在这个"Apache MINA2学习笔记DEMO"中,我们很可能会看到如何使用MINA来创建一个自定义协议的示例。自定义协议通常是为了满足特定应用的需求,例如高效的数据传输、安全性或者特定的编码格式。MINA允许开发者定义自己...

    Apache Mina 入门Demo

    7. **minaDemo项目结构**:压缩包中的minaDemo项目可能包含以下组件:主类(启动服务)、配置文件(如XML配置服务)、过滤器实现、编码解码器、以及IoHandler的实现。通过分析这个Demo,我们可以了解到如何实际搭建...

    Apache Mina帮助文档

    过滤器(Filter)是Mina的另一个重要组件,它们按照预定义的顺序对数据进行处理,如解码、编码、安全检查等,极大地简化了网络应用的开发。 **4. 丰富的协议支持** Apache Mina支持多种网络协议,如TCP、UDP、SSL/...

    apache mina 框架实例

    通过上述内容,我们可以看出Apache Mina是一个强大且灵活的网络通信框架,它支持自定义协议设计和高效的编码解码机制,适用于多种类型的网络应用开发。在实践中,开发者可以根据具体需求,结合Mina提供的工具和接口...

    Apache MINA 2.0 用户指南( 缺第一章节)

    Filters 可以帮助处理编码解码、错误处理等任务。 3. **创建 I/O Handler**:定义具体的业务逻辑。这里可以处理各种事件,例如连接建立、数据接收等。 #### 服务器端架构详解 服务器端架构是基于 MINA 的应用程序...

    Apache Mina Server 2.0 抢鲜体验

    开发者可以自定义过滤器来实现数据编码、解码、安全加密等功能,提高了代码的复用性和模块化。 5. **协议支持**:Mina不仅支持TCP/IP,还支持UDP和其他多种协议,如HTTP、FTP、SSL/TLS等。这使得开发者能够轻松构建...

    一个Apache MINA使用案例源代码ApacheMina

    MINA提供了一种灵活的方式,可以根据实际需求定义自定义的编解码器。 3. **FilterChain**: 过滤器链是MINA中实现业务逻辑的关键机制。开发者可以通过添加自定义过滤器来处理数据流,如日志记录、性能监控、身份验证...

    apache mina 简单示例

    如果需要自定义编码解码规则,可以实现相应接口。 9. **测试与调试**:在"TestMina"这个文件中,可能包含了服务端和客户端的测试代码,用于验证Mina应用的功能。通过断言和日志输出,你可以检查数据是否正确传输,...

    Mina自定义协议简单实现

    **Mina自定义协议简单实现** Apache Mina(Minimum Asynchronous Network)是一个开源的网络通信框架,它为Java开发者提供了一种高效、灵活且可扩展的框架,用于构建高性能的网络应用程序,如服务器和客户端应用。...

    Apache MINA 线程模型配置

    ### Apache MINA线程模型配置详解 #### 一、线程模型配置介绍 Apache MINA 是一个用于构建网络应用程序的高性能、高可靠性的框架。它提供了丰富的功能来简化网络编程,包括TCP/IP 和 UDP/IP 协议的支持。线程模型...

    mina编解码示例

    通过分析这些代码,我们可以深入理解Mina如何处理网络通信中的编码解码问题,以及如何根据具体需求设计和实现自定义的`Codec`。 总的来说,Mina编解码示例是一个很好的学习资源,帮助开发者掌握如何在实际项目中...

    apache-mina源码

    - **协议处理**:MINA提供了一些预定义的协议处理器,如TCP、UDP的实现,以及一些基础的协议编码解码器。 - **示例应用**:MINA通常会附带一些示例程序,帮助开发者理解如何使用框架构建实际应用。 - **测试用例**:...

    深入理解Apache Mina (2)---- 与IoFilter相关的几个类

    Apache Mina的IoFilter主要有以下作用:记录事件日志、测量系统性能、验证信息、过载控制以及信息的转换(例如编码和解码)。 要深入理解IoFilter,我们需从以下几个方面入手: 1. IoFilter的工作机制与应用场景 ...

    Apache mina源代码框架解析

    在这里,我们添加了两个过滤器:`LoggingFilter`用于记录网络通信的日志,以及`ProtocolCodecFilter`,它使用`TextLineCodecFactory`来编码和解码文本消息。`TextLineCodecFactory`依赖于指定的字符集(这里是UTF-8...

    mina编码器详解

    ### Mina编码器详解 #### 一、引言 Mina是Apache下的一个高效、轻量级的网络通信框架,支持多种传输协议如TCP...开发者可以根据实际应用场景选择合适的编码策略,并结合Mina提供的工具类轻松实现高效的编码解码逻辑。

    apache_mina_maven 客户端测试程序

    3. **消息编码解码**:MINA 提供了 `ProtocolDecoder` 和 `ProtocolEncoder` 接口,用于将应用层的消息转换成字节流,以及将接收到的字节流转换回消息对象。 4. **服务端交互**:测试程序会发送请求到服务器并接收...

Global site tag (gtag.js) - Google Analytics