Mina TCP 编码解码相关资料收集

来源:互联网 发布:澳大利亚国立大学知乎 编辑:程序博客网 时间:2024/05/29 07:14

用到了mina,自己记录下,用到了以前文章

编码 解码的例子

http://blog.csdn.net/jbgtwang/article/details/26266309

http://blog.csdn.net/jbgtwang/article/details/26261643

messageReceivce中字符还原成字符串的例子。

http://m.blog.csdn.net/eddle/article/details/6895550
字节截取的例子

http://blog.csdn.net/u010277446/article/details/52459613

Java代码
  1. /**  
  2. * 将byte[]转换成string    
  3. * @param butBuffer  
  4. */  
  5. public static String byteToString(byte [] b)   
  6. {   
  7.        StringBuffer stringBuffer = new StringBuffer();   
  8.        for (int i = 0; i < b.length; i++)   
  9.        {   
  10.            stringBuffer.append((char) b [i]);   
  11.        }   
  12.        return stringBuffer.toString();   
  13. }   
  14.   
  15. /**  
  16. * 将bytebuffer转换成string    
  17. * @param str  
  18. */  
  19. public static IoBuffer stringToIoBuffer(String str)   
  20. {   
  21.   
  22.        byte bt[] = str.getBytes();   
  23.   
  24.        IoBuffer ioBuffer = IoBuffer.allocate(bt.length);   
  25.        ioBuffer.put(bt, 0, bt.length);   
  26.        ioBuffer.flip();   
  27.        return ioBuffer;   
  28. }   
  29. /**  
  30. * 将IoBuffer转换成string    
  31. * @param str  
  32. */  
  33. public static IoBuffer byteToIoBuffer(byte [] bt,int length)   
  34. {   
  35.   
  36.        IoBuffer ioBuffer = IoBuffer.allocate(length);   
  37.        ioBuffer.put(bt, 0, length);   
  38.        ioBuffer.flip();   
  39.        return ioBuffer;   
  40. }   
  41. /**  
  42. * 将IoBuffer转换成byte    
  43. * @param str  
  44. */  
  45. public static byte [] ioBufferToByte(Object message)   
  46. {   
  47.       if (!(message instanceof IoBuffer))   
  48.       {   
  49.           return null;   
  50.       }   
  51.       IoBuffer ioBuffer = (IoBuffer)message;   
  52.       byte[] b = new byte[ioBuffer.limit()];   
  53.       ioBuffer.get(b);   
  54.       return b;   
  55. }   
  56. /**  
  57. * 将IoBuffer转换成string    
  58. * @param butBuffer  
  59. */  
  60. public static String ioBufferToString(Object message)   
  61. {   
  62.       if (!(message instanceof IoBuffer))   
  63.       {   
  64.         return "";   
  65.       }   
  66.       IoBuffer ioBuffer = (IoBuffer) message;   
  67.       byte[] b = new byte [ioBuffer.limit()];   
  68.       ioBuffer.get(b);   
  69.       StringBuffer stringBuffer = new StringBuffer();   
  70.   
  71.       for (int i = 0; i < b.length; i++)   
  72.       {   
  73.   
  74.        stringBuffer.append((char) b [i]);   
  75.       }   
  76.        return stringBuffer.toString();   
  77. }  
  78. public static byte[] subBytes(byte[] src, int begin, int count) {  
  79.     byte[] bs = new byte[count];  
  80.     System.arraycopy(src, begin, bs, 0, count);  
  81.     return bs;  
  82. }  
我们在自定义传输协议时,通常都是采用字节数组的方式进行传送,如何正确接收和解码byte数组?

假设我们自定义了传输协议: 字节数组的前4个字节是要传输的数据长度,后面跟数据。我们用mina可以这样处理

1.自定义编码器ByteArrayEncoder.java

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

/**
 *  编码器将数据直接发出去(不做处理)
 */
public class ByteArrayEncoder extends ProtocolEncoderAdapter {

    @Override
    public void encode(IoSession session, Object message,
            ProtocolEncoderOutput out) throws Exception {
        out.write(message);
        out.flush();
        
    }
}

2.自定义解码器(确保能读取到完整的包)

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.talkweb.meeting.tools.IntByteConvert;

public class ByteArrayDecoder extends CumulativeProtocolDecoder  {

    @Override
    public boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out)
            throws Exception {
        
        if(in.remaining() > 4){//前4字节是包头
            //标记当前position的快照标记mark,以便后继的reset操作能恢复position位置
            in.mark(); 
            byte[] l = new byte[4];
            in.get(l);

            //包体数据长度
            int len = MyTools.bytes2int(l);//将byte转成int
           

            //注意上面的get操作会导致下面的remaining()值发生变化
            if(in.remaining() < len){
                //如果消息内容不够,则重置恢复position位置到操作前,进入下一轮, 接收新数据,以拼凑成完整数据
                in.reset();   
                return false;
            }else{
                //消息内容足够
                in.reset();//重置恢复position位置到操作前
                int sumlen = 4+len;//总长 = 包头+包体
                byte[] packArr = new byte[sumlen];
                in.get(packArr, 0 , sumlen);
                
                IoBuffer buffer = IoBuffer.allocate(sumlen);
                buffer.put(packArr);
                buffer.flip();
                out.write(buffer);
                buffer.free();
                
                if(in.remaining() > 0){//如果读取一个完整包内容后还粘了包,就让父类再调用一次,进行下一次解析
                    return true;
                }
            }
        }
        return false;//处理成功,让父类进行接收下个包
    }
    
}

3.编解码工厂类

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 BruceYang
 *
 */
public class ByteArrayCodecFactory implements ProtocolCodecFactory {
    
    private ByteArrayDecoder decoder;
    private ByteArrayEncoder encoder;
    
    public ByteArrayCodecFactory() {
        encoder = new ByteArrayEncoder();
        decoder = new ByteArrayDecoder();
    }

    @Override
    public ProtocolDecoder getDecoder(IoSession session) throws Exception {
        return decoder;
    }

    @Override
    public ProtocolEncoder getEncoder(IoSession session) throws Exception {
        return encoder;
    }

}

4.调用编解码工厂进行编解码

NioSocketAcceptor acceptor = new NioSocketAcceptor();

acceptor.getFilterChain().addLast("mycoder", new ProtocolCodecFilter(new ByteArrayCodecFactory()));

原创粉丝点击