Apache MINA简单介绍及其使用

来源:互联网 发布:淘宝收货了还能退货吗 编辑:程序博客网 时间:2024/05/18 21:43

Apache MINA简单介绍及其使用

1、简单介绍

首先,Mina是个什么东西?看下官方网站(http://mina.apache.org/)对它的解释:Apache的Mina(Multipurpose Infrastructure Networked Applications)是一个网络应用框架,可以帮助用户开发高性能和高扩展性的网络应用程序;它提供了一个抽象的、事件驱动的异步API,使Java NIO在各种传输协议(如TCP/IP,UDP/IP协议等)下快速高效开发。
  Apache Mina也称为:

  • NIO框架
  • 客户端/服务端框架(典型的C/S架构)
  • 网络套接字(networking socket)类库
  • 事件驱动的异步API(注意:在JDK7中也新增了异步API)
    总之:我们简单理解它是一个封装底层IO操作,提供高级操作API的通讯框架!

2、基本框架

MINA框架图
MINA框架图

Mina的通信流程大致如上图所示,各个组件功能有:
(1) IoService:这个接口在一个线程上负责套接字的建立,拥有自己的Selector,监
听是否有连接被建立。
(Mina底层使用Java NIO, 因此它是典型的使用Reactor模式架构的,采用事件驱动编程 , Mina运行用户自定义线程模型,可以是单线程、多线程、线程池等 ,
跟JAVA Socket不一样, Mina是非阻塞的Socket,它内部已经保证了对各个连接(session)的业务和数据的隔离,采用轮询机制为各个session分配CPU资源,
  所以,你就不需要再去考虑不同Socket连接需要用不同的线程去操纵的问题了。)
(2) IoProcessor:这个接口在另一个线程上负责检查是否有数据在通道上读写,也就是
说它也拥有自己的Selector,这是与我们使用JAVA NIO 编码时的一个不同之处,
通常在JAVA NIO 编码中,我们都是使用一个Selector,也就是不区分IoService
与 IoProcessor 两个功能接口。另外,IoProcessor 负责调用注册在IoService 上
的过滤器,并在过滤器链之后调用IoHandler。

(3) IoFilter:这个接口定义一组拦截器,这些拦截器可以包括日志输出、黑名单过滤、
数据的编码(write 方向)与解码(read 方向)等功能,其中数据的encode 与 decode
是最为重要的、也是你在使用Mina 时最主要关注的地方。

(4) IoHandler:这个接口负责编写业务逻辑,也就是接收、发送数据的地方。

3、MINA示例实现

1、依赖包

  • log4j.jar
  • mina-core-2.0.4.jar
  • slf4j-api-1.6.3.jar
  • slf4j-log4j12-1.6.3.jar

2、示例代码

MinaTimeServer.java

import java.io.IOException;import java.net.InetSocketAddress;import java.nio.charset.Charset;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.textline.TextLineCodecFactory;import org.apache.mina.filter.logging.LoggingFilter;import org.apache.mina.transport.socket.nio.NioSocketAcceptor;/** */public class MinaTimeServer {                // 服务器监听端口    private static final int PORT = 8888;    /**     *      */    public MinaTimeServer() {        // TODO Auto-generated constructor stub    }    /**     * @param args     */    public static void main(String[] args) {        // 服务器端的主要对象        IoAcceptor acceptor = new NioSocketAcceptor();        // 设置Filter链         acceptor.getFilterChain().addLast("logger", new LoggingFilter());        // 协议解析,采用mina现成的UTF-8字符串处理方式        acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));        // 设置消息处理类(创建、关闭Session,可读可写等等,继承自接口IoHandler)        acceptor.setHandler(new TimeServerHandler() );        // 设置接收缓存区大小        acceptor.getSessionConfig().setReadBufferSize(2048);        acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);        try {            // 服务器开始监听            acceptor.bind( new InetSocketAddress(PORT) );        }catch(Exception e){            e.printStackTrace();        }    }}

TimeServerHandler.java

import org.apache.mina.core.service.IoHandlerAdapter;import org.apache.mina.core.session.IdleStatus;import org.apache.mina.core.session.IoSession;import java.util.Date;/** * 服务器端业务逻辑 *//** * 继承自IoHandlerAdapter,IoHandlerAdapter继承接口 IoHandler        类IoHandlerAdapter实现了IoHandler的所有方法,只要重载关心的几个方法就可以了 */public class TimeServerHandler extends IoHandlerAdapter {    @Override    public void exceptionCaught(IoSession session, Throwable cause)            throws Exception {        cause.printStackTrace();    }    /*     * 这个方法是目前这个类里最主要的,     * 当接收到消息,只要不是quit,就把服务器当前的时间返回给客户端     * 如果是quit,则关闭客户端连接*/    @Override    public void messageReceived(IoSession session, Object message)            throws Exception {        String str = message.toString();        if (str.trim().equalsIgnoreCase("quit")) {            session.close();            return;        }        Date date = new Date();        System.out.println("hello"+str+session.getRemoteAddress()+date.toString());        session.write("i am recived");        System.out.println("Message written...");    }    @Override    public void sessionClosed(IoSession session) throws Exception {        // TODO Auto-generated method stub        super.sessionClosed(session);        System.out.println("客户端与服务端断开连接.....");    }}

MinaTimeClient.java

import java.net.InetSocketAddress;   import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;   import org.apache.mina.core.future.ConnectFuture;   import org.apache.mina.filter.codec.ProtocolCodecFilter;   import org.apache.mina.filter.codec.textline.TextLineCodecFactory;   import org.apache.mina.transport.socket.nio.NioSocketConnector;   /**   * mina客户端   */  public class MinaTimeClient {       public static void main(String []args)throws Exception{           //Create TCP/IP connection           NioSocketConnector connector = new NioSocketConnector();           //创建接受数据的过滤器           DefaultIoFilterChainBuilder chain = connector.getFilterChain();           //设定这个过滤器将一行一行(/r/n)的读取数据           chain.addLast("myChin", new ProtocolCodecFilter(new TextLineCodecFactory()));           //客户端的消息处理器:一个SamplMinaServerHander对象           connector.setHandler(new TimeClientHandler());           //set connect timeout           connector.setConnectTimeout(30);           //连接到服务器:           ConnectFuture cf = connector.connect(new InetSocketAddress("localhost",8888));           //Wait for the connection attempt to be finished.           cf.awaitUninterruptibly();           cf.getSession().getCloseFuture().awaitUninterruptibly();           connector.dispose();       }  }

TimeClientHandler.java

import org.apache.mina.core.service.IoHandlerAdapter;import org.apache.mina.core.session.IoSession;/** * 客户端业务处理逻辑 */public class TimeClientHandler extends IoHandlerAdapter {    // 当客户端连接进入时    @Override    public void sessionOpened(IoSession session) throws Exception {        System.out.println("incomming 客户端: " + session.getRemoteAddress());        session.write("i am coming");    }    @Override    public void exceptionCaught(IoSession session, Throwable cause)            throws Exception {        System.out.println("客户端发送信息异常....");    }    // 当客户端发送消息到达时    @Override    public void messageReceived(IoSession session, Object message)            throws Exception {        System.out.println("服务器返回的数据:" + message.toString());    }    @Override    public void sessionClosed(IoSession session) throws Exception {        System.out.println("客户端与服务端断开连接.....");    }    @Override    public void sessionCreated(IoSession session) throws Exception {        // TODO Auto-generated method stub        System.out                .println("one Client Connection" + session.getRemoteAddress());        session.write("我来了······");    }}

4、常见错误

  • 错误
    错误1
  • 解决方法
    这个错误是jar包版本太低导致的,因此只需下载高版本的jar包并替换。

5、参考文献

【1】http://www.cnblogs.com/xuekyo/archive/2013/03/06/2945826.html
【2】http://blog.csdn.net/madun/article/details/7890885
【3】http://blog.csdn.net/lsh6688/article/details/9671281

0 0
原创粉丝点击