mina例子 中文+英文+源碼下載

例子下載地址:http://blog.csdn.net/hujunil/article/details/9923381java

英文:
linux

This tutorial will walk you through the process of building a MINA based program. This tutorial will walk through building a time server. The following prerequisites are required for this tutorial:web

  • MINA 2.0.7 Coreapache

  • JDK 1.5 or greaterapi

  • [SLF4J|http://www.slf4j.org/] 1.3.0 or greater服務器

    • Log4J 1.2 users: slf4j-api.jarslf4j-log4j12.jar, and Log4J 1.2.xsession

    • Log4J 1.3 users: slf4j-api.jarslf4j-log4j13.jar, and Log4J 1.3.x框架

    • java.util.logging users: slf4j-api.jar and slf4j-jdk14.jarless

    • IMPORTANT : Please make sure you are using the right slf4j-*.jar that matches to your logging framework. For instance, slf4j-log4j12.jar and log4j-1.3.x.jar can not be used together, and will malfunction.socket

I have tested this program on both Windows漏 2000 professional and linux. If you have any problems getting this program to work, please do not hesitate to [contact us|Contact] in order to talk to the MINA developers. Also, this tutorial has tried to remain independent of development environments (IDE, editors..etc). This tutorial will work with any environment that you are comfortable with. Compilation commands and steps to execute the program have been removed for brevity. If you need help learning how to either compile of execute java programs, please consult the Java tutorial.

Writing the MINA time server

We will begin by creating a file called MinaTimeServer.java. The initial code can be found below: :::Java public class MinaTimeServer {

    public static void main(String[] args) {
        // code will go here next
    }}

This code should be straightforward to all. We are simply defining a main method that will be used to kick off the program. At this point, we will begin to add the code that will make up our server. First off, we need an object that will be used to listen for incoming connections. Since this program will be TCP/IP based, we will add a SocketAcceptor to our program.

import org.apache.mina.core.service.IoAcceptor;import org.apache.mina.transport.socket.nio.NioSocketAcceptor;public class MinaTimeServer{
    public static void main( String[] args )
    {
        IoAcceptor acceptor = new NioSocketAcceptor();
    }}

With the NioSocketAcceptor class in place, we can go ahead and define the handler class and bind the NioSocketAcceptor to a port.

Next we add a filter to the configuration. This filter will log all information such as newly created sessions, messages received, messages sent, session closed. The next filter is a ProtocolCodecFilter. This filter will translate binary or protocol specific data into message object and vice versa. We use an existing TextLine factory because it will handle text base message for you (you don't have to write the codec part)

import java.nio.charset.Charset;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 MinaTimeServer{
    public static void main( String[] args )
    {
        IoAcceptor acceptor = new NioSocketAcceptor();

        acceptor.getFilterChain().addLast( "logger", new LoggingFilter() );
        acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));
    }}

At this point, we will define the handler that will be used to service client connections and the requests for the current time. The handler class is a class that must implement the interface IoHandler. For almost all programs that use MINA, this becomes the workhorse of the program, as it services all incoming requests from the clients. For this tutorial, we will extend the class IoHandlerAdapter. This is a class that follows the adapter design pattern which simplifies the amount of code that needs to be written in order to satisfy the requirement of passing in a class that implements the IoHandler interface.

import java.io.IOException;import java.nio.charset.Charset;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 MinaTimeServer{
    public static void main( String[] args ) throws IOException
    {
        IoAcceptor acceptor = new NioSocketAcceptor();

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

        acceptor.setHandler(  new TimeServerHandler() );
    }}

We will now add in the NioSocketAcceptor configuration. This will allow us to make socket-specific settings for the socket that will be used to accept connections from clients.

import java.io.IOException;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 MinaTimeServer{
    public static void main( String[] args ) throws IOException
    {
        IoAcceptor acceptor = new NioSocketAcceptor();

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

        acceptor.setHandler(  new TimeServerHandler() );

        acceptor.getSessionConfig().setReadBufferSize( 2048 );
        acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );
    }}

There are 2 new lines in the MinaTimeServer class. These methods set the set the IoHandler, input buffer size and the idle property for the sessions. The buffer size will be specified in order to tell the underlying operating system how much room to allocate for incoming data. The second line will specify when to check for idle sessions. In the call to setIdleTime, the first parameter defines what actions to check for when determining if a session is idle, the second parameter defines the length of time in seconds that must occur before a session is deemed to be idle.

