`
Chrisp
  • 浏览: 4411 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

Apache MINA学习之路(4)

 
阅读更多

       查看 Mina 对 TextLineCodec 的实现源码会发现,根据换行符解码的消息 默认最大长度是 1024, 相当于缓冲区最大能存放 1K 的数据。所以使用时,建议调整参数为 2K;

       根据我们自己定义的文本换行符及编码格式编解码, 则需要把它们作为参数传递给编解码器;完整代码如下:

解码器

import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;

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

public class MyCodecDecoderII implements ProtocolDecoder {
	private Charset charset; // 编码格式
	private String delimiter; // 文本分隔符
	private IoBuffer delimBuf; // 文本分割符匹配的变量

	// 定义常量值,作为每个IoSession中保存解码任务的key值
	private static String CONTEXT = MyCodecDecoderII.class.getName()
			+ ".context";

	// 构造函数,必须指定Charset和文本分隔符
	public MyCodecDecoderII(Charset charset, String delimiter) {
		this.charset = charset;
		this.delimiter = delimiter;
	}

	public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out)
			throws Exception {
		Context ctx = getContext(session);
		// 如果文本换行符未指定,使用默认值
		if (delimiter == null || "".equals(delimiter)) {
			delimiter = "\r\n";
		}
		if (charset == null) {
			charset = Charset.forName("utf-8");
		}
		decodeNormal(ctx, in, out);
	}

	// 从IoSession中获取Context对象
	private Context getContext(IoSession session) {
		Context ctx;
		ctx = (Context) session.getAttribute(CONTEXT);
		if (ctx == null) {
			ctx = new Context();
			session.setAttribute(CONTEXT, ctx);
		}
		return ctx;
	}

	// 解码
	private void decodeNormal(Context ctx, IoBuffer in,
			ProtocolDecoderOutput out) throws CharacterCodingException {
		// 取出未完成任务中已经匹配的文本换行符的个数
		int matchCount = ctx.getMatchCount();
		// 设置匹配文本换行符的IoBuffer变量
		if (delimBuf == null) {
			IoBuffer tmp = IoBuffer.allocate(2).setAutoExpand(true);

			tmp.putString(delimiter, charset.newEncoder());
			tmp.flip();
			delimBuf = tmp;
		}

		int oldPos = in.position(); // 解码的IoBuffer中数据的原始信息
		int oldLimit = in.limit();
		while (in.hasRemaining()) { // 变量解码的IoBuffer
			byte b = in.get();
			if (delimBuf.get(matchCount) == b) { // 匹配第matchCount位换行符成功
				matchCount++;
				if (matchCount == delimBuf.limit()) { // 当前匹配到字节个数与文本换行符字节个数相同,匹配结束
					int pos = in.position(); // 获得当前匹配到的position(position前所有数据有效)
					in.limit(pos);
					in.position(oldPos); // position回到原始位置
					ctx.append(in); // 追加到Context对象未完成数据后面
					in.limit(oldLimit); // in中匹配结束后剩余数据
					in.position(pos);
					IoBuffer buf = ctx.getBuf();
					buf.flip();
					buf.limit(buf.limit() - matchCount);// 去掉匹配数据中的文本换行符
					try {
						out.write(buf.getString(ctx.getDecoder())); // 输出解码内容
					} finally {
						buf.clear(); // 释放缓存空间
					}
					oldPos = pos;
					matchCount = 0;
				}
			} else {
				// 如果matchCount==0,则继续匹配
				// 如果matchCount>0,说明没有匹配到文本换行符的中的前一个匹配成功字节的下一个字节,
				// 跳转到匹配失败字符处,并置matchCount=0,继续匹配
				in.position(in.position() - matchCount);
				matchCount = 0; // 匹配成功后,matchCount置空

			}
		}
		// 把in中未解码内容放回buf中
		in.position(oldPos);
		ctx.append(in);
		ctx.setMatchCount(matchCount);
	}

	public void dispose(IoSession session) throws Exception {
	}

	public void finishDecode(IoSession session, ProtocolDecoderOutput out)
			throws Exception {
	}

	// 内部类,保存IoSession解码时未完成的任务
	private class Context {
		private CharsetDecoder decoder;
		private IoBuffer buf; // 保存真实解码内容
		private int matchCount = 0; // 匹配到的文本换行符个数

		private Context() {
			decoder = charset.newDecoder();
			buf = IoBuffer.allocate(80).setAutoExpand(true);
		}

		// 重置
		public void reset() {
			matchCount = 0;
			decoder.reset();
		}

		// 追加数据
		public void append(IoBuffer in) {
			getBuf().put(in);
		}

		// ======get/set方法=====================
		public CharsetDecoder getDecoder() {
			return decoder;
		}

		public IoBuffer getBuf() {
			return buf;
		}

		public int getMatchCount() {
			return matchCount;
		}

		public void setMatchCount(int matchCount) {
			this.matchCount = matchCount;
		}
	} // end class Context;
}

 编码器

 

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

public class MyCodecEncoderII implements ProtocolEncoder {
	private Charset charset; // 编码格式
	private String delimiter; // 文本分隔符

	public MyCodecEncoderII(Charset charset, String delimiter) {
		this.charset = charset;
		this.delimiter = delimiter;
	}

	public void encode(IoSession session, Object message,
			ProtocolEncoderOutput out) throws Exception {
		if (delimiter == null || "".equals(delimiter)) { // 如果文本换行符未指定,使用默认值
			delimiter = "\r\n";
		}
		if (charset == null) {
			charset = Charset.forName("utf-8");
		}
		String value = message.toString();
		IoBuffer buf = IoBuffer.allocate(value.length()).setAutoExpand(true);

		buf.putString(value, charset.newEncoder()); // 真实数据
		buf.putString(delimiter, charset.newEncoder()); // 文本换行符
		buf.flip();
		out.write(buf);
	}

	public void dispose(IoSession session) throws Exception {
	}
}
 编解码工厂

 

 

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;

public class MyCodecFactoryII implements ProtocolCodecFactory {
	private Charset charset; // 编码格式
	private String delimiter; // 文本分隔符

	public MyCodecFactoryII(Charset charset, String delimiter) {
		this.charset = charset;
		this.delimiter = delimiter;
	}

	public ProtocolDecoder getDecoder(IoSession session) throws Exception {
		return new MyCodecDecoderII(charset, delimiter);
	}

	public ProtocolEncoder getEncoder(IoSession session) throws Exception {
		return new MyCodecEncoderII(charset, delimiter);
	}
}
 服务端或客户端绑定过滤器
// 添加过滤器
acceptor.getFilterChain().addLast(
		"codec",
		new ProtocolCodecFilter(new MyCodecFactoryII(Charset
				.forName("utf-8"), "\r\n")));
 

 

分享到:
评论

相关推荐

    Apache Mina Server 2.0中文参考手册V1.0,Apache Mina2.0学习笔记(修订版)

    Apache Mina Server 2.0中文参考手册V1.0,Apache Mina2.0学习笔记(修订版)Apache Mina Server 2.0中文参考手册V1.0,Apache Mina2.0学习笔记(修订版)

    apache Mina的完整学习资料

    在学习Apache Mina时,首先要理解其核心组件和设计模式。Mina的核心组件包括Session、Filter、ProtocolCodec等。Session代表了客户端和服务器之间的连接,Filter则提供了数据处理链,ProtocolCodec则用于将应用层的...

    apache-mina-2.0.4.rar_apache mina_mina

    对于希望提高网络应用性能或熟悉Java NIO编程的开发者来说,Apache Mina 2.0.4的源码分析是一次宝贵的学习机会。你可以通过阅读源码学习到如何有效地处理高并发场景,如何设计和实现高效的网络协议,以及如何利用...

    Apache mina2学习笔记DEMO

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

    apache mina 学习笔记三(子项目FtpServer)

    在本学习笔记中,我们将专注于MINA的子项目——FtpServer,它是实现FTP服务器功能的一个模块。 FTP(File Transfer Protocol)是一种广泛使用的互联网协议,用于在不同主机之间传输文件。Apache MINA FtpServer提供...

    Apache Mina帮助文档

    Apache Mina是一个高度可扩展的网络通信框架,主要用于构建高性能、高效率的服务端应用程序。...通过学习和使用"Mina帮助文档",开发者可以更好地理解和利用这个框架,构建出高效、稳定的网络应用。

    Apache Mina 入门Demo

    通过深入学习和实践这个Apache Mina入门Demo,你将掌握如何利用Mina构建网络应用,并了解其核心特性和工作原理,这对于从事Java网络编程或者需要处理大规模并发连接的开发者来说是非常有价值的。

    apache mina实例免费下载

    Apache MINA(Multipurpose Infrastructure for Network Applications)是一个开源框架,主要设计用于简化网络应用程序的开发,尤其是基于TCP和UDP协议的应用。它提供了高度可扩展和高性能的非阻塞I/O模型,使得...

    apache-mina-2.0.4架包及源码各pdf学习教程

    apache-mina-2.0.4 架包 源码 学习教程.apache mina是Apache 组织一个较新的项目,它为开发高性能和高可用性的网络应用程序提供了非常便利的框架。当前发行的 MINA 版本支持基于 Java NIO 技术的 TCP/UDP 应用程序...

    Apache MINA框架相关资料

    标题中的“Apache MINA框架相关资料”涵盖了对MINA框架的全面学习材料,包括中文参考手册、源码分析、API文档和与Spring框架的整合指南。 1. **中文参考手册**(Apache_Mina_Server_2.0中文参考手册V1.0.pdf):这...

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

    Apache MINA是一个高性能、异步事件驱动的网络应用程序框架,主要设计用于简化开发服务器端的高性能网络应用。这个框架提供了一种抽象层,允许开发者使用相同的API处理多种不同的传输协议,如TCP/IP、UDP/IP以及SSL/...

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

    ### Apache MINA 2.0 用户指南:基础知识 #### 基础概念介绍 Apache MINA 2.0 是一款高性能且易于使用的网络...在未来的学习过程中,我们将更深入地探索 MINA 的高级特性,如会话管理、错误处理、安全性和扩展性等。

    apache mina-spring 服务端程序

    通过这个项目,开发者可以学习到如何将Mina的异步I/O能力与Spring的容器管理及依赖注入机制结合,构建出健壮且易于维护的网络服务端程序。这包括理解Mina的事件模型、Spring的bean管理和网络编程的最佳实践。同时,...

    Apache Mina Server 2.0 抢鲜体验

    Apache Mina Server 2.0 是一款高性能、...此外,下载的压缩包文件“minaTest”可能包含示例代码或测试项目,可以作为学习和实践Apache Mina的好材料。通过这些实践,你可以加深对Mina的理解,并将其应用到实际项目中。

    apache-mina例子

    Apache Mina是一个开源项目,主要用于构建高...在`MinaTimeServer`和`MinaClient`的例子中,我们可以看到如何使用Mina轻松地建立一个简单的服务器和客户端通信系统,这对于理解和学习Mina的基本用法是非常有帮助的。

    apache mina 中文版 学习资料(很详细的哟)

    很详细的描述了apache mina 框架,对于那些对于英文不是很懂得人,这简直就是福音啊,哈哈

    apache-mina源码

    通过阅读和分析`apache-mina-2.0.16`的源码,我们可以深入理解MINA的设计思想,学习如何构建高效的网络服务,并能根据自己的需求定制和扩展MINA的功能。对于想要从事网络编程或系统架构设计的开发者来说,研究MINA...

    Apache-Mina-2.rar_apache mina_java mina_mina_mina-core-1.1.3

    Apache Mina是一个强大的开源项目,专门设计用于构建网络应用程序。这个框架的核心目标是提供一个抽象层,使得开发者能够专注于业务逻辑,而不是底层网络通信的复杂性。标题中的"Apache-Mina-2.rar"和"mina-mina-...

    Apache Mina 2 完全自学手册

    IoService是Mina中的核心接口之一,它定义了网络服务的基本操作,包括启动、停止服务以及连接管理。它是IoAcceptor和IoConnector的超类型,为它们提供统一的接口。 **2. IoFilter接口** IoFilter接口用于处理数据...

Global site tag (gtag.js) - Google Analytics