Apache MINA简单介绍及其使用

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值