mina入门学习

本文介绍了Apache MINA框架,包括其特点、主要类介绍及开发示例。MINA简化了网络应用开发过程,提供了高可维护性和可复用性的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、 MINA简介
Apache MINA(Multipurpose Infrastructure for Network Applications)发行的 MINA 版本支持基于 Java NIO 技术的 TCP/UDP 应用程序开发、串口通讯程序。 MINA是一个网络应用框架,在不牺牲性能和可扩展性的前提下用于解决如下问题:
1)快速开发自己的应用
2)高可维护性、高可复用性:网络I/O编码,消息的编码/解码、业务逻辑互相分离
3)相对容易的进行单元测试

2、 原理图(对象传送):
[img][/img]
[img]http://dl.iteye.com/upload/attachment/279587/c9e289d0-4c27-3032-9be2-c1c7900fb790.png[/img]


3、 MINA主要类介绍
1)IoFilters: IoFilter为MINA的功能扩展提供了接口。它拦截所有的IO事件进行事件的预处理和后处理(AOP)。我们可以把它想象成Servlet的filters。IoFilter能够实现以下几种目的:事件日志、性能检测、数据转换(e.g. SSL support),codec防火墙…等等。
2)codec: ProtocolCodecFactory
MINA提供了方便的Protocol支持。如上说讲,codec在IoFilters中设置。通过它的Encoder和Decoder,可以方便的扩展并支持各种基于Socket的网络协议,比如HTTP服务器、FTP服务器、Telnet服务器等等。
要实现自己的编码/解码器(codec)只需要实现interface: ProtocolCodecFactory即可.在MINA 1.0版本,MINA已经实现了几个常用的(codec factory):
DemuxingProtocolCodecFactory,
NettyCodecFactory,
ObjectSerializationCodecFactory,
TextLineCodecFactory
3)business logic: IoHandler
MINA中,所有的业务逻辑都有实现了IoHandler的class完成
interfaceHandles:
all protocol events fired by MINA. There are 6 event handler methods, and they are all invoked by MINA automatically.
当事件发生时,将触发IoHandler中的方法:
sessionCreated(),
sessionOpened(),
sessionClosed(),
sessionIdle(),
exceptionCaught(),
messageReceived(),
messageSent()

4) MINA的高级主题:线程模式
MINA通过它灵活的filter机制来提供多种线程模型。
没有线程池过滤器被使用时MINA运行在一个单线程模式。
如果添加了一个IoThreadPoolFilter到IoAcceptor,将得到一个leader-follower模式的线程池。
如果再添加一个ProtocolThreadPoolFilter,server将有两个线程池;
一个(IoThreadPoolFilter)被用于对message对象进行转换,另外一个(ProtocolThreadPoolFilter)被用于处理业务逻辑。
SimpleServiceRegistry加上IoThreadPoolFilter和ProtocolThreadPoolFilter的缺省实现即可适用于需
要高伸缩性的应用。如果想使用自己的线程模型,请参考SimpleServiceRegistry的源代码,并且自己初始化Acceptor。
MINA 1.O中,IoHandler的实现类:
ChainedIoHandler,
DemuxingIoHandler,
IoHandlerAdapter,
SingleSessionIoHandlerDelegate,
StreamIoHandler


具体细节可参考javadoc。

4、 MINA开发示例
首先到apache下载相关文件,最新版是2.0,最新稳定版是1.7。导入全部jar包至工程

开发的一般步骤:
1)、 客户端建立连接: IoAcceptor acceptor = new SocketAcceptor();//建立client连接或者
SocketConnector connector = new SocketConnector();
2)、 Server段的属性配置
3)、 绑定address和business Logic

5、 Demo源代码
Client.java
[/code]

import java.net.InetSocketAddress;

import org.apache.mina.common.IoSession;
import org.apache.mina.filter.LoggingFilter;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.transport.socket.nio.SocketConnector;
import org.apache.mina.transport.socket.nio.SocketConnectorConfig;

public class Client
{
private static final String HOSTNAME = "localhost";
private static final int PORT = 8080;
private static final int CONNECT_TIMEOUT = 30; // seconds


public static void main( String[] args ) throws Throwable
{
SocketConnector connector = new SocketConnector();
// Configure the service.
SocketConnectorConfig cfg = new SocketConnectorConfig();
cfg.setConnectTimeout( CONNECT_TIMEOUT );
cfg.getFilterChain().addLast(
"codec",
new ProtocolCodecFilter( new ObjectSerializationCodecFactory() ) );

cfg.getFilterChain().addLast( "logger", new LoggingFilter() );

IoSession session;
Message msg = new Message(0,1,"hello");
connector.connect(new InetSocketAddress( HOSTNAME, PORT ),
new ClientSessionHandler(msg), cfg );

}
}


ClientSessionHandler.java
[code="java"]


import org.apache.mina.common.IoHandlerAdapter;
import org.apache.mina.common.IoSession;
import org.apache.mina.util.SessionLog;