The code for the handler is shown below:

import java.util.Date;import org.apache.mina.core.session.IdleStatus;import org.apache.mina.core.service.IoHandlerAdapter;import org.apache.mina.core.session.IoSession;public class TimeServerHandler extends IoHandlerAdapter{
    @Override
    public void exceptionCaught( IoSession session, Throwable cause ) throws Exception
    {
        cause.printStackTrace();
    }

    @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();
        session.write( date.toString() );
        System.out.println("Message written...");
    }

    @Override
    public void sessionIdle( IoSession session, IdleStatus status ) throws Exception
    {
        System.out.println( "IDLE " + session.getIdleCount( status ));
    }}

The methods used in this class are exceptionCaughtmessageReceived and sessionIdleexceptionCaught should always be defined in a handler to process and exceptions that are raised in the normal course of handling remote connections. If this method is not defined, exceptions may not get properly reported.

The exceptionCaught method will simply print the stack trace of the error and close the session. For most programs, this will be standard practice unless the handler can recover from the exception condition.

The messageReceived method will receive the data from the client and write back to the client the current time. If the message received from the client is the word "quit", then the session will be closed. This method will also print out the current time to the client. Depending on the protocol codec that you use, the object (second parameter) that gets passed in to this method will be different, as well as the object that you pass in to the session.write(Object) method. If you do not specify a protocol codec, you will most likely receive a IoBuffer object, and be required to write out a IoBuffer object.

The sessionIdle method will be called once a session has remained idle for the amount of time specified in the callacceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );.

All that is left to do is define the socket address that the server will listen on, and actually make the call that will start the server. That code is shown below:

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 = 9123;

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

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

        acceptor.setHandler( new TimeServerHandler() );
    acceptor.getSessionConfig().setReadBufferSize( 2048 );
        acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );
        acceptor.bind( new InetSocketAddress(PORT) );
    }}


中文:

  • MINA 2.0.7 Core

  • JDK 1.5 或更高

  • SLF4J 1.3.0 或更高

  • Log4J 1.2 用戶: slf4j-api.jar, slf4j-log4j12.jar, 和Log4J 1.2.x

  • Log4J 1.3 用戶: slf4j-api.jar, slf4j-log4j13.jar, 和Log4J 1.3.x

  • java.util.logging 用戶: slf4j-api.jar 和slf4j-jdk14.jar

  • 重要提醒:請確認你使用的slf4j-*.jar和你的logging框架匹配。舉個板栗,slf4j-log4j12.jar 和 log4j-1.3.x.jar 是不能混在一塊兒用的,不然會出問題。

建立一個MINA時間服務

We will begin by creating a file called MinaTimeServer.java
咱們建立一個文件名爲 MinaTimeServer.java ,文件內容以下:

public class MinaTimeServer{
    public static void main( String[] args )
    {
        //尚未東西呢
    }}

上面的代碼應該不用解釋了吧,爲了建立咱們的服務,咱們須要一個監聽傳入鏈接的對象,因爲咱們的項目是基於TCP/IP,因此須要一個SocketAcceptor 對象來幫咱們處理。

import org.apache.mina.core.service.IoAcceptor;import org.apache.mina.transport.socket.nio.NioSocketAcceptor;public class MinaTimeServer{
    public static void main( String[] args )
    {
        IoAcceptor acceptor = new NioSocketAcceptor();
    }}

建立好後,咱們能夠定義處理請求的類,和指定監聽的端口等。

接下來,咱們須要在配置裏添加幾個過濾器。第一個是logger,這個過濾器用來記錄全部的信息,好比建立session(會話),接收消息,發送消息,關閉會話等。第二個是ProtocolCodecFilter(協議編解碼過濾器).這個過濾器用來轉換二進制或協議的專用數據到消息對象中, 反之亦然。咱們這裏使用一個已經存在的TextLine工廠,由於咱們這裏只處理一些文字消息(你不須要再去寫編解碼部分)。

import java.nio.charset.Charset;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 MinaTimeServer{
    public static void main( String[] args )
    {
        IoAcceptor acceptor = new NioSocketAcceptor();

        acceptor.getFilterChain().addLast( "logger", new LoggingFilter() );
        acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));
    }}

