基于Apache Mina的一个简单应用

时间:2021-10-18 20:49:43

1、前言

Apache MINA是Apache组织的一个优秀的项目。MINA是Multipurpose Infrastructure forNetwork Applications的缩写。它是一个网络应用程序框架,用来帮助用户非常方便地开发高性能和高可靠性的网络应用程序。在本文中介绍了如何通过Apache Mina2.0来创建一个简单的TCP协议Client/Server应用。

2、Apache Mina简介

Apache MINA是一个网络应用程序框架,它对Java中的socket和NIO进行了有效和清晰的封装,方便开发人员开发TCP/UDP程序,从而抛开在使用原始的socket时需要考虑的各种繁杂而又烦人问题(比如线程、性能、会话等),把更多精力专著在应用中的业务逻辑开发上。

3、需要的资源

         需要的jar包:

1. mina-core-2.0.4.jar

2. slf4j-api-1.6.1.jar

3. slf4j-jdk14-1.6.1.jar

4、服务端程序

在服务端有两个类:MinaServer和MinaServerHandler。

MinaServer类是服务端的入口,它包含一个名为“IoAcceptor”的接口用来接收服务端的请求,并且触发处理器事件。定义了两个过滤器:日志过滤器和编码过滤器。

MinaServer.java

package tcp.mina.demo.server;

 

import java.io.IOException;

import java.net.InetSocketAddress;

import java.nio.charset.Charset;

 

import org.apache.mina.core.session.IdleStatus;

import org.apache.mina.core.service.IoAcceptor;

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 MinaServer{

    private static final int PORT = 1234;

 

    public static void main(String[] args) throws IOException {

       IoAcceptor acceptor = new NioSocketAcceptor();

 

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

       acceptor.getFilterChain().addLast("codec", newProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));

 

       acceptor.setHandler(new MinaServerHandler());

       acceptor.getSessionConfig().setReadBufferSize(2048);

       acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);

       acceptor.bind(new InetSocketAddress(PORT));

       System.out.println("server islistenig at port : " +PORT);

    }

}

MinaServerHandler类是服务端的消息处理类,其中名为“messageReceived”的方法是处理服务端接收到的数据。

MinaServerHandler.java

package tcp.mina.demo.server;

 

import org.apache.mina.core.session.IdleStatus;

import org.apache.mina.core.service.IoHandlerAdapter;

import org.apache.mina.core.session.IoSession;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

 

public class MinaServerHandlerextends IoHandlerAdapter {

    private final Logger logger = (Logger) LoggerFactory.getLogger(getClass());

 

    @Override

    public void sessionOpened(IoSession session) {

       // set idle time to 10seconds

       session.getConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);

 

    }

 

    @Override

    public void messageReceived(IoSession session, Object message) {

       logger.info("Messagereceived in the server..");

       logger.info("Message is:" + message.toString());

    }

 

    @Override

    public void sessionIdle(IoSession session, IdleStatus status) {

       logger.info("Disconnectingthe idle.");

       // disconnect an idle client

       session.close(true);

    }

 

    @Override

    public void exceptionCaught(IoSession session, Throwable cause) {

       // close the connection onexceptional situation

       logger.warn(cause.getMessage(), cause);

       session.close(true);

    }

 

}

5、客户端程序

在客户端有两个类:MinaClient和MinaClientHandler。

MinaClient类是客户端的入口,它包含一个名为“IoConnector”的接口用来向服务端发起连接请求,并且触发处理器事件。定义了两个过滤器:日志过滤器和编码过滤器。连接成功后使用“ConnectFuture”将异步执行转换为同步执行。

MinaClient.java

package tcp.mina.demo.client;

 

import java.io.IOException;

import java.net.InetSocketAddress;

import java.nio.charset.Charset;

import org.apache.mina.core.future.ConnectFuture;

import org.apache.mina.core.service.IoConnector;

import org.apache.mina.core.session.IoSession;

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.NioSocketConnector;

 

public class MinaClient {

    private static final int PORT = 1234;

 

    public static void main(String[] args) throws IOException,InterruptedException {

       IoConnector connector = new NioSocketConnector();

       connector.getSessionConfig().setReadBufferSize(2048);

 

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

       connector.getFilterChain().addLast("codec", newProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));

 

       connector.setHandler(new MinaClientHandler("Hello Server.."));

       ConnectFuture future = connector.connect(new InetSocketAddress("127.0.0.1",PORT));

       future.awaitUninterruptibly();

 

       if (!future.isConnected()) {

           return;

       }

       IoSession session = future.getSession();

       session.getConfig().setUseReadOperation(true);

       session.getCloseFuture().awaitUninterruptibly();

 

       System.out.println("AfterWriting");

       connector.dispose();

 

    }

 

}

MinaClientHandler类是客户端的消息处理类,其中名为“messageReceived”的方法是处理客户端接收到的数据。在“sessionOpened”方法中使用session.write(values);发送消息。

MinaClientHandler.java

package tcp.mina.demo.client;

 

import org.apache.mina.core.service.IoHandlerAdapter;

import org.apache.mina.core.session.IoSession;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

 

public class MinaClientHandler extends IoHandlerAdapter {

    private final Logger logger = (Logger) LoggerFactory.getLogger(getClass());

    private final String values;

 

    public MinaClientHandler(String values) {

       this.values = values;

    }

 

    @Override

    public void sessionOpened(IoSession session) {

       session.write(values);

    }

 

    @Override

    public void messageReceived(IoSession session, Object message) {

       logger.info("Messagereceived in the client..");

       logger.info("Message is:" + message.toString());

    }

 

    @Override

    public void exceptionCaught(IoSession session, Throwable cause) {

       logger.warn(cause.getMessage(), cause);

       session.close(true);

    }

 

}

6、总结

通过本文中的例子,我们可以看到使用Apache Mina可非常方便的开发网络服务应用程序,可以隐藏处理底层I/O和线程并发等复杂工作。除此之外MINA框架还具有很多特点:基于java NIO类库开发;采用非阻塞方式的异步传输;事件驱动;支持批量数据传输;支持TCP、UDP协议;控制反转的设计模式(支持Spring);采用优雅的松耦合架构;可灵活的加载过滤器机制;单元测试更容易实现;可自定义线程的数量,以提高运行于多处理器上的性能;采用回调的方式完成调用,线程的使用更容易。

7、参考资料

http://www.techbrainwave.com/?p=912

http://log-cd.iteye.com/blog/519408

http://blog.whhpaccp.com/?post=409