public class ClientSessionHandler extends IoHandlerAdapter
{
private Object msg;

public ClientSessionHandler(Object msg)
{
this.msg = msg;
}


public void sessionOpened( IoSession session )
{
session.write(this.msg);
}

public void messageReceived( IoSession session, Object message )
{
System.out.println("in messageReceived(Client)");
Message rm = (Message ) message;
SessionLog.debug(session, rm.getMsgBody());
System.out.println("message is: " + rm.getMsgBody());
session.write(rm);
}

public void exceptionCaught( IoSession session, Throwable cause )
{
session.close();
}
}


传输的对象Message.java
[/code]

import java.io.Serializable;

public class Message implements Serializable {

private int type;
private int status;
private String msgBody;

public Message(int type, int status, String msgBody)
{
this.type = type;
this.status = status;
this.msgBody = msgBody;
}

public String getMsgBody() {
return msgBody;
}

public void setMsgBody(String msgBody) {
this.msgBody = msgBody;
}

public int getStatus() {
return status;
}

public void setStatus(int status) {
this.status = status;
}

public int getType() {
return type;
}

public void setType(int type) {
this.type = type;
}
}

Server.java
[code="java"]


import java.net.InetSocketAddress;

import org.apache.mina.common.IoAcceptor;
import org.apache.mina.filter.LoggingFilter;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.transport.socket.nio.SocketAcceptor;
import org.apache.mina.transport.socket.nio.SocketAcceptorConfig;

public class Server
{
private static final int SERVER_PORT = 8080;

public static void main( String[] args ) throws Throwable
{
IoAcceptor acceptor = new SocketAcceptor();

// Prepare the service configuration.
SocketAcceptorConfig cfg = new SocketAcceptorConfig();
cfg.setReuseAddress( true );

cfg.getFilterChain().addLast(
"codec",
new ProtocolCodecFilter( new ObjectSerializationCodecFactory() ) );
cfg.getFilterChain().addLast( "logger", new LoggingFilter() );

acceptor.bind(
new InetSocketAddress( SERVER_PORT ),
new ServerSessionHandler( ), cfg );

System.out.println( "The server Listening on port " + SERVER_PORT );
}
}


ServerSessionHandler.java
[code="java"][/code]

import org.apache.mina.common.IdleStatus;
import org.apache.mina.common.IoHandlerAdapter;
import org.apache.mina.common.IoSession;
import org.apache.mina.util.SessionLog;

public class ServerSessionHandler extends IoHandlerAdapter
{
public void sessionOpened( IoSession session )
{
// set idle time to 60 seconds
session.setIdleTime( IdleStatus.BOTH_IDLE, 60 );
session.setAttribute("times",new Integer(0));
}

public void messageReceived( IoSession session, Object message )
{
System.out.println("in messageReceived(Server)");
int times = ((Integer)(session.getAttribute("times"))).intValue();
System.out.println("tiems = " + times);
// communicate 30 times,then close the session.
if (times < 30)
{
times++;
session.setAttribute("times", new Integer(times));
Message msg;
msg = (Message) message;
msg.setMsgBody("in server side: " + msg.getMsgBody());
System.out.println("begin send msg: " + msg.getMsgBody());
session.write(msg);
}
else
{
session.close();
}
}

public void sessionIdle( IoSession session, IdleStatus status )
{
SessionLog.info( session, "Disconnecting the idle." );
// disconnect an idle client
session.close();
}

public void exceptionCaught( IoSession session, Throwable cause )
{
// close the connection on exceptional situation
session.close();
}
}

5、 Demo异常处理
不出意外的话, 你运行程序会抛出如下异常:
Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
at org.apache.mina.util.NamePreservingRunnable.<init>(NamePreservingRunnable.java:32)
at org.apache.mina.transport.socket.nio.SocketAcceptor.startupWorker(SocketAcceptor.java:165)
at org.apache.mina.transport.socket.nio.SocketAcceptor.bind(SocketAcceptor.java:141)
at com.apusic.mina.Server.main(Server.java:29)
Caused by: java.lang.ClassNotFoundException: org.slf4j.LoggerFactory
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 4 more

导入slf4j-api-1.5.2.jar解决

抛出新异常:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/impl/StaticLoggerBinder
at org.slf4j.LoggerFactory.<clinit>(LoggerFactory.java:60)
at org.apache.mina.util.NamePreservingRunnable.<init>(NamePreservingRunnable.java:32)
at org.apache.mina.transport.socket.nio.SocketAcceptor.startupWorker
(SocketAcceptor.java:165)
at org.apache.mina.transport.socket.nio.SocketAcceptor.bind(SocketAcceptor.java:141)
at com.apusic.mina.Server.main(Server.java:29)
Caused by: java.lang.ClassNotFoundException: org.slf4j.impl.StaticLoggerBinder
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 5 more
导入slf4j-nop-1.5.2.jar解决
所需的两个jar见附件

6、 使用socket重写(不使用框架版, 待下回分解)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值