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框架深入学习指南 本文还有配套的精品资源,点击获取 简介:Apache MINA是一个用于简化网络应用开发的开源框架,支持TCP和UDP协议。它通过事件驱动模型和异步I/O提高并发性能,并采用Filter Chain设计模式优化代码结构。本学习笔记旨在为初学者提供MINA基础、事件模型、Filter Chain构建、异步I/O和实例应用等内容,同时结合《Mina2.0快速入门与源码剖析》的快... 阅读详情

相关推荐

Apache MINA2学习笔记:构建自定义协议的实践教程

在当今的网络编程领域中,Apache MINA作为一个高性能的、异步的I/O框架,提供了构建可扩展、可维护的网络应用程序的基础。它不仅仅是一个库,而是一个完整的框架,为开发者们简化了复杂的网络通信任务。MINA在底层抽象了网络通信的细节,使开发者能够专注于业务逻辑的实现。它支持TCP和UDP协议,广泛应用于即时通讯、网络游戏、物联网等多个领域。本章我们将对MINA框架进行一个基础概述,让读者对MINA有一个初步的了解。

weixin_42551310的博客 945

Mina基础(三)

        自定义协议编解码,自定义协议是使用最广泛的,因为它非常的灵活! 制定协议         协议需求:向服务端发送请求(频道的ID和说明文字),返回响应结果(该频道下所有的节目信息)。         协议格式如下:         请求格式 Syntax No. of Bits Identifier _ description...

wjxbj的博客 201

Apache MINA源码解析与应用

htmltable {th, td {th {pre {简介:Apache MINA是一个开源网络编程框架,支持TCP和UDP通信,为开发者提供了一个高级的、异步事件驱动的编程模型。本文深入分析了MINA的设计理念、架构、核心组件、以及源码实现,涵盖了过滤器链的构建、I/O事件处理、性能优化等方面。通过学习MINA源码,可以提升网络编程能力,尤其在高并发和低延迟的应用场景中。

weixin_42513870的博客 1034

mina自定义编解码器接收处理byte数组(同时解决数据传输中的粘包、缺包问题)

我们在自定义传输协议时,通常都是采用字节数组的方式进行传送,如何正确接收和解码byte数组? 假设我们自定义了传输协议: 字节数组的前4个字节是要传输的数据长度,后面跟数据。我们用mina可以这样处理 1.自定义编码器ByteArrayEncoder.java import org.apache.mina.core.session.IoSession; import org.a

jbgtwang的专栏 1万+

给新人的储能系统入门图解:从电芯到EMS,一张图看懂BESS里那些‘黑话’

本文通过视觉化拆解储能系统,从电芯到EMS详细解析BESS中的关键组件和行业术语。涵盖电芯参数、模组组装、PCS功能、BMS与EMS分工,以及SOC、DOD等关键运维参数,帮助新人快速理解储能系统的核心技术和应用场景。

weixin_42522964的博客 595

手把手教你用Matlab为PMSM电流环设计2P2Z补偿器(附与PI对比)

本文详细介绍了如何使用Matlab的controlSystemDesigner工具为永磁同步电机(PMSM)电流环设计2P2Z补偿器,并与传统PI控制器进行性能对比。通过频域分析和时域仿真,展示了2P2Z补偿器在提升带宽、减少超调等方面的优势,为高性能伺服驱动和精密运动控制提供了实用解决方案。

weixin_42551227的博客 380

Mina基础(二)

        Mina基础(一)中的简单实例,虽然实现了根据\r\n换行符编解码的功能,但是却存在以下问题:         a.编解码器中编码类型Charset硬编码,不便调整;         b.只能根据Windows的换行符\r\n解码,没有考虑其他操作系统的换行符,不灵活;         c.解码器中定义了成员变量IoBuffer, 但Decoder实例是单例的,因此Dec...

wjxbj的博客 260

【SABRE 3D, SABRE 3DxT,LAM设备】2025年9月14日-Clamshell 拆卸与安装

Clamshell 拆卸与安装。

weixin_46735260的博客 1691

apache mina 学习(九)-----IoBuffer

mina中没有直接使用java nio中原生的ByteBuffer作为底层缓存流处理方式,具体的原因官方给出的主要是: 1、NIO ByteBuffer没提供很可用的getters 和putters 。 2、很难在固定的大小中写入可变长度的数据。 当然mina并不是不让我们用原生的nio的ByteBuffer,这一点我们可以从IoBuffer的allocat方法得知: pu...

Cages的专栏 281

【DIY】使用STM32及PID算法实现一个磁悬浮玩具

今天教大家来做一个磁悬浮玩具。

小白白学电子 1万+

IGS精密星历高效获取与解析指南

本文详细介绍了IGS精密星历在高精度定位中的核心作用,对比了IGS Final、IGR和IGU等不同产品的精度与时效性差异。指南提供了从武汉大学、NASA CDDIS等数据中心高效下载数据的实战方法,并深入解析了SP3文件格式,帮助用户掌握精密星历的获取、解析与自动化处理技巧,以支持厘米级定位应用。

garlic的博客 839

Apache Mina 学习笔记(4)-Session

Session是Apache的核心,每当一个客户端连接到达时,就会

人生需要沉淀 732

如何通过 GitHub Actions 使用 SSH 自动化部署到阿里云 ECS 实例

通过 GitHub Actions 和 SSH 自动化部署,可以显著提高你的开发效率和部署的可靠性。本文介绍了如何生成 SSH 密钥、将公钥添加到阿里云 ECS 实例、将私钥添加到 GitHub Secrets,以及编写 GitHub Actions 工作流来实现自动化部署。希望这篇文章对你有所帮助!

吃面不喝汤的博客 1511

Apache Mina 学习笔记(4) - Filters

IoFilter是MINA的另外一个核心部分,他过滤所有的

人生需要沉淀 648

把 SAP Event Mesh 讲透:从事件驱动架构到 SAP BTP 落地实践

摘要: SAP Event Mesh是SAP BTP上的云端消息与事件服务,支持企业构建解耦、弹性的应用架构。它通过异步通信模式(如发布/订阅)解决传统同步集成的痛点,如系统紧耦合、链路脆弱等问题。核心能力包括事件驱动通信、可靠消息投递(支持至少一次送达)、与SAP生态深度集成(如S/4HANA事件扩展)以及混合环境支持。典型场景包括订单处理、库存同步等,发布方只需发出业务事件,订阅方按需消费,避免系统间直接依赖,符合Clean Core理念。两种关键模式为广播式的Publish/Subscribe和定向的

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 117

断层错动和近断层地震动联合作用下软岩隧洞衬砌损伤分析

摘要 本文提出了一种基于Python的软岩隧洞衬砌损伤分析系统,重点研究断层错动和近断层地震动的联合作用效应。系统采用有限元方法建立隧洞-围岩体系模型,通过非线性动力分析评估衬砌结构损伤。研究内容包括:1)建立考虑应变软化的软岩本构模型;2)基于位错理论模拟断层错动过程;3)合成具有速度脉冲效应的近断层地震动;4)开发完整的动力响应分析流程。结果表明,所提出的方法能有效评估软岩隧洞在复杂地质条件下的抗震性能,为工程设计提供理论依据。 关键词:软岩隧洞、断层错动、近断层地震动、损伤分析、Python、有限元法

