Apache Mina server簡單編解碼實現

openkk 12年前發布 | 72K 次閱讀 網絡工具包 Apache MINA

協議編解碼器是在使用Mina 的時候你最需要關注的對象,因為在網絡傳輸的數據都是二進制數據(byte),而你在程序中面向的是JAVA 對象,這就需要你實現在發送數據
時將JAVA 對象編碼二進制數據,而接收數據時將二進制數據解碼為JAVA 對象(這個可不是JAVA 對象的序列化、反序列化那么簡單的事情)。廢話少說直接上代碼:

 

Server:

package com.cemso.mina.server;

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;

import com.cemso.mina.coder.CmccSipcCodecFactory;

/**
 * @author gl65293
 */
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.getFilterChain().addLast("codec", new ProtocolCodecFilter(new CmccSipcCodecFactory(Charset.forName("UTF-8"))));

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

    }
}
package com.cemso.mina.server;

/**
 * @author gl65293
 *
 */
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;

import com.cemso.mina.dto.SmsObject;

public class TimeServerHandler extends IoHandlerAdapter {

    public TimeServerHandler() {
    }

    public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
        cause.printStackTrace();
    }

    public void messageReceived(IoSession session, Object message) throws Exception {

        SmsObject sms = (SmsObject)message;
        System.out.println(sms.getMessage());
        System.out.println(sms.getSender());
        System.out.println(sms.getReceiver());

    }

    public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
        System.out.println((new StringBuilder()).append("IDLE ").append(session.getIdleCount(status)).toString());
    }
}
dto:
package com.cemso.mina.dto;

/**
 * @author gl65293
 *
 */
public class SmsObject {

    private String sender;
    private String receiver;
    private String message;
    /**
     * @return the sender
     */
    public String getSender() {
        return sender;
    }
    /**
     * @param sender the sender to set
     */
    public void setSender(String sender) {
        this.sender = sender;
    }
    /**
     * @return the receiver
     */
    public String getReceiver() {
        return receiver;
    }
    /**
     * @param receiver the receiver to set
     */
    public void setReceiver(String receiver) {
        this.receiver = receiver;
    }
    /**
     * @return the message
     */
    public String getMessage() {
        return message;
    }
    /**
     * @param message the message to set
     */
    public void setMessage(String message) {
        this.message = message;
    }
}
encoder and decoder:
package com.cemso.mina.coder;

import java.nio.charset.Charset;

import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolEncoder;

/**
 * @author gl65293
 *
 */
public class CmccSipcCodecFactory implements ProtocolCodecFactory {

    private final CmccSipcEncoder encoder;
    private final CmccSipcDecoder decoder;

    public CmccSipcCodecFactory(){
        this(Charset.defaultCharset());
    }
    /**
     * @param defaultCharset
     */
    public CmccSipcCodecFactory(Charset charSet) {
        this.encoder = new CmccSipcEncoder(charSet);
        this.decoder = new CmccSipcDecoder(charSet);
    }
    /* (non-Javadoc)
     * @see org.apache.mina.filter.codec.ProtocolCodecFactory#getDecoder(org.apache.mina.core.session.IoSession)
     */
    @Override
    public ProtocolDecoder getDecoder(IoSession iosession) throws Exception {
        // TODO Auto-generated method stub
        return decoder;
    }

    /* (non-Javadoc)
     * @see org.apache.mina.filter.codec.ProtocolCodecFactory#getEncoder(org.apache.mina.core.session.IoSession)
     */
    @Override
    public ProtocolEncoder getEncoder(IoSession iosession) throws Exception {
        // TODO Auto-generated method stub
        return encoder;
    }

}
package com.cemso.mina.coder;

import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;

import com.cemso.mina.dto.SmsObject;

/**
 * @author gl65293
 *
 */
public class CmccSipcDecoder extends CumulativeProtocolDecoder {

    private final Charset charset;


    /**
     * @param charset
     */
    public CmccSipcDecoder(Charset charset) {
        this.charset = charset;
    }

    /* (non-Javadoc)
     * @see org.apache.mina.filter.codec.CumulativeProtocolDecoder#doDecode(org.apache.mina.core.session.IoSession, org.apache.mina.core.buffer.IoBuffer, org.apache.mina.filter.codec.ProtocolDecoderOutput)
     */
    @Override
    protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
        // TODO Auto-generated method stub

        IoBuffer buffer = IoBuffer.allocate(100).setAutoExpand(true);
        CharsetDecoder decoder = charset.newDecoder();

        int matchCount = 0;

        String statusLine = "";
        String sender = "";
        String receiver = "";
        String length = "";
        String sms="";
        int i = 1;

