Mina使用起来多么简洁方便呀,就是不具备Java NIO的基础,只要了解了Mina常用的API,就可以灵活使用并完成应用开发。
首先,看Mina在项目中所处的位置,如下图:
Mina处于中间层,它不关心底层网络数据如何传输,只负责接收底层数据,过滤并转换为Java对象提供给我们的应用程序,然后把应用程序响应值过滤并转换为底层识别的字节,提供给底层传输; 总之,Mina是底层数据传输和用户应用程序交互的接口!
Mina工作流程图如下:
这个流程图不仅很直观的看出了Mina的工作流程,也涵盖了Mina的三个核心接口:IoService接口,IoFilter接口和IoHandler接口:
第一步.创建服务对象(客户端或服务端) ---IoService接口实现
第二步. 数据过滤(编码解码等) ---IOFilter接口实现
第三步. 业务处理 ---IoHandler接口实现
Mina的精髓是IOFilter,它可以进行日志记录,信息过滤,编码解码等操作,把数据接收发送从业务层独立出来。
创建服务对象,则是把NIO繁琐的部分进行封装,提供简洁的接口。
业务处理是我们最关心的部分,跟普通的应用程序没任何分别。
一.IoService接口
作用:IoService是创建服务的顶层接口,无论客户端还是服务端,都是从它继承实现的。
1.类结构
常用接口为:IoService,IoAcceptor,IoConnector
常用类为:NioSocketAcceptor,NioSocketConnector
类图如下:
先提出两个问题:
1.为什么有了IoService接口还要定义AbstractIoService抽象类?
2. AbstractIoService抽象类与IoAcceptor(IoConnector)有什么区别?
分析:
a.IoService接口声明了服务端的共有属性和行为;
b.IoAcceptor接口继承了IoService接口,并添加了服务端特有的接口属 性及方法,比如bind()方法,成为典型的服务端接口;
c.IoConnector接口同样继承了IoService接口,并添加了客户端特有的 接口属性及方法,比如connect()方法,成为典型的客户端接口;
IoService是IoAcceptor和IoConnector父接口,为什么不直接定义IoAcceptor和IoConnector接口呢,因为它们有共同的特点,比如共同属性,管理服务的方法等,所有IoService的出现是为了代码复用。
d.AbstractIoService实现了IoService中管理服务的方法,比如 getFilterChainBuilder方法,获得过滤器链;为什么有了IoService接口还要定义AbstractIoService抽象类?一样为了代码的复用!AbstractIoService抽象类实现了服务端或客户端的共有的管理服务的方法,不需要让IoService接口的子类重复的实现这些方法;
e.AbstractIoService抽象类继承了AbstractIoService抽象类并实现了 IoAcceptor接口,成为了拥有管理服务端实现功能的服务端类;我们常用的NioSocketAcceptor就是它的子类;
AbstractIoConnector抽象类继承了AbstractIoService抽象类并实现了 IoConnector接口,成为了拥有管理客户端实现功能的客户端类;我们常用的NioSocketConnector就是它的子类;
AbstractIoService抽象类与IoAcceptor(IoConnector)有什么区别?很清楚,AbstractIoService抽象类实现的是共有的管理服务的方法,只有管理功能的一个类;而两个接口却是不同的两个服务角色,一个客户端,一个服务端。
2.应用
在实际应用中,创建服务端和客户端的代码很简单:
创建服务端:
IoAcceptor acceptor = null; // 创建连接 try { // 创建一个非阻塞的server端的Socket acceptor = new NioSocketAcceptor();
创建客户端:
// 创建一个非阻塞的客户端程序 IoConnector connector = new NioSocketConnector();
而我们常常关心的就是服务端和客户端的一些参数信息:
1).IoSessionConfig getSessionConfig()
获得IoSession的配置对象IoSessionConfig,通过它可以设置Socket连接的一些选项。
a. void setReadBufferSize(int size)
这个方法设置读取缓冲的字节数,但一般不需要调用这个方法,因为IoProcessor 会自动调整缓冲的大小。你可以调用setMinReadBufferSize()、setMaxReadBufferSize()方法,这样无论IoProcessor 无论如何自动调整,都会在你指定的区间。
b. void setIdleTime(IdleStatus status,int idleTime)
这个方法设置关联在通道上的读、写或者是读写事件在指定时间内未发生,该通道就进入空闲状态。一旦调用这个方法,则每隔idleTime 都会回调过滤器、IoHandler 中的sessionIdle()方法。
c. void setWriteTimeout(int time)
这个方法设置写操作的超时时间。
d. void setUseReadOperation(boolean useReadOperation)
这个方法设置IoSession 的read()方法是否可用,默认是false。
// 获得IoSessionConfig对象 IoSessionConfig cfg=acceptor.getSessionConfig(); // 设置读取数据的缓冲区大小() cfg.setReadBufferSize(2048); // 读写通道10秒内无操作进入空闲状态 cfg.setIdleTime(IdleStatus.BOTH_IDLE, 10); // 写操作超时时间10秒 cfg.setWriteTimeout(10);
2).DefaultIoFilterChainBuilder getFilterChain()
获得过滤器链,由此来配置过滤器;非常核心的一个配置!(过滤器是Mina的核心)
// 创建一个非阻塞的server端的Socket acceptor = new NioSocketAcceptor(); // 设置日志过滤器 acceptor.getFilterChain().addLast("logger",new LoggingFilter()); // 设置过滤器(使用Mina提供的文本换行符编解码器) acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"), LineDelimiter.WINDOWS.getValue(), LineDelimiter.WINDOWS.getValue())));
3).setHandler(IoHandler handler)
向IoService注册IoHandler进行业务处理。这是服务(无聊客户端还是服务端)必不可少的配置。
// 添加业务逻辑处理器类 connector.setHandler(new Demo1ClientHandler());
4).其他配置 服务端必须指定绑定的端口号
// 绑定端口 acceptor.bind(new InetSocketAddress(PORT)); logger.info("服务端启动成功... 端口号为:" + PORT);
客户端必须指定请求的服务器地址和端口号:(该方法是异步执行的)
ConnectFuture future = connector.connect(new InetSocketAddress( HOST, PORT));// 创建连接 future.awaitUninterruptibly();// 等待连接创建完成 session = future.getSession();// 获得session session.write("我爱你mina");// 发送消息
5).关闭客户端
因为客户端的连接是异步的,所有必须先连接上服务端获得了session才能通信;同时,一旦需要关闭,必须指定disponse()方法关闭客户端,如下:
// 添加业务逻辑处理器类 connector.setHandler(new DemoClientHandler()); IoSession session = null; try { ConnectFuture future = connector.connect(new InetSocketAddress( HOST, PORT));// 创建连接 future.awaitUninterruptibly();// 等待连接创建完成 session = future.getSession();// 获得session session.write("我爱你mina");// 发送消息 } catch (Exception e) { logger.error("客户端链接异常...", e); } session.getCloseFuture().awaitUninterruptibly();// 等待连接断开 connector.dispose();
这是Mina2的处理方式,但在Mina1.1.7中,必须使用setWorkerTimeout()方法关闭客户端:
// 在关闭客户端前进入空闲状态的时间为1秒 //Set how many seconds the connection worker thread should remain alive once idle before terminating itself. connector.setWorkerTimeout(1);
6).总结
IoService是创建服务端和客户端的接口,实际应用中我们大多都是应用它的实现类来创建服务对象;但是,在开发中你最关心的是你究竟处于哪个位置?说直白一点就是:你究竟是开发客户端还是服务端?比如经常跟银行打交道的朋友都知道,开发中往往银行是服务端,我们要和它打交道就是要知道银行服务端的IP,端口号和请求格式,写一个客户端来请求数据。
但有一点可以肯定,服务端的难度比客户端大!服务端首先要制定协议,其次是考虑并发量;这些都不是很轻松就可以搞定的。
IoService就这些啦,下面的IoFilter接口是Mina的精髓,要关键学习。
二.IoFilter接口
Mina最主要的工作就是把底层传输的字节码转换为Java对象,提供给应用程序;或者把应用程序返回的结果转换为字节码,交给底层传输。这些都是由IoFilter完成的,因此IoFilter是Mina的精髓所在。
在Mina程序中,IoFilter是必不可少的;有了它,Mina的层次结构才异常清晰:
IoFilter----消息过滤 IoHandler----业务处理
Filter,过滤器的意思。IoFilter,I/O操作的过滤器。IoFilter和Servlet中的过滤器一样,主要用于拦截和过滤网络传输中I/O操作的各种消息。在Mina的官方文档中已经提到了IoFilter的作用:
(1)记录事件的日志(Mina默认提供了LoggingFilter)
(2)测量系统性能
(3)信息验证
(4)过载控制
(5)信息的转换(主要就是编码和解码)
(6)和其他更多的信息
IoService实例会绑定一个DefaultIoFilterChainBuilder——过滤器链,我们把自定义的各种过滤器(IoFilter)自由的插放在这个过滤器链上了,类似于一种可插拔的功能!
1.类结构
常用接口为:IoFilter,IoFilterChainBuilder
常用类为:IoFilterAdapter,DefaultIoFilterChainBuilder,ProtocolCodecFilter,LoggingFilter
类图如下:
同上面,先提出两个问题:
1. 在IoService中如何添加多个IoFilter?
2. 如何自定义协议编解码器?
分析:
a. IoFilter有2个实现类:IoFilterAdapter是个抽象的适配器类,我们可以根据需要扩展这个类,并且有选择的覆盖过滤器的方法;所有方法的默认把事件转发到下一个过滤器;
查看源码如下:
/** * {@inheritDoc} */ public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { nextFilter.sessionOpened(session); }
b .ReferenceCountingFilter封装了IoFilter实例,监看调用该filter的对象的个数,如果没有任何对象调用该IoFilter,就自动销毁IoFilter;查看源码如下:
public class ReferenceCountingFilter extends IoFilterAdapter { private final IoFilter filter; private int count = 0; public ReferenceCountingFilter(IoFilter filter) { this.filter = filter; } public void init() throws Exception { // no-op, will init on-demand in pre-add if count == 0 } public void destroy() throws Exception { //no-op, will destroy on-demand in post-remove if count == 0 } ... }
c. 实现IoFilterAdapter的类有多个,但是我们使用最多的就是ProtocolCodecFilter,它是我们自定义编解码器的入口。
2.应用
我们在应用中解释上面提述的两个问题!
1).添加过滤器
在IoService中如何添加多个IoFilter?如下代码,我添加了2个过滤器:LoggingFilter和TextLineCodecFactory(源码为入门的服务端程序Demo03Server.java基础上增加日志过滤器)
// 创建一个非阻塞的server端的Socket acceptor = new NioSocketAcceptor(); //设置日志过滤器 acceptor.getFilterChain().addLast("logger", new LoggingFilter()); // 直接发送对象 acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new ObjectSerializationCodecFactory())); // 获得IoSessionConfig对象 IoSessionConfig cfg = acceptor.getSessionConfig(); // 读写通道10秒内无操作进入空闲状态 cfg.setIdleTime(IdleStatus.BOTH_IDLE, 100); // 绑定逻辑处理器 acceptor.setHandler(new Demo03ServerHandler()); // 绑定端口 acceptor.bind(new InetSocketAddress(PORT)); logger.info("服务端启动成功... 端口号为:" + PORT);
运行服务端程序,后再执行Demo03Client.java,服务端打印信息如下:
2016-01-03 22:13:14,571 INFO Demo03Server - 服务端启动成功... 端口号为:3005 2016-01-03 22:13:19,771 INFO LoggingFilter - CREATED 2016-01-03 22:13:19,773 INFO Demo03ServerHandler - 服务端与客户端创建连接... 2016-01-03 22:13:19,774 INFO LoggingFilter - OPENED 2016-01-03 22:13:19,774 INFO Demo03ServerHandler - 服务端与客户端连接打开... 2016-01-03 22:13:19,785 INFO LoggingFilter - RECEIVED: HeapBuffer[pos=0 lim=169 cap=2048: 00 00 00 A5 AC ED 00 05 73 72 01 00 29 63 6F 6D...] 2016-01-03 22:13:19,785 DEBUG ProtocolCodecFilter - Processing a MESSAGE_RECEIVED for session 1 2016-01-03 22:13:19,797 INFO Demo03ServerHandler - 发送人手机号码:13681803609 2016-01-03 22:13:19,798 INFO Demo03ServerHandler - 接受人手机号码:13721427169 2016-01-03 22:13:19,798 INFO Demo03ServerHandler - 发送信息:测试发送短信,这个是短信信息哦,当然长度是有限制的哦.... 2016-01-03 22:13:19,804 INFO LoggingFilter - SENT: HeapBuffer[pos=0 lim=0 cap=0: empty] 2016-01-03 22:13:19,804 INFO Demo03ServerHandler - 服务端发送信息成功... 2016-01-03 22:13:19,805 INFO LoggingFilter - CLOSED
注意:LoggerFilter的日志,修改代码,交换LoggingFilter和TextLineCodecFactory的位置,如下所示:
// 创建一个非阻塞的server端的Socket acceptor = new NioSocketAcceptor(); // 直接发送对象 acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new ObjectSerializationCodecFactory())); //设置日志过滤器 acceptor.getFilterChain().addLast("logger", new LoggingFilter()); // 获得IoSessionConfig对象 IoSessionConfig cfg = acceptor.getSessionConfig(); // 读写通道10秒内无操作进入空闲状态 cfg.setIdleTime(IdleStatus.BOTH_IDLE, 100); // 绑定逻辑处理器 acceptor.setHandler(new Demo03ServerHandler()); // 绑定端口 acceptor.bind(new InetSocketAddress(PORT)); logger.info("服务端启动成功... 端口号为:" + PORT);
运行服务端程序,后再执行Demo03Client.java,服务端打印信息如下:
2016-01-03 22:18:20,578 INFO Demo03Server - 服务端启动成功... 端口号为:3005 2016-01-03 22:18:26,725 INFO LoggingFilter - CREATED 2016-01-03 22:18:26,727 INFO Demo03ServerHandler - 服务端与客户端创建连接... 2016-01-03 22:18:26,727 INFO LoggingFilter - OPENED 2016-01-03 22:18:26,727 INFO Demo03ServerHandler - 服务端与客户端连接打开... 2016-01-03 22:18:26,738 DEBUG ProtocolCodecFilter - Processing a MESSAGE_RECEIVED for session 1 2016-01-03 22:18:26,750 INFO LoggingFilter - RECEIVED: com.bijian.study.mina.dto.PhoneMessageDto@16e5255 2016-01-03 22:18:26,750 INFO Demo03ServerHandler - 发送人手机号码:13681803609 2016-01-03 22:18:26,750 INFO Demo03ServerHandler - 接受人手机号码:13721427169 2016-01-03 22:18:26,750 INFO Demo03ServerHandler - 发送信息:测试发送短信,这个是短信信息哦,当然长度是有限制的哦.... 2016-01-03 22:18:26,756 INFO LoggingFilter - SENT: 发送成功! 2016-01-03 22:18:26,757 INFO Demo03ServerHandler - 服务端发送信息成功... 2016-01-03 22:18:26,757 INFO LoggingFilter - CLOSED
对比上下日志,会发现,如果LoggingFilter在编码器前,它会在编码器处理前打印请求值和返回值的二进制信息,在编码器之后就不会打印!
在FilterChain中都是addLast()的方式添加在过滤链的最后面,这时候,把那个过滤器放在前面,就会先执行那个过滤器!
同addLast()方法一样,还提供了addFirst(),addBefore()等方法供使用。此时,就不难知道如何添加过滤器了吧!它们的顺序如何,就看你的设置的位置了!
同时发现,日志过滤器是根据IoSession的状态(创建、开启、发送、接收、异常等等)来记录会话的事件信息的!这对我们跟踪IoSession很有用。当地,也可以自定义logger的日志级别,定义记录那些状态的日志。比如:
// 设置日志过滤器 LoggingFilter lf=new LoggingFilter(); lf.setMessageReceivedLogLevel(LogLevel.DEBUG); acceptor.getFilterChain().addLast("logger",lf);
2).自定义编解码器
如何自定义协议编解码器?
协议编解码器是在使用Mina 的时候最需要关注的对象,因为网络传输的数据都是二进制数据(byte),而在程序中面向的是JAVA 对象,这就需要在发送数据时将JAVA 对象编码二进制数据,接收数据时将二进制数据解码为JAVA 对象。
编解码器同样是以过滤器的形式安插在过滤器链上,如下所示:
// 设置过滤器(使用Mina提供的文本换行符编解码器) acceptor.getFilterChain().addLast( // 添加消息过滤器 "codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset .forName("UTF-8"), LineDelimiter.WINDOWS.getValue(), LineDelimiter.WINDOWS.getValue())));
协议编解码器是通过ProtocolCodecFilter过滤器构造的,看它的构造方法,它需要一个ProtocolCodecFactory对象:
public ProtocolCodecFilter(ProtocolCodecFactory factory) { if (factory == null) { throw new IllegalArgumentException("factory"); } this.factory = factory; }
ProtocolCodecFactory接口非常直接,通过ProtocolEncoder和ProtocolDecoder对象来构建!
public interface ProtocolCodecFactory { /** * Returns a new (or reusable) instance of {@link ProtocolEncoder} which * encodes message objects into binary or protocol-specific data. */ ProtocolEncoder getEncoder(IoSession session) throws Exception; /** * Returns a new (or reusable) instance of {@link ProtocolDecoder} which * decodes binary or protocol-specific data into message objects. */ ProtocolDecoder getDecoder(IoSession session) throws Exception; }
ProtocolEncoder和ProtocolDecoder接口是Mina负责编码和解码的顶级接口!
编码和解码的前提就是协议的制定:比如上面我们使用的Mina自带的根据文本换行符解码的TextLineCodecFactory(),如果遇到文本换行符就开始编解码!
为什么要制定协议呢?常用的协议制定方法有哪些? 我们知道,底层传输的都是二进制数据,服务端和客户端建立连接后进行数据的交互,接受这对方发送来的消息,如何判定发送的请求或者响应的数据结束了呢?总不能一直傻等着,或者随意的就结束消息接收吧。这就需要一个规则!比如QQ聊天工具,当输入完一个消息后,点击发送按钮向对方发送时,此时系统就会在在你的消息后添加一个文本换行符,接收方看到这个文本换行符就认为这是一个完整的消息,解析成字符串显示出来。而这个规则,就称之为协议!
3).制定协议的方法
a.定长消息法:这种方式是使用长度固定的数据发送,一般适用于指令发送。譬如:数据发送端规定发送的数据都是双字节,AA 表示启动、BB 表示关闭等等。
b.字符定界法:这种方式是使用特殊字符作为数据的结束符,一般适用于简单数据的发送。譬如:在消息的结尾自动加上文本换行符(Windows使用\r\n,Linux使用\n),接收方见到文本换行符就认为是一个完整的消息,结束接收数据开始解析。注意:这个标识结束的特殊字符一定要简单,常常使用ASCII码中的特殊字符来标识。
c.定长报文头法:使用定长报文头,在报文头的某个域指明报文长度。该方法最灵活,使用最广。譬如:协议为:协议编号(1字节)+数据长度(4个字节)+真实数据。请求到达后,解析协议编号和数据长度,根据数据长度来判断后面的真实数据是否接收完整。HTTP 协议的消息报头中的Content-Length 也是表示消息正文的长度,这样数据的接收端就知道到底读到多长的字节数就不用再读取数据了。
根据协议,把二进制数据转换成Java对象称为解码(也叫做拆包);把Java对象转换为二进制数据称为编码(也叫做打包);我们这里重点讲解下后面两个协议的具体使用!
4).IoBuffer常用方法
Mina中传输的所有二进制信息都存放在IoBuffer中,IoBuffer是对Java NIO中ByteBuffer的封装(Mina2.0以前版本这个接口也是ByteBuffer),提供了更多操作二进制数据,对象的方法,并且存储空间可以自增长,用起来非常方便;简单理解,它就是个可变长度的byte数组!
a.static IoBuffer allocate(int capacity,boolean useDirectBuffer)
创建IoBuffer实例,第一个参数指定初始化容量,第二个参数指定使用直接缓冲区还是JAVA 内存堆的缓存区,默认为false。
b.IoBuffer setAutoExpand(boolean autoExpand)
这个方法设置IoBuffer 为自动扩展容量,也就是前面所说的长度可变,那么可以看出长度可变这个特性默认是不开启的。
c.IoBuffer flip()
limit=position,position=0,重置mask,为了读取做好准备,一般是结束buf操作,将buf写入输出流时调用;这个必须要调用,否则极有可能position!=limit,导致position后面没有数据;每次写入数据到输出流时,必须确保position=limit。
d.IoBuffer clear()与IoBuffer reset()
clear:limit=capacity , position=0,重置mark;它是不清空数据,但从头开始存放数据做准备,相当于覆盖老数据。
reset就是清空数据
e.int remaining()与boolean hasRemaining()
这两个方法一般是在调用了flip()后使用的,remaining()是返回limt-position的值!hasRemaining()则是判断当前是否有数据,返回position<limit的boolean值!
5).模拟根据文本换行符编解码实例
a.编写解码器
实现ProtocolDecoder接口,覆盖decode()方法。
package com.bijian.study.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.ProtocolDecoder; import org.apache.mina.filter.codec.ProtocolDecoderOutput; public class MyTextLineCodecDecoder implements ProtocolDecoder { private Charset charset = Charset.forName("UTF-8"); IoBuffer buf = IoBuffer.allocate(100).setAutoExpand(true); public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception { while (in.hasRemaining()) { byte b = in.get(); buf.put(b); if(b == '\n') { buf.flip(); byte[] msg = new byte[buf.limit()]; buf.get(msg); String message = new String(msg, charset); //解码成功,把buf重置 buf = IoBuffer.allocate(100).setAutoExpand(true); out.write(message); } } } public void dispose(IoSession session) throws Exception { } public void finishDecode(IoSession session, ProtocolDecoderOutput out) throws Exception { } }方法解释:
public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {decode方法的参数IoBuffer是建立连接后接收数据的字节数组;我们不断的从它里面读数据,直到遇上\r\n就停止读取数据,把上面累加的所有数据转换为一个字符串输出!
相关推荐
本教程旨在帮助开发者深入理解和掌握这些技术,并提供了一个可直接使用的基础平台框架。 Java NIO,全称为New Input/Output,是Java在1.4版本引入的一种新的I/O模型,它提供了与传统的BIO(Blocking I/O)不同的...
Mina基础示例 Mina,全称是Java Mina框架,是一个开源的网络通信应用框架,主要用于构建高性能、高可用性的网络服务器。Mina旨在简化网络编程,它提供了高级抽象,如事件驱动和异步I/O,使得开发者能够专注于业务...
Apache Mina是一个开源的网络通信应用框架,主要应用于Java平台,它为高性能、高可用性的网络应用程序提供了基础架构。在本文中,我们将深入探讨Mina的高级使用,特别是在文件图片传送、文件发送、XML和JSON报文处理...
在本教程中,我们将深入探讨如何整合Spring Boot与Mina框架,同时介绍Java NIO(非阻塞I/O)的基础知识。Spring Boot以其简洁、快速的起步方式深受开发者喜爱,而Mina则是一个强大的网络通信框架,常用于构建高性能...
在"Mina基础(三)"这篇博文中,我们主要探讨了Apache Mina框架的基本概念、工作原理以及如何通过实例来理解和应用它。Apache Mina是一个轻量级、高性能的网络应用开发框架,常用于构建网络服务,如TCP/IP和UDP通信...
《Mina基础(二)——深入理解Apache Mina框架》 Apache Mina是一个开源的网络通信框架,它为Java开发者提供了构建高性能、高可用性的网络应用程序的工具。在本篇文章中,我们将深入探讨Mina的核心概念和关键特性,...
Apache Mina是一个开源的Java框架,专门用于构建高性能、高可扩展性的网络应用程序。它提供了一个事件驱动的网络通信模型,使得开发者可以更方便地处理网络协议和I/O操作。在"mina学习基础-入门实例-传输定长报文(三...
Mina(全称“MINA: Minimalistic Application Networking API”)是Apache软件基金会的一个开源项目,它为开发者提供了一种简单而高效的方式来构建高性能、跨平台的网络应用。Mina的核心优势在于它的事件驱动和异步I...
标题中的"mina客户端简单代码示例"意味着我们将探讨如何使用Mina框架编写一个基础的客户端程序,该程序能够连接到服务器并发送数据。描述指出,运行这个客户端程序(minaTestClient)会展示一个窗口,用户可以通过...
Apache Mina是一个网络通信应用框架,它提供了一个高度可扩展和高性能的基础结构,用于处理I/O操作。Mina的核心是它的事件驱动、非阻塞I/O模型,这使得它能够在有限的资源下处理大量的并发连接。Mina支持多种传输...
1. **mina框架基础** - Mina提供了一个高效的、事件驱动的网络应用程序框架,简化了网络编程,尤其是TCP和UDP通信。 - 它基于IoSession接口,用于管理客户端与服务器之间的连接,包括读写操作、会话属性等。 2. *...
4. **Apache+Mina+ABC.pdf**:这个文档可能是对Mina的基础知识进行简单介绍的教程,"ABC"通常代表"基础、基本、入门",所以这本书可能会涵盖Mina的基本概念、安装步骤、第一个Mina应用的创建等内容,为初学者提供一...
了解以上知识点是掌握Apache MINA的基础,通过提供的学习资料,如《Mina2.0学习笔记》、《Apache MINA入门基础》和《Apache MINA Server 2.0中文参考手册》等,可以深入学习MINA的API用法、设计原理和最佳实践。...
本资源包包含了实现Mina框架基础功能所需的组件,对于搭建即时通讯服务器至关重要。 1. **Mina框架核心**:`apache-mina-2.0.19-bin.zip` 这个文件是Mina框架的二进制发行版,包含了Mina运行所需的jar文件和其他可...
Apache Mina是一个高度可扩展的网络通信框架,它允许开发者创建高性能、高效率的服务端和客户端应用程序。...通过学习和实践这个DEMO,开发者可以掌握Mina的基本用法,为构建高性能、高并发的网络应用打下坚实的基础。
Mina(Java Multithreaded Application Network Architecture)是一个开源的网络通信框架,由Apache软件基金会开发并维护。它提供了一个高度可扩展的、高性能的、事件驱动的I/O服务架构,广泛应用于各种网络协议的...
### Mina基础技术知识点 #### 一、MINA框架简介 **1.1 MINA是什么?** Apache MINA是一个强大的网络应用框架,旨在帮助开发者轻松构建高性能和高扩展性的网络应用。它通过Java NIO(非阻塞I/O)提供了一个抽象的...
MINA(Minimal Asynchronous Network Application)是一个高性能、基于Java NIO(非阻塞I/O)技术的网络应用程序框架。这个框架的主要目标是简化网络服务的开发,让开发者能够更专注于业务逻辑,而不是底层的网络...
Apache MINA(Multipurpose ...这为学习和理解MINA框架提供了一个基础平台,并且可以在实际项目中作为起点进行扩展和定制。如果你对MINA感兴趣,你可以参考作者的博客获取更多资源和支持,进一步探索MINA的强大功能。