max500600的博客 844

Apache Mina

初步接触RPC通信框架,目前有很多优秀的RPC框架,今天我参考该博文:http://www.cnblogs.com/xuekyo/archive/2013/03/06/2945826.html 学习了Aapche Mina通信框架。博主介绍的非常详细,包括Mina的源码流程,这里通过阅读博主的文章进行了学习记录,方便以后需要时使用。 Apache Mina 是一个网络应用程序框架,用来帮助用户简

JY_He的博客 3437

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Apache-mina学习笔记,非常全都资料,附带大量实例

Apache Mina2 学习笔记             目录 引言. 3 一.    Mina入门. 3 第一步.下载使用的Jar包. 3 第二步.工程创建配置. 4 第三步.服务端程序. 4 第四步.使用telnet命令来测试服务端. 6 第五步.客户端程序. 9 第六步.长连接VS短连接. 11 第七步.入门程序0212 第八步.入门程序

有 prepare , No out 1万+

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

apache之mina

市面上比较成熟的nio框架很少,其中做的比较好的就是apache的nio和jboss的netty了。因为apache是主流,所以可能mina用的较多。 到apache官网下载最新版的mina。接着mina官方给出的例子一起学习下mina。 /* * Licensed to the Apache Software Foundation (ASF) under one * or mor

孤独症有所好转 1898

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Apache MINA 快速入门指南-时间服务器

最近用到Socket套接字编程,在服务器监听方面还没有具体思路,朋友推荐了Apahce Mina,就在官方看了一下快速入门文档。原文是英文的,学习之余就将它翻译出来和大家共享!关于Mina的中文简介内容不多就摘抄了一些。     “MINA是一个Socket的网络框架,但是它提供了方便的Protocol支持,通过它的Encoder和Decoder,你将你的应用可以方便的扩展并支持各种基于S

wjp553650958的专栏 1707

mina java 1.6 版本_Apache MINA学习

1.准备工作mina官方下载地址:http://mina.apache.org/downloads.html,这里使用的版本是apache-mina-2.0.4-bin.zip。slf4j官方下载地址:http://www.slf4j.org/download.html,这里使用的版本是slf4j-1.6.4.zip。2.新手上路hello world先通过一个基本的例子来初步认识mina。新建项...

weixin_35619710的博客 363

Apache MINA学习笔记

handler

Klopp.牧野的专栏 456

apache-Mina学习笔记

Apache Mina       是一个支持基于socket NIO库的TCP/UDP应用程序的开发。 mina是apache基于socket nio的一套框架 Mina TCP的几个重要接口: IoSession :是对底层连接的封装,对应于当前客户端到服务器端的一个TCP连接实例。连接池中保存着多个IoSession             这个接口有如下常用的方法:

hit100410628的博客 908

MINA框架学习

转自:http://www.cnblogs.com/super-d2/archive/2013/02/18/2915495.html 一.MINA框架简介  MINA(Multipurpose Infrastructure for Network Applications)是用于开发高性能和高可用性的网络应用程序的基础框架。通过使用MINA框架可以可以省下处理底层I/O和线程并

yangyan19870319的专栏 1243

Apache MINA 时间服务 Demo 教程

Apache MINA 时间服务 Demo 教程 项目介绍 Mina-TimeDemo 是一个基于 Apache MINA 的简单示例项目,旨在演示如何使用 MINA 框架实现在 Android 客户端上向服务器请求当前时间并显示的功能。Apache MINA 是一个高性能、轻量级的异步通信框架,支持TCP/UDP等多种传输类型,并基于Java NIO构建。本项目由 shadowao 开发,作为...

gitblog_00939的博客 515
上一篇: Apache MINA学习之路(3)
gpair
博客等级 码龄17年 0粉丝 4原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值