        while(in.hasRemaining()){
            byte b = in.get();
            buffer.put(b);

            if(b == 10 && i < 5){
                matchCount ++;
                if(i == 1){
                    buffer.flip();
                    statusLine = buffer.getString(matchCount,decoder);
                    statusLine = statusLine.substring(0, statusLine.length()-1);
                    matchCount = 0;
                    buffer.clear();
                }
                if(i == 2){
                    buffer.flip();
                    sender = buffer.getString(matchCount,decoder);
                    sender = sender.substring(0, sender.length()-1);
                    matchCount = 0;
                    buffer.clear();
                }
                if(i == 3){
                    buffer.flip();
                    receiver = buffer.getString(matchCount,decoder);
                    receiver = receiver.substring(0, receiver.length()-1);
                    matchCount = 0;
                    buffer.clear();
                }
                if(i == 4){
                    buffer.flip();
                    length = buffer.getString(matchCount,decoder);
                    length = length.substring(0, length.length()-1);
                    matchCount = 0;
                    buffer.clear();
                }

                i++;
            }else if(i == 5){
                matchCount ++;
                if(matchCount == Long.parseLong(length.split(": ")[1])){
                    buffer.flip();
                    sms = buffer.getString(matchCount,decoder);
                    i++;
                    break;
                }
            }else{
                matchCount ++;
            }
        }

        SmsObject smsObject = new SmsObject();
        smsObject.setSender(sender.split(": ")[1]);
        smsObject.setReceiver(receiver.split(": ")[1]);
        smsObject.setMessage(sms);

        out.write(smsObject);

        return false;
    }

}
package com.cemso.mina.coder;


import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolEncoderAdapter;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;

import com.cemso.mina.dto.SmsObject;

/**
 * @author gl65293
 *
 */
public class CmccSipcEncoder extends ProtocolEncoderAdapter {

    private final Charset charset;

    public CmccSipcEncoder(Charset charset){
        this.charset = charset;
    }

    /* (non-Javadoc)
     * @see org.apache.mina.filter.codec.ProtocolEncoder#encode(org.apache.mina.core.session.IoSession, java.lang.Object, org.apache.mina.filter.codec.ProtocolEncoderOutput)
     */
    @Override
    public void encode(IoSession iosession, Object obj, ProtocolEncoderOutput out) throws Exception {
        // TODO Auto-generated method stub
        SmsObject sms = (SmsObject)obj;
        CharsetEncoder charst = charset.newEncoder();
        IoBuffer buffer = IoBuffer.allocate(100).setAutoExpand(true);
        String statusLine = "M sip:wap.fetion.com.cn SIP-C/2.0";
        String sender = sms.getSender();
        String recevier = sms.getReceiver();
        String smsContent = sms.getMessage();

        buffer.putString(statusLine+'\n', charst);
        buffer.putString("S: "+sender+'\n', charst);
        buffer.putString("R: "+recevier+'\n', charst);
        buffer.putString("L: "+smsContent.getBytes(charset).length+"\n", charst);
        buffer.putString(smsContent, charst);

        buffer.flip();
        out.write(buffer);

    }

}
client:
package com.cemso.mina.client;

/**
 * @author gl65293
 *
 */
import java.net.InetSocketAddress;
import java.nio.charset.Charset;

import org.apache.mina.core.service.IoConnector;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

import com.cemso.mina.coder.CmccSipcCodecFactory;

// Referenced classes of package org.apache.mina.example.sumup:
//            ClientSessionHandler

public class Client {

    public Client() {
    }

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

    /*    if (args.length == 0) {
            System.out.println("Please specify the list of any integers");
            return;
        }
        // prepare values to sum up
        int[] values = new int[args.length];
        for (int i = 0; i < args.length; i++) {
            values[i] = Integer.parseInt(args[i]);
        }

        NioSocketConnector connector = new NioSocketConnector();

        // Configure the service.
        connector.setConnectTimeoutMillis(CONNECT_TIMEOUT);
        if (USE_CUSTOM_CODEC) {
            connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new SumUpProtocolCodecFactory(false)));
        } else {
            connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));
        }
        connector.getFilterChain().addLast("logger", new LoggingFilter());
        connector.setHandler(new ClientSessionHandler(values));

        IoSession session;
        for (;;) {
            try {
                ConnectFuture future = connector.connect(new InetSocketAddress(HOSTNAME, PORT));
                future.awaitUninterruptibly();
                session = future.getSession();
                break;
            } catch (RuntimeIoException e) {
                System.err.println("Failed to connect.");
                e.printStackTrace();
                Thread.sleep(5000);
            }
        }

        // wait until the summation is done
        session.getCloseFuture().awaitUninterruptibly();
        connector.dispose();*/

        IoConnector connector = new NioSocketConnector();
        connector.setHandler(new ClientSessionHandler("你好!\r\n哈哈!"));
        connector.setConnectTimeoutMillis(30000);
//        connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
        connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new CmccSipcCodecFactory(Charset.forName("UTF-8"))));

        connector.connect(new InetSocketAddress("127.0.0.1",9123));


    }

}
package com.cemso.mina.client;

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

import com.cemso.mina.dto.SmsObject;

/**
 * @author gl65293
 *
 */
public class ClientSessionHandler extends IoHandlerAdapter{
    private final String values;

    public ClientSessionHandler(String values){
        this.values = values;
    }

    public void sessionOpened(IoSession session){
        //session.write(values);

        SmsObject sms = new SmsObject();
        sms.setSender("18817261072");
        sms.setReceiver("15951892458");
        sms.setMessage("你好! Hello world!");
        session.write(sms);
    }
}

 本文由用戶 openkk 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!