協議編解碼器是在使用Mina 的時候你最須要關注的對象,由於在網絡傳輸的數據都是二進制數據(byte),而你在程序中面向的是JAVA 對象,這就須要你實如今發送數據
時將JAVA 對象編碼二進制數據,而接收數據時將二進制數據解碼爲JAVA 對象(這個可不是JAVA 對象的序列化、反序列化那麼簡單的事情)。廢話少說直接上代碼:java
Server:ios
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)); } }
encoder and decoder:apache
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)); } }