在这篇文章中主要讲解如下内容:
1.mina 简介
1.1 mina 分布图
1.2 mina 组件图
2.例子
2.1 服户端实现
2.2 客户端实现
2.3 日志配置
3.运行结果
1.简介
由于最近项目要用OBD定位车载终端,让其中的数据经过系统分析更人性化的发送到客户的手机、网站中。所以就想到了mina这个东西,通过它来实现现有需求。
mina是个什么东西了?简单介绍下:
Apache的MINA是一个网络应用框架,它可以帮助用户轻松地开发高性能和高可扩展性的网络应用。它提供了一个抽象的事件驱动和通过Java NIO实现的各种传输协议异步API,如TCP / IP和UDP/ IP。
对于mina可以直接到apache官网:http://mina.apache.org/downloads-mina.html 下载
1.1分布图
下面看看mina的分布层图:
通过上图,我们可以看到MINA是界于:你的应用程序(客户端或服务器)和底层的网络层之间。这个网络层它可以基于TCP,UDP或者和一个虚拟机交互。
在开发中,你不用考虑复杂的network层,你只要基于的mina架构上开发你的应用程序就可以了。
1.2 组件图
下面我们们通过mina的内部来更深入的了解细节,可以参看下面的mina架构的组件图:
从广义上讲,基于MINA的应用程序分为3层
I/O服务 - 执行实际I/O
I/O过滤器链 - 过滤器,将字节转换成所需的数据结构或者将数据结构转换成字节
I/O处理器 - 在这里驻留实际的业务逻辑
因此,为了创建一个基于MINA的应用,你必须:
创建I/O服务已经提供的服务(*接受器) - 选择已有的或创建自己的
创建一个过滤器链 - 从已经存在的过滤器中选择或创建自定义过滤器转化的请求/响应
创建一个I/O处理器 - 写业务逻辑,处理不同的消息
下面我们就通过mina的这个原理,来实现一个tcp/ip的服务
2.例子
这个例子需要的基本的jar包有MINA 2.x Core、JDK 1.5 or greater、SLF4J 1.3.0 or greater,如果项目是用maven构建的,引入的包如下所示:
<dependency> <groupId>org.apache.mina</groupId> <artifactId>mina-core</artifactId> <version>2.0.7</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.6.6</version> </dependency>
2.1服务端
首先写一个mina 服务端MinaTcpServer.java
import java.io.IOException; import java.net.InetSocketAddress; import org.apache.mina.core.service.IoAcceptor; import org.apache.mina.core.session.IdleStatus; import org.apache.mina.filter.codec.ProtocolCodecFilter; import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory; import org.apache.mina.filter.logging.LoggingFilter; import org.apache.mina.transport.socket.nio.NioSocketAcceptor; public class MinaTcpServer { private static final int PORT = 9999; /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { /** * 首先,我们需要一个侦听传入连接的对象。由于本程序是基于TCP/IP,所以我们添加一个ScoketAcceptor */ IoAcceptor acceptor = new NioSocketAcceptor(); /** * 添加一个过虑器,用于记录一些信息,例如session的创建、消息接收、消息发送、session关闭 */ acceptor.getFilterChain().addLast("logger", new LoggingFilter()); /** * 再添加一个过滤器,用于将一些二进制信息或者指定的协议数据转换成消息对象,或者将一些发送的消息转换成二进制信息或者指定的协议数据 */ acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter(new ObjectSerializationCodecFactory())); /** * 我们需要定义一个事件处理器,主要是用于处理服务端接收客户端的连接和一些实时的请求。 * 这个事件处理器必须要继承IoHandler接口 */ acceptor.setHandler(new MessageServerHandler()); /** * 下面是配置一些信息,来指定于客户端连接的一些信息设定 */ acceptor.getSessionConfig().setReadBufferSize(2048); acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10); /** * 下面是启动服务,并指定TCP/IP服务监听的端口 */ acceptor.bind(new InetSocketAddress(PORT)); } }
从上面代码中可以看出,服务端需要一个处理事件的类,而这个类需要实现IoHandler接口.在mina的核心包中有个IoHandlerAdapter类,这个类实现了IoHandler接口,但是所有的方法都未进行实际的业务处理。一般在开发中都是基于这个类来实现的.
下面是MessageServerHandler.java的代码:
import org.apache.mina.core.service.IoHandlerAdapter; import org.apache.mina.core.session.IdleStatus; import org.apache.mina.core.session.IoSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class MessageServerHandler extends IoHandlerAdapter { private final static Logger LOGGER = LoggerFactory .getLogger(MessageServerHandler.class); @Override public void messageReceived( IoSession session, Object message ) throws Exception { LOGGER.info("服务端接收消息"); AddMessage message2 = (AddMessage) message; ResultMessage resultMessage = new ResultMessage(); if(message2.getSequence() % 2 == 0){ resultMessage.setOk(true); }else { resultMessage.setOk(false); } resultMessage.setSequence(message2.getSequence()); resultMessage.setValue(message2.getValue()); session.write(resultMessage); LOGGER.info("服务端发送消息"); } }
这个类我主要是重写了消息接收这个方法。对于来处客户端的消息,我将其转换成一个对象AddMessage,然后将这个对象进行处理后转换成ResultMessage对象。最后将转换后的对象通过session.write()方法返回到客户端。
MessageServerHandler.java这个类中用到的两个类,就是两个基本的java bean,因为这两个类需要进行TCP传输,而且在MinaTcpServer.java类中我们添加的数据转换设置是ObjectSerializationCodecFactory这个类,也就是对客户端传来的对象进行序列化。所以,我们需要在创建AddMessage和ResultMessage这两个类时要实现Serializable接口。
为了方便,我先定义一个抽象类来作处理:AbstractMessage.java
import java.io.Serializable; public class AbstractMessage implements Serializable{ /** * */ private static final long serialVersionUID = 1L; private int sequence; public int getSequence() { return sequence; } public void setSequence(int sequence) { this.sequence = sequence; } }
然后看看AddMessage.java代码:
public class AddMessage extends AbstractMessage { /** * */ private static final long serialVersionUID = 1L; private int value; public int getValue() { return value; } public void setValue(int value) { this.value = value; } @Override public String toString(){ return getSequence() + ":ADD(" + value + ")"; } }
ResultMessage.java代码如下所示:
public class ResultMessage extends AbstractMessage { /** * */ private static final long serialVersionUID = 1L; private boolean ok; private int value; public boolean isOk() { return ok; } public void setOk(boolean ok) { this.ok = ok; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } @Override public String toString(){ if(ok){ return getSequence() + ":RESULT(" + value + ")"; }else { return getSequence() + ":RESULT(ERROR)"; } } }
以上就是服务端的代码以及一些po对象,下面来看看客户端的实现
2.2客户端
首先客户端需要定义一个客户端连接的服务SimpleTcpClient.java
import java.net.InetSocketAddress; import org.apache.mina.core.future.ConnectFuture; import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.codec.ProtocolCodecFilter; import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory; import org.apache.mina.filter.logging.LoggingFilter; import org.apache.mina.transport.socket.nio.NioSocketConnector; public class SampleTcpClient { private static final long CONNECT_TIMEOUT = 25000; private static final String HOSTNAME = "127.0.0.1"; private static final int PORT = 9999; private static int[] values = { 1, 2, 3 }; /** * @param args */ public static void main(String[] args) { //客户端建立连接通道 NioSocketConnector connector = new NioSocketConnector(); //设置超时时间 connector.setConnectTimeoutMillis(CONNECT_TIMEOUT); //设置连接时传输数据时的数据转换方式 connector.getFilterChain().addLast( "codec", new ProtocolCodecFilter(new ObjectSerializationCodecFactory())); //记录一些session状态的信息 connector.getFilterChain().addLast("logger", new LoggingFilter()); //设置客户端的处理事件 connector.setHandler(new ClientSessionHandler(values)); IoSession session = null; //绑定到服务中 ConnectFuture future = connector.connect(new InetSocketAddress( HOSTNAME, PORT)); //等待连接服务 future.awaitUninterruptibly(); //获取连接时的session对象 session = future.getSession(); //等待session的关闭 session.getCloseFuture().awaitUninterruptibly(); //关闭session连接 connector.dispose(); } }
对于客户端连接的服务也需要一个客户端的整件处理,它的功能与服务端的事件处理功能是一致的。下面来看看实现的代码.
import org.apache.mina.core.service.IoHandlerAdapter; import org.apache.mina.core.session.IoSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.wy.mina.message.AddMessage; import com.wy.mina.message.ResultMessage; public class ClientSessionHandler extends IoHandlerAdapter { private final static Logger LOGGER = LoggerFactory .getLogger(ClientSessionHandler.class); private final int[] values; private boolean finished; public ClientSessionHandler(int[] values) { this.values = values; } public boolean isFinished() { return finished; } @Override public void sessionOpened(IoSession session) { // 客户端发送消息 for (int i = 0; i < values.length; i++) { AddMessage m = new AddMessage(); m.setSequence(i); m.setValue(values[i]); session.write(m); } } @Override public void messageReceived(IoSession session, Object message) { //接收服务端返回的信息 ResultMessage rm = (ResultMessage) message; if (rm.isOk()) { if (rm.getSequence() == values.length - 1) { // print the sum and disconnect. LOGGER.info("The sum: " + rm.getValue()); session.close(true); finished = true; } } else { LOGGER.warn("Server error, disconnecting..."); session.close(true); finished = true; } } @Override public void exceptionCaught(IoSession session, Throwable cause) { LOGGER.info("client session close....."); session.close(true); } }
通过上面看出,客户端的事件处理,主要是在session打开时,发送信息到服务端,和在服务端返回数据时,以返回的数据进行的处理。
2.3 日志配置
因为在些例子中,我用到了slf4j,所以为了让例子顺利的执行,内存中不能存在任何错误,否则,这个例子将运行不成功(客户端和服务端交互不成功).日志的配置很简单,我们就简单的添加一个日志配置。在maven构建的项目src/main/resources根目录下添加一个log4j.properties,里面的具体内容如下所示:
# Set root logger level to DEBUG and its only appender to A1. log4j.rootLogger=DEBUG, A1 # A1 is set to be a ConsoleAppender. log4j.appender.A1=org.apache.log4j.ConsoleAppender # A1 uses PatternLayout. log4j.appender.A1.layout=org.apache.log4j.PatternLayout log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c{1} %x - %m%n
3.运行
上面就完成了一个TCP/IP的小例子,下面我们就可以运行了.首先运行服务端MinaTimeServer.java类,然后再运行客户端SimpleTcpClient.java类。运行客户端后运行的结果如下所示:
客户端运行结果:
0 [NioProcessor-2] INFO LoggingFilter - CREATED 0 [NioProcessor-2] INFO LoggingFilter - OPENED 11 [NioProcessor-2] INFO LoggingFilter - SENT: 0:ADD(1) 11 [NioProcessor-2] INFO LoggingFilter - SENT: 1:ADD(2) 11 [NioProcessor-2] INFO LoggingFilter - SENT: 2:ADD(3) 21 [NioProcessor-2] DEBUG ProtocolCodecFilter - Processing a MESSAGE_RECEIVED for session 1 31 [NioProcessor-2] INFO LoggingFilter - RECEIVED: 0:RESULT(1) 31 [NioProcessor-2] DEBUG ProtocolCodecFilter - Processing a MESSAGE_RECEIVED for session 1 31 [NioProcessor-2] INFO LoggingFilter - RECEIVED: 1:RESULT(ERROR) 31 [NioProcessor-2] WARN ClientSessionHandler - Server error, disconnecting... 31 [NioProcessor-2] INFO LoggingFilter - RECEIVED: 2:RESULT(3) 31 [NioProcessor-2] INFO ClientSessionHandler - The sum: 3 31 [NioProcessor-2] INFO LoggingFilter - CLOSED
服务端运行结果:
0 [NioProcessor-2] INFO LoggingFilter - CREATED 0 [NioProcessor-2] INFO LoggingFilter - OPENED 21 [NioProcessor-2] INFO LoggingFilter - RECEIVED: HeapBuffer[pos=0 lim=93 cap=2048: 00 00 00 59 AC ED 00 05 73 72 01 00 1E 63 6F 6D...] 21 [NioProcessor-2] DEBUG ProtocolCodecFilter - Processing a MESSAGE_RECEIVED for session 1 31 [NioProcessor-2] INFO MessageServerHandler - 服务端接收消息 31 [NioProcessor-2] INFO MessageServerHandler - 服务端发送消息 31 [NioProcessor-2] INFO LoggingFilter - SENT: HeapBuffer[pos=0 lim=0 cap=0: empty] 31 [NioProcessor-2] INFO LoggingFilter - RECEIVED: HeapBuffer[pos=0 lim=186 cap=2048: 00 00 00 59 AC ED 00 05 73 72 01 00 1E 63 6F 6D...] 31 [NioProcessor-2] DEBUG ProtocolCodecFilter - Processing a MESSAGE_RECEIVED for session 1 31 [NioProcessor-2] INFO MessageServerHandler - 服务端接收消息 31 [NioProcessor-2] INFO MessageServerHandler - 服务端发送消息 31 [NioProcessor-2] INFO MessageServerHandler - 服务端接收消息 31 [NioProcessor-2] INFO MessageServerHandler - 服务端发送消息 31 [NioProcessor-2] INFO LoggingFilter - SENT: HeapBuffer[pos=0 lim=0 cap=0: empty] 31 [NioProcessor-2] INFO LoggingFilter - SENT: HeapBuffer[pos=0 lim=0 cap=0: empty] 41 [NioProcessor-2] INFO LoggingFilter - CLOSED
对于源码,因为项目中还有其它的例子,在这里就不上传了,博客中都将所有的代码粘贴出来了,只要读者一个个拷就可以顺利运行。
相关推荐
它提供了一个统一的API,无论你是在处理TCP/IP协议(如TCP、UDP)还是在处理基于套接字的协议(如SSL/TLS),都可以使用相同的API。Mina在设计时考虑了可扩展性、灵活性和性能,使得开发者能够更专注于业务逻辑,而...
在Android开发中,Mina可以帮助开发者构建TCP/IP和UDP网络应用,尤其适用于实现复杂的服务器与客户端间的通信。本Demo将展示如何在Android手机端使用Mina进行通信,让我们一起深入探讨这个过程。 **1. Mina框架介绍...
在Java平台上,MINA提供了一种统一的方式来处理TCP/IP和UDP/IP协议,使得开发者可以专注于业务逻辑,而不是底层网络编程的细节。 TCP(Transmission Control Protocol)是一种面向连接的、可靠的传输层协议,它通过...
最近使用Mina开发一个Java的NIO服务端程序,因此也特意学习了Apache的这个Mina框架。...它提供了一个抽象的、事件驱动的异步API,使Java NIO在各种传输协议(如TCP/IP,UDP/IP协议等)下快速高效开发
Apache Mina Server 是一个网络通信应用框架,也就是说,它主要是对基于TCP/IP、UDP/IP 协议栈的通信框架(当然,也可以提供JAVA 对象的序列化服务、虚拟机管道通信服务等), Mina 可以帮助我们快速开发高性能、高...
当前发行的MINA版本支持基于Java NIO技术的TCP/UDP应用程序开发、串口通讯程序(只在最新的预览版中提供),MINA所支持的功能也在进一步的扩展中。 Apache MINA是一个网络应用程序框架,可帮助用户轻松开发高性能和...
它提供了一个抽象的、事件驱动的异步API,使Java NIO在各种传输协议(如TCP/IP,UDP/IP协议等)下快速高效开发。 Apache Mina也称为: NIO框架 客户端/服务端框架(典型的C/S架构) 网络套接字(networking...
MINA是Apache软件基金会的一个项目,它提供了一个高度可扩展和高性能的网络应用开发框架,适用于多种传输协议,如TCP/IP和UDP/IP,以及SSL/TLS加密。在大数据传输场景中,MINA因其非阻塞I/O模型而被广泛采用,能够...
Apache Mina Server 是一个网络通信应用框架,也就是说,它主要是对基于TCP/IP、UDP/IP协议栈的通信框架(当然,也可以提供JAVA 对象的序列化服务、虚拟机管道通信服务等),Mina 可以帮助我们快速开发高性能、高...
Apache Mina是一个高性能、异步事件驱动的网络应用程序框架,主要设计用于简化开发网络服务,尤其是TCP/IP协议栈上的服务。Mina的核心理念是提供一套简单而强大的API,让开发者可以专注于业务逻辑,而非底层网络通信...
MINA提供了一种统一的API来处理不同的传输层协议,如TCP/IP、UDP/IP、串口通信以及VM内部的管道,降低了代码的复杂性和重复性。 在TCP/IP方面,MINA支持建立安全的SSL/TLS连接,这对于实现安全的网络通信至关重要。...
Apache Mina Server 是一个网络通信应用框架,也就是说,它主要是对基于TCP/IP、UDP/IP协议栈的通信框架
MINA是一个为高性能网络应用提供高度抽象的Java NIO框架,它简化了网络编程,尤其是TCP/IP和UDP/IP协议的使用。标题中提及的“所需jar”指的是为了运行这个项目所必需的第三方库文件,通常包括MINA框架本身和其他...
MINA2提供了一个抽象层,允许开发者编写与传输协议无关的应用程序,比如TCP/IP和UDP/IP。MINA2的强大之处在于它为开发者提供了异步事件驱动的网络通信框架,免去了处理底层网络编程的复杂性,如多线程管理和数据缓冲...
基于 TCP/IP、UDP/IP协议栈的通信框架 支持串口和虚拟机内部的管道等传输方式 Mina 可以帮助我们快速开发高性能、高扩展性的网络通信应用 Mina 提供了事件驱动、异步操作(JAVA NIO 作为底层支持)的编程模型 本...
Mina不仅支持TCP/IP协议,还支持UDP/IP和其他多种协议,能够帮助开发者快速构建高性能、高并发的网络服务。 Mina的核心特性包括: 1. **非阻塞I/O**:Mina采用了NIO(Non-blocking I/O)模型,允许同时处理大量...
利用 Mina 可以高效地完成以下任务: <br>TCP/IP 和 UDP/IP 通讯 串口通讯 VM 间的管道通讯 SSL/TLS JXM 集成 IoC 容器集成( Spring 、 Pico 等) 状态机 <br>据官方评测, APR 的...
MINA以其事件驱动、非阻塞I/O的核心特性,广泛应用于网络通信领域,包括TCP和UDP协议的客户端与服务器开发。在本篇中,我们将深入探讨如何利用MINA框架来构建一个TCP客户端,并实现长连接。 首先,TCP...
MINA的名字来源于多语言(Multi-purpose Infrastructure for Network Applications),它提供了非阻塞I/O(Non-blocking I/O)的服务,允许开发者构建高性能、高可用性的网络应用,如TCP/IP和UDP通信。MINA的核心...
Apache Mina是一个流行的Java框架,专门用于简化和优化网络应用开发,它支持多种协议如TCP/IP、UDP/IP等,并提供了长连接和短连接的支持。在这个实例中,我们将探讨如何使用Mina实现长连接和短连接。 首先,理解长...