For this tutorial, we will extend the class IoHandlerAdapter. This is a class that follows the adapter design pattern which simplifies the amount of code that needs to be written in order to satisfy the requirement of passing in a class that implements the IoHandler interface.
接下來咱們須要建立一個handler來實時處理客戶端的鏈接和請求,這個handler 類必須實現 IoHandler這個接口。對於全部使用MINA的程序來講,主要的負荷都在這個文件,它爲全部客戶端請求提供服務。在這個例子中,咱們將擴展IoHandlerAdapter類。這是一個聽從適配器模式的類,幫咱們簡化了不少爲了去實現IoHandler接口的代碼。

import java.io.IOException;import java.nio.charset.Charset;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 MinaTimeServer{
    public static void main( String[] args ) throws IOException
    {
        IoAcceptor acceptor = new NioSocketAcceptor();

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

        acceptor.setHandler(  new TimeServerHandler() );
    }}

如今咱們要添加一些NioSocketAcceptor 配置,這將容許咱們設置特殊的socket設置來接收客戶端的鏈接。

import java.io.IOException;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 MinaTimeServer{
    public static void main( String[] args ) throws IOException
    {
        IoAcceptor acceptor = new NioSocketAcceptor();

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

        acceptor.setHandler(  new TimeServerHandler() );

        acceptor.getSessionConfig().setReadBufferSize( 2048 );
        acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );
    }}

這有兩行新代碼,這些方法是用來爲會話設置IoHandler,輸入緩衝區的大小和空閒等待時間。
須要指定緩衝區大小來告訴底層操做系統爲傳入的數據分配多少的空間。第二行指定多少時間沒有讀寫操做就進入空閒狀態。

handler的代碼以下:

import java.util.Date;import org.apache.mina.core.session.IdleStatus;import org.apache.mina.core.service.IoHandlerAdapter;import org.apache.mina.core.session.IoSession;public class TimeServerHandler extends IoHandlerAdapter{
    @Override
    public void exceptionCaught( IoSession session, Throwable cause ) throws Exception
    {
        cause.printStackTrace();
    }

    @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();
        session.write( date.toString() );
        System.out.println("Message written...");
    }

    @Override
    public void sessionIdle( IoSession session, IdleStatus status ) throws Exception
    {
        System.out.println( "IDLE " + session.getIdleCount( status ));
    }}

這個類中通常有exceptionCaughtmessageReceived 和 sessionIdle這幾個方法。exceptionCaught 應該老是在handler 中定義,來處理一些異常狀況,不然異常信息將沒法捕捉。

exceptionCaught 方法簡單地打印了錯誤的堆棧跟蹤和關閉會話。對於大多數程序,這將是標準的作法,除非處理程序能夠從異常狀態中恢復。

messageReceived 方法來處理從客戶端接收到的數據,這裏是將當前時間返回給客戶端,當收到quit時,會話將被關閉,也會返回一個當前時間給客戶端。根據所使用的協議編解碼器,object 這個參數傳遞的類型有所不一樣,以及返回的數據時的session.write(Object) 也不一樣。若是不指定協議的編解碼器,你將收到一個類型爲IoBuffer 的對象,返回的數據也要求是IoBuffer

The sessionIdle method will be called once a session has remained idle for the amount of time specified in the call acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );.
sessionIdle 方法將定時調用一次會話,保持空閒狀態。經過調用acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );來設定時間間隔。

全部剩下要作的就是定義套接字地址,該服務器將偵聽,實際接入時纔會啓動服務。

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 = 9123;

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

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

        acceptor.setHandler( new TimeServerHandler() );
    acceptor.getSessionConfig().setReadBufferSize( 2048 );
        acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );
        acceptor.bind( new InetSocketAddress(PORT) );
    }}

到了這裏後,服務端的操做就已經完成了,客戶端可參考附件中代碼,裏面包含了完整的實例,來源自http://blog.csdn.net/hujunil/article/details/9923381

代碼結構

代碼結構

效果

客戶端
mina-2.jpg
服務端
mina-3.jpg

源碼下載:http://oss.loftor.com/usr/uploads/2014/08/3841585032.rar

相關文章
相關標籤/搜索