1、滨州学院计算机科学与技术系 seesky 译制我的博客:http:/ MINA、NIO 的第一感觉,以及为什么我们在 NIO 上构建框架。我们还展示了如何运行一个基于MINA 的非常简单的程序例子。1、NIO 综述NIO APIs 在 Java 1.4 中被给出,如今它已经在在大量的程序中被使用了。NIO APIs 允许非阻塞 IO 操作。注意:首先,知道 MINA 是在 NIO 1 的基础上开发的是很重要的,如今在 Java 7 中一个新版本的 NIO-2 已经被设计出来,但是我们还没有从这个版本所带有的特性中获益。注意:知道 N 在 NIO 中的意思是 New 也是重要的,但是我们将在很多
2、地方使用非阻塞( Non-Blocking)这个术语。NIO-2 需要被看为 New New I/Ojava.nio.*包包含以下关键结构 Buffers数据容器 Chartsetsbytes 和 Unicode 之间的翻译容器 Channels代表 I/O 操作的连接实体 Selectors提供可选择的多路复用非阻塞 IO Regexps提供一些操作正则表达式的工具我们将集中关注 MINA 框架的 Channels、Selectors 以及 Buffers 部分,其它部分我们将对用户进行隐藏。本手册将集中关注在这些内部组件上构建我们所需要的系统。NIO vs BIO知道 BIO 和 Cloc
3、king IO 这两种 APIs 之间的不同是很重要的,在阻塞模型中依赖普通的 sockets 链接:当你读、写或者在 socket上做任何操作的时候,被调用的操作将会阻塞调用者,知道操作完成。在一些例子中,关键是能够调用操作,并期望被调用的操作在操作完成之后能够通知调用者:这使得调用者在平均的运行时间里可以做更多的事情。这也就是 NIO 的优点,当你有很多的 socket 链接时,NIO 能帮你更好的处理它们:你不需要为每一个链接创建指定的进程,你只需要使用少量的进程来做同样的事情。如果你想获得有关于 NIO 的更多信息,网上有很多不错的文章,还有几本书讲述了有关 NIO 的问题。2、为什么
4、开发 MINA编写网络程序被看做是繁重的底层开发。它一个开发者不经常学习和知晓的区域,要么是因为很久之前在学校里学过但是现在已经忘了,或者是因为复杂的网络层总是被高层隐藏,总之你没有深入学习过它。另外当涉及到异步 IO 的时候,一个额外的发杂层又参杂了进来:time。BIO(Blocking IO)和 NIO(Non-Blocking IO)之间的最大的区别是,在 BIO 中,你发送一个请求,然后需要一直等待直到你获得答复。在服务器端,这意味着一个进程将会与一个对内连接相联系,所以你不得不处理复杂的多路链接。在 NIO 中,另一方面,你需要解决非阻塞系统的同步工作,这就意味当一些事情发生之后,
5、你的程序将被唤醒。在 NIO 中,你不需要调用和等待结果,你发送完命令之后,之后当恢复准备好了你将获得通知。框架的需求考虑到这些不同,事实上许多的程序都期待在调用网络层的时候有一个阻塞模式,而最好的解决方法就是编写一个模拟阻塞的框架来隐藏这些不同。这就是为什么需要 MINA。但是 MINA 可以做更多。它为使用 TCP、UDP 和其他机制进行通信提供统一的接口。当你只考虑 TCP 和 UDP 的时候,一个是有连接的(TCP),而另外一个是无连接的(UDP)。MINA 掩饰这些不同,使你能够专注于你的程序的两个重要部分:程序的编码以及协议的编码和解码。MINA 不但可以处理 TCP 和 UDP,
6、它还通过 VmpPipe 或 APR 为串口通信(RSC232)提供了一个高层接口。滨州学院计算机科学与技术系 seesky 译制我的博客:http:/ 被特别的设计为能够在客户端和服务器端都能运行的网络框架。编写一个关键是能够扩展的系统,同时在性能和内存使用方面能够符合服务器的要求:这就是 MINA 所擅长的,它使得构建你自己的服务器变得简单。什么时候使用 MINA?这是一个有趣的问题!MINA 在一些情况下并不是最好的选择。当你想要使用 MINA 的时候有几个元素需要考虑。让我们来看看: 当你没有特定的性能环境的时候它是易用的,这个时候 MINA 是一个很好的选择因为它让你更简单的构建一个
7、服务器或客户端,而不用在 BIO 和 NIO 的上层重复编写处理代码和处理各种参数。你甚至能够用简单地 10 行代码完成你的服务器,而且可以避免更少的问题。 一定数量的用户连接 BIO 是比 NIO 快的。不同的是大约 30%支持 BIO。这对于拥有几千条用户连接的系统是正确的,但是在一定程度上,BIO 已经停止扩展了:你不能用一个用户一个进程的方式处理百万级的用户连接!而 NIO 可以。另一方面你在MINA 部分所花费的时间在你整个程序的编码过程中也许并不重要。在一定程度上,编写一个更快的网络层也许并没有什么价值,因为性能基本得不到提升。 在全世界有数万的程序在使用 MINA,这可以证明 M
8、INA 很有用。有很多的 Apache 项目基于 MINA,它们工作的都很好。这也保证了你不用花费数小时的时间来解决你自己的网络层实现中所遇到的奇怪问题了。 MINA 当前支持的已存在协议有:HTTP、XML 、TCP 、LDAP、DHCP 、NTP、DNS、XMPP、SSH、FTP在一定程度上,MINA 不只是一个 NIO 的网络框架,它还是一个带有许多协议实现的网络框架。MINA 的一个未来发展是成为一个你能够使用的各种存在协议的集合。产品特点MINA 是一个简单地同时也是全功能的网络程序开发框架,它提供了以下功能: 为各种传输方式提供了同一个 API:o 基于 NIO 的 TCP/IP
9、& UDP/IPo 基于 RXTX 的串口通信( RS232)o In-VM pipe 通信o 你可以在它上边实现你自己的通信! 作为扩展的过滤器接口;类似于 Servlet 的过滤器 底层和高层 API:o 底层:使用 ByteBufferso 高层:使用用户定义的信息类和编码 可定制的进程模型:o 单线程o 线程池o 多个线程池(SEDA) Out-of-the-box SSL.TLS.StartTLS 支持使用 Java 5 SSLEngine 过载保护和流量节流 模拟对象的单元测试 JMX 可管理性 基于流的 IO 操作:StreamIoHandler 与一些知名的容器集成,例如 Pi
10、coContainer 和 Spring 从 Netty 的平滑迁移, MINA 的祖先滨州学院计算机科学与技术系 seesky 译制我的博客:http:/ MINA 包提供的示例代码为你展示如何简单地使用 MINA。你所要做的第一件事就是在你的程序中使用 MINA 之前配置你的环境。我们将描述你需要安装什么和如何运行 MINA 程序。没什么技巧,只是一个 MINA 的测试下载首先你需要从现在站点现在最新的 MINA 发布包。最好下载最新版,除非你有很好的理由不这样做一般而言,如果你想使用 MINA 构建你自己的项目,你不需要下载什么东西,你只需要将一个 MINA 库包含到你的项目中就可以了:
11、你只需要告诉你的 IDE 你要使用 MINA 的 jar 包就可以了。MINA 库中有什么在你下载完成之后,提取 tar.gz 或 zip 文档中的文件到本地目录。压缩文档中包含了以下内容。在 UNIX 系统中:在 apache-mina-2.0.7 目录中,你能够得到:内容详情 dist包含 MINA 的 jar 包 doce包含 API 文档和代码引用文件 lib包含 MINA 要用到的所有的 jar 库除此之外,根目录还包含 license 文件和其他几个注意文件运行你的第一个 MINA 程序好的,你已经下载了最新的 MINA,让我们来运行 MINA 中附带的示例程序。把以下包加入 cl
12、asspath mina-core-2.0.7.jar mina-example-2.0.7.jar slf4j-api-1.6.6.jar slf4j-log4j12-1.6.6.jar log4j-1.2.17.jar在命令行中输入以下命令:滨州学院计算机科学与技术系 seesky 译制我的博客:http:/ telnet 连接服务器看有什么结果。输入如下 telnet 指令:现在你已经运行了第一个 MINA 程序。请尝试 MINA 中附带的其他示例程序。概要在这一章中,我们看到了基础的 MINA 程序结构,它对于客户端和服务器都适用。我们还涉及到了简单地 TCP 服务器/客户端的实现,还
13、有 UDP 服务器和客户端。在接下来的一章中,我们将会讨论 MINA 的核心结构和一些更高级的话题。第二章基础在第一章中,我们简单地了解了一下 MINA。在这一章中我们将会看到服务器/客户端的结构和一些它们的细节。我们将会展示一些简单地基于 TCP 和 UDP 的服务器和客户端示例。基于 MINA 的应用程序结构我们也可以这样问:“一个基于 MINA 的程序看起来是什么样子的?”在这一章中,让我们来看一看基于 MINA 的程序的结构。我们试图从 MINA 演示中搜集信息。鸟瞰图:在这我们看到 MINA 是你的程序(客户端或服务器)与网络层之间的粘合剂,而程序的底层可以是基于 TCP、UDP、i
14、n-VM 连接,甚至是 RS-232C 串口协议的连接。你只需要在 MINA 的上层构建你的应用而不需要处理复杂的网络层问题。让我们更深入细节一些。下边的图片展示了 MINA 的组成,并写出了每部分做功能:滨州学院计算机科学与技术系 seesky 译制我的博客:http:/ MINA 的程序分为三层: I/O 服务实际执行 I/O 操作 I/O 过滤器链对所需的数据就够进行过滤/翻译,反之亦然 I/O 处理这里包含着真正的业务逻辑所以,为了构建一个基于 MINA 的程序,你需要: 创建 I/O 服务从已有服务器选择一个或者创建你自己的 创建过滤器链选择已经存在的过滤器或者是定义用户转换请求 /
15、回复的过滤器 创建处理器编写业务逻辑,处理不同的信息你可以通过阅读以下两个文件更深入的了解这方面的内容: 服务器结构 客户端结构当然,MINA 提供了比这更多的功能,你还需要注意其他的一些方面,像信息的编码/解码,网络配置的扩展等我们将在下一张进一步讨论这些问题。服务器结构在上一小节我们已经展示了 MINA 程序的结构。接下来让我们看一下服务器的结构。基本上,一个服务器要在特定的端口上监听客户端的请求,处理这些请求并作出回复。同时它需要创建和处理与每一个客户端之间的连接(不管你使用的是 TCP 还是 UDP 协议),这些将在第四章中有更详细的解说。滨州学院计算机科学与技术系 seesky 译制
16、我的博客:http:/ IOAcceptor 监听来自网络的连接和数据包 对于一个新的连接,一个对话将会被建立,同时随后来自于这个 IP 地址和端口的通信都将通过这个回话进行处理 对一个会话的所有数据包,都会穿过如图所示的过滤器链。过滤器可以被用来修改数据包的内容(例如转换对象、添加或者删除信息等)。这对于为高层对象转化进出的比特数据,以及对数据的编码和解码是特别有用的。 最后数据包或转化的对象将被放在 IOHandler 中。IOHandler 在整个业务逻辑过程中都可以被使用。会话的创建无论什么时候一个客户端连接到 MINA 服务器,我们都会创建一个会话并把固定的数据保存在里边。及时协议不
17、是面向连接的,这个会话也会被创建。下边的架构图展示了 MINA 如何处理对内的连接:图挂了!对内信息的处理我们现在解释了 MINA 如何处理队内的信息。假设对话已经被建立,当一些新的信息到来的时候,它将会导致一个选择器被唤醒。简单地 TCP 服务器快速开始手册滨州学院计算机科学与技术系 seesky 译制我的博客:http:/ MINA 程序。此手册将会构建一个时间服务器。本手册需要以下预备知识: MINA 2.0.7 核心 JDK 1.5 或更高版本 SLF4 1.3.0 或更高版本o Log4J 1.2 users: slf4j-api.jar, slf4j-log4j12.jar, an
18、d Log4J 1.2.xo Log4J 1.3 users: slf4j-api.jar, slf4j-log4j13.jar, and Log4J 1.3.xo java.util.logging users: slf4j-api.jar and slf4j-jdk14.jaro 重要:请确保对你的日志框架使用了正确的 slf4j-*.jar 版本。例如, slf4j-log4j12.jar 和 log4j-1.3.x.jar 不能同时使用,将会出现问题。我已经在 Window 2000 系统和 Linux 系统上测试了这个程序。如果你再运行这个程序的时候有什么问题,请不要犹豫,联系我们或
19、告诉其他的开发者。并且,本手册已经尽量独立于特定的开发环境(IDE、编辑器等)。这个手册将在你熟悉的开发环境中运行的很好。这个程序的编译命令和执行命令已经被剔除的很简洁。如果你需要学习如何编译和运行程序,请查看其他 java 手册。编写 MINA 时间服务器我们将要建立一个叫做 MinaTimeServer.java 的文件。起始代码如下所示:public class MinaTimeServer public static void main(String args) / code will go here next代码就是如此。我们简单地定义了一个用于启动程序的 main 方法。接下来,我
20、们将会添加用于代码来弥补我们的服务器。首先,我们需要一个用来监听外来连接的端口。这个程序将基于 TCP/IP,我们将向程序中添加一个 SocketAcceptor。通过这个 NioSocketAcceptor 类,我们可以继续前进来定义一个处理类同时将 NioSocketAcceptor 绑定到一个端口上。接下来我们给配置添加一个过滤器。这个过滤器将会把所有的信息写入日志中,例如新 session 的创建、信息的获取、信息的发送、session 的关闭。下一个过滤器是 ProtocolCodecFilter。这个过滤器将会把二进制或符合协议规范的数据翻译成消息对象,反之亦然。我们使用一个已经存
21、在的 TextLine 工厂,它将会为你处理关于 text 的信息(这样你就不用自己写代码了)。滨州学院计算机科学与技术系 seesky 译制我的博客:http:/ IoHandler接口的类。对于所有使用 MINA 的程序来说,这个处理器将是最主要的程序,它将为接入的所有客户端提供服务。对于本手册来说,我们将继承 IoHandlerAdapter 类。这个类遵循适配器模式,它简化了大量为满足实现 IoHandler 接口的类所需要的代码。现在我们将会添加 NioSocketAcceptor 配置。这将使得我们可以对 socket 进行特定的设置,此 socket 将被用来接受客户端的连接。滨
22、州学院计算机科学与技术系 seesky 译制我的博客:http:/ MinaTimeServer 类中有两个新行。这些方法设置了 IoHandler 的设置,输入缓冲区大小和会话的空闲性能。缓冲区的尺寸将被指定,它将通知潜在的操作系统应该为输入的数据分配多少空间。第二行指定多长时间监测空闲会话。在调用 setidleTime 的时候,第一个参数定义了当检测到会话空闲的时候要做什么,第二个参数定义了判定会话为空闲的时长。处理器类的代码如下所示:滨州学院计算机科学与技术系 seesky 译制我的博客:http:/ exceptionCaught、messageReceived 和 sessioni
23、dle。exceptionCaught 总会在一个处理器类中被实现,它将处理远程连接过程中产生的异常。如果这个方法没有被定义,异常将不能得到正确的处理。exceptionCaught 方法将简单地输出错误堆栈的信息,并关闭会话。对于大多数程序来说,这将是基本的实践,除非处理器类能从异常中恢复过来。messageReceived 方法将接受来自客户端的数据同时将当前时间写回给客户端。当从客户端接收到的信息是“quit”,则会话将被关闭。这个方法将向客户端打印当前时间。依赖你所使用的协议编码器,在第二个方法中传输的对象将会不同,它将会是你在session.write(Object)方法中传输的对象
24、。如果你没有指定协议编码器,你将接收到一个 IoBuffer 对象,并回复一个 IoBuffer 对象。sessionidle 方法将会在会话被确定为空闲后执行,这段空闲时间我们已经使用 acceptor.getSessionConfig().setidleTime(idleStatus.BOTH_IDLE, 10)中进行了设置。接下来所要做的就是定义一个 socket 地址,用于服务器的监听,然后启动服务器。代码如下:滨州学院计算机科学与技术系 seesky 译制我的博客:http:/ telnet 连接它:简单地 TCP 客户端我们已经看过了客户端的结构。接下来让我们看一下一个客户端的实现
25、。我们用一个 Sumup Client 作为参考实现。我们将删除样板代码并把注意力集中在一些重要的结构上,以下是客户端的代码:滨州学院计算机科学与技术系 seesky 译制我的博客:http:/ 创建一个 Connector 创建一个过滤器链 创建一个 IOHandler 并添加 Connector 绑定到服务器下面让我们详细的说明每一步。创建一个 Connector在这我们创建了一个 NIO socket 连接。创建一个过滤器链滨州学院计算机科学与技术系 seesky 译制我的博客:http:/ Connector 将过滤器添加到过滤器链中。这里我们将 ProtocolCodec 添加到了过
26、滤器链中。创建一个 IOHandler在这里我们创建了一个 ClientSessionHandler 的示例,并将其配置到 Connector 上。绑定服务器这是很重要的部分。我们连接远程服务器。至此,连接是个异步任务,我们使用 ConnectFuture 类确定什么时候连接完成。一旦连接完成,我们将得到连接 IoSession。为了向服务器发送信息,我们需要向这个 session 中写数据。所有来自服务器的回复和信息将会穿过过滤器链并最终在 IoHandler 中得到处理。简单地 UDP 服务器我们来看看 org.apache.mima.example.udp 包中的代码。为了让示例简单,我
27、们只简述 MINA 的内容。为了构造服务器,我们需要做下边的事情: 创建一个数据包 Socket 用来监听来自客户端的请求(看 MemoryMonitor.java) 创建一个 IoHandler 来处理 MINA 框架的事件(看 MemoryMonitorHandler.java)以下是一个小片段:在这,我们创建了一个 NioDatagramAcceptor 来监听来自客户端的请求,同时设置 IoHandler。变量“PORT”只是一个 int 型数据。下一步是为 DtagramAcceptor 添加要使用的日志过滤器。用 LoggingFilter 查看 MINA 是如何活动的是一种很好的
28、方法。它在不同的阶段产生日志文档,提供了 MINA 如何工作的例证。滨州学院计算机科学与技术系 seesky 译制我的博客:http:/ UDP 传输的特殊代码。我们将会设置这个 acceptor 使用这个地址:当然我们需要做的最后的事情就是调用 bind()函数。IoHandler 的实现有三个主要事件是我们的服务器实现所感兴趣的: 会话创建 信息接收 会话关闭让我们分别看看它们的详情。会话创建事件在会话的创建事件中,我们只是调用了 addClient()函数,它在 UI 上添加了一个标签。信息接收事件在信息接收事件中,我们只是将接收到的信息全部送入 message 中。程序能够使用这个函数
29、发送回复、处理信息并把回复写入会话中。会话关闭事件滨州学院计算机科学与技术系 seesky 译制我的博客:http:/ UI 上移除了。简单地 UDP 客户端让我们看看 UDP 客户端的代码。为了实现这个客户端,我们需要做下边的事情: 为服务器创建 Socket 和 Connect 设置 IoHandler 收集空闲内存 向服务器发送数据我们先来看 MemMonClient.java,它在 org.apache.mina.example.udp.clent 包中。开始的一段代码直截了当:在这我们创建了一个 NioDatagramConnector,为服务器配置了 handler 和 conne
30、ct。我遇到的一个问题是你必须在InetSocketAddress 对象中设置主机或者别的什么工作。这个例子是在 Windows XP 上进行测试的,所以一些工作在其他地方可能会不同。接下来我们需要等待确认客户端连接到了服务器。一旦连接成功,我们可以开始等待来自服务器的数据。代码如下:在这里我们为 ConnectFuture 对象添加了一个监听器,当我们获得一个客户端已经连接的回调时,我们就开始写数据。向服务器写入的数据通过调用 sendData 函数来处理。这个方法的代码如下:滨州学院计算机科学与技术系 seesky 译制我的博客:http:/ 30 秒就会将大量空闲内存写给服务器。在这里我
31、们可以看到,我们分配了一个足够大的 IoBuffer 用来保存一个长变量然后把大量的空闲内存放入这个 buffer 中。随后这个 buffer 将会被遍历并写给服务器。我们的 UDP 客户端实现就完成了。概述在这一章中,我们看了基于 MINA 的程序的结构,包括客户端和服务器。同时我们涉及到了简单 TCP 服务器客户端和 UDP 服务器客户端的实现。在接下来的一章中,我们将会讨论 MINA 核心结构和高级主题。第三章IoServiceMINA IoService它是所有 IO 服务的基础类,包括服务器端和客户端。它将处理所有与你的程序之间的互动,发送和接收信息,管理会话,连接等。它是一个接口,
32、它在服务器端有 IoAcceptor 实现,在客户端有 IoConnector 的实现。我们将会在接下来的章节中介绍这些接口:IoService 介绍IoService 在 MINA 中提供了基本的 I/O 服务和 I/O 会话管理服务。它是 MINA 结构中最重要的部分。IoService 的实现类和子接口是绝大多数底层 I/O 操作进行的地方。IoService 思维导图让我们来看看 IoService 和她的实现类 AbstractIoService 类的职责。让我们用一种稍微不同的方式,先使用思维导图然后再跳进内部的工作过程。思维导图是由 XMind 创建的。职责在给出的图像中可以看出
33、,IoService 有以下职责: 会话管理:创建和删除会话,检测空闲情况 过滤器链管理:处理过滤器链,允许用户在工作过程中修改过滤器链 处理调用:当收到信息的时候调用处理器,等 统计管理:更新信息发送、bytes 和其他数据的发送数量滨州学院计算机科学与技术系 seesky 译制我的博客:http:/ 监听器管理:管理用户可以设置的监听器 连接管理:在两个方向处理数据的传输这所有的方面在接下来的章节中将被描述。接口细节IoService 是所有 IoConnector 和 IoAcceptor 所提供的 I/O 服务和 I/O 对话管理的基础接口。这个接口包含了所有用于 I/O 相关操作的函
34、数。让我们来深入的看一下这个接口中的各种函数 getTransportMetadata() addListener() removeListener() isDisposing() isDisposed() dispose() getHandler() setHandler() getManagedSessions() getManagedSessionCount() getSessionConfig() getFilterChainBuilder() setFilterChainBuilder() getFilterChain() isActive() getActivationTime()
35、 broadcast() setSessionDataStructureFactory() getScheduledWriteBytes() getScheduledWriteMessages() getStatistics()getTransportMetadata()这个方法返回 IoAcceptor 或 IoConnector 运行过程中的传输元数据。典型细节包括名字(nio、apr、rxtx ),连接类型(无连接/有连接)等。addListener允许添加一个用于监听与 IoService 有关的事件的指定监听器。removeListener移除绑定在这个 IoService 的指定的
36、 IoServiceListener。isDisposing这个方法将告知这个 service 当前正在被处理。由于它会花费一些时间,所以获得 service 的当前状态是很有用的。isDisposed滨州学院计算机科学与技术系 seesky 译制我的博客:http:/ service 已经被处理过了。只有当 service 申请的所有资源全部被释放的时候,它才被认为处理过了。dispose这个方法将释放所有 service 所申请的资源。由于它会花费一些时间,所以用户需要使用 isDisposing()和 isDisposed()来检测当前的service 是否已经被处理完成了。当你关闭一个
37、 service 的时候一定要调用 dispose()。getHandler返回 service 所申请的 IoHandler。setHandler设置用于处理所有事件的 IoHandler。这个 handler 将包含你的程序逻辑!getManagedSeesions返回当前由这个 service 管理的所有对话所组成的一个 map。被管理的会话是那些被加入 service 监听器的会话。它将被用来处理空闲的会话和其他的会话,这基于用户加入监听器的会话的类型。getManagedSessionCount返回当前由这个 service 所管理的会话的数量。getSessionConfig返回对
38、话配置。getFilterChainBuilder返回过滤器链创建者。如果想在会话建立的时候向其中添加新的过滤器,这个函数将是很有用的。getFilterChain返回当前这个 service 的默认过滤器链。isActive告知当前 service 是活动的还是不活动的。getActivationTime当 service 获得的时候返回活动时间。当 service 已经不在活动的时候,这个函数将返回它最后一次活动的时间。broadcast向 service 管理的所有会话发送信息。setSessionDataStructureFactory这个方法将设置 IoSessionDataStru
39、ctureFactory,此工厂将为当前 service 所创建的会话提供相关数据结构。getScheduledWriteBytes返回将要写的比特数(这些比特保存在内存中,它们等待着 socket 的写)。getScheduledWriteMessages返回将要写的信息数(这些信息保存在内存中,它们等待着 socket 的写)。滨州学院计算机科学与技术系 seesky 译制我的博客:http:/ service 返回 IoServiceStatistics 对象。IoService 细节IoService 在 MINA 中被两个非常重要的类所实现: IoAcceptor IoConnect
40、or为了构建一个服务器,你需要选择一个 IoAccrptor 接口的实现。为了构建一个客户端,你需要一个 IoConnector 接口的实现。IoAcceptor基本上这个接口被这样命名是因为 accept()方法,它负责在一个服务器和客户端之间创建链接。服务器结构对内的请求。在一些情况下,我们可以将这个借口命名为“Server”(这个新的名字来自 MINA 3.0)。我们有很多的方式来完成传输任务(TCP/UDP),所以对于这个接口也有多个实现。它不大可能需要你自己写一个实现。我们对它有以下实现类: NioSocketAcceptor:非阻塞的 Socket 传输 IoAcceptor Ni
41、oDatagramAcceptor:非阻塞的 UDP 传输 IoAcceptor AprSocketAcceptor:阻塞的 Socket 传输 IoAcceptor,基于 APR VmPipeSocketAcceptor:in-VM IoAcceptor只需要选择一个你需要的。以下是 IoAcceptor 的实现类图解:滨州学院计算机科学与技术系 seesky 译制我的博客:http:/ Acceptor首先你要选择你需要的 IoAcceptor 的实例类型。你的这个选择将决定你在后期使用什么样的网络协议。让我们来看一个它是如何工作的示例:就是这样!你已经创建了一个 TCP 服务器。如果你想
42、创建一个 UDP 服务器,你只需要简单地更换第一行代码:滨州学院计算机科学与技术系 seesky 译制我的博客:http:/ dispose()方法停止。服务器只有在所有挂起的会话都被解决之后才会停止:你也可以通过向这个方法传送一个 loolean 值然后等待所有的线程都被执行:状态你可以通过调用以下方法获得 IoService 的状态: isActive():如果服务可以接受请求则值为 true isDisposing():当 dispose()方法已经被执行过则它返回 true。当服务已经停止的话它将没有返回值(一些会话可能已经被执行了)。 isDisposed():当 dispose(b
43、oolean)方法已经被执行则它返回 true,此时处理的线程已经完成了。管理 IoHandler如果服务实例化后你可以向其添加 IoHandler 或获取与其绑定的 IoHandler。你只需要调用 setHandler(IoHandler)或 getHandler()方法。管理过滤器链如果你想要管理过滤器链,你需要调用 getFilterChain()方法。以下是一个例子:你也可以事先创建一个过滤器链,然后再将它加入服务:IoConnector就如我们需要 IoAcceptor 来构建服务器,你需要为客户端实现 IoConnector 接口。同样,我们已经有了很多实现类: NioSocke
44、tConnector: 非阻塞的 Socket 传输 IoConnector NioDatagramconnector: 非阻塞的 UDP 传输 IoConnector AprSocketConnetor:阻塞的 Socket 传输 IoConnector,基于 APR ProxyConnector:一个提供代理支持的 IoConnector SerialConnector:一个提供串口传输功能的 IoConnector VmPipeConnector:in-Vm IoConnector滨州学院计算机科学与技术系 seesky 译制我的博客:http:/ IoConnector 的实现类图解:
45、第四章会话会话是 MINA 的核心:每当客户端连接到服务器,一个新的会话就会被建立,它会被保存在内存中直到客户端断开连接。会话用来保存与链接相关的固定信息,外加一些服务器恢复客户端请求时所要用到的信息,还有在整个会话生存期中有用的信息。会话状态会话有它自己的状态,这种状态会不断的变化。 已连接的:会话已经被创建并且可用 空闲:这个回话在一段时间(这段时间是可配置的)里没有处理任何请求o 读空闲:在一段时间里没有读操作o 写空闲:在一段时间里没有写操作o 全部空闲:在一段时间里没有读写操作 正在关闭:会话正在被关闭(剩余的信息将被刷新清理,会话将被终止) 已关闭:会话已经被关闭了,不能再通过它做任何事情下边的图片展示了所有的状态以及他们之间的转化关系:滨州学院计算机科学与技术系 seesky 译制我的博客:http:/ 接收缓存的大小 发送缓存的大小 空闲时间 写超时时间还有一些其他的配置,它们将依赖于所使用的传输协议类型(看第六章 传输协议)管