mina 接受大数据量信息 socket接受无固定长度的报文体

接受socket无固定长度的报文,报文体的长度存在http头的Content-Length:中
protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
if (in.remaining() < packetLength)
return false;



byte[] headBytes = null;

try{
if(headLength ==0 && bodyLength==0){

headBytes = new byte[in.limit()];
log.debug("in.limit():" + in.limit() + " in.remaining():" + in.remaining());
in.get(headBytes);
in.flip();
}
if(headBytes != null && headBytes.length >=0){

String httpMes = new String( headBytes,"UTF-8");
int startIndex = httpMes.indexOf("Content-Length:") + "Content-Length:".length();
int endIndex = httpMes.indexOf("Connection:");

String length = httpMes.substring(startIndex, endIndex);
length = length.trim();
bodyLength = Integer.parseInt(length);
httpMes = httpMes.substring(0,httpMes.indexOf("keep-alive") + "keep-alive".length()+1);
headLength = httpMes.getBytes().length;
headBytes = null;
log.debug("bodyLength:" + bodyLength +" headLength:" + headLength);
}
}catch(Exception e){
e.printStackTrace();
log.debug("exception e");
headLength =0;
bodyLength = 0;
// throw new Exception("exception e");
}

byte[] bytes = null;
if(headLength >= 0 && bodyLength>=0){

// 先获取上次的处理上下文,其中可能有未处理完的数据 
        Context ctx = getContext(session); 
        log.debug("in.limit:" + in.limit());
        // 先把当前buffer中的数据追加到Context的buffer当中 
        ctx.append(in); 
        // 把position指向0位置,把limit指向原来的position位置 
        IoBuffer buf = ctx.getBuffer(); 
        buf.flip(); 
      log.debug("buf.remaining()--------" + buf.remaining()); 
       
        try{
     // 然后按数据包的协议进行读取 
        while (buf.remaining() >= packetLength) { 
            buf.mark(); 
       
            // 检查读取是否正常,不正常的话清空buffer 
            if (bodyLength < 0 || bodyLength > maxPackLength) { 
              
                buf.clear(); 
                break; 
            } 
            // 读取正常的消息,并写入输出流中,以便IoHandler进行处理 
            else if (bodyLength >= headLength 
                    && bodyLength + headLength <= buf.remaining()) { 
           
            log.debug("buf.limit():" + buf.limit() + " buf.remaining():" + buf.remaining());
            bytes =  new byte[buf.remaining()];
            buf.get(bytes);
            bodyLength=0;
           headLength=0;
           ctx.reset();
           buf.clear();
               
                ICBCMessage icbcMessage = new ICBCMessage();
       
                icbcMessage.setMessageBody(bytes);
        log.debug("CCBMessageDecoder bytes.lenght:" + bytes.length);
        log.debug("body: " + new String(bytes,"UTF-8"));

        ItxMessage itxMessage = convertToItxMessage(icbcMessage);

        // 一般为加密报文,故这里只做报文接收,不做格式转换
        // AcordLAHUtils.parseMessage(itxMessage, icbcMessage.getMessageBody());

        out.write(itxMessage);
        break;
       
            } else { 
                // 如果消息包不完整 
                // 将指针重新移动消息头的起始位置 
               log.debug("消息包不完整......"); 
               bytes =  new byte[buf.remaining()];
            buf.get(bytes);
            log.debug(new String(bytes,"UTF-8"));
                buf.reset(); 
                break; 
            } 
        } 
        if (buf.hasRemaining()) { 
           log.debug("###################");
            // 将数据移到buffer的最前面 
            IoBuffer temp = IoBuffer.allocate(maxPackLength) 
                    .setAutoExpand(true); 
            temp.put(buf); 
            temp.flip(); 
//             buf.clear(); 
//             buf.put(temp); 
            String content = buf.getString(ctx.getDecoder());  
            log.debug("content: " + content);
        } else {// 如果数据已经处理完毕,进行清空 
           log.debug("!!!!!!!!!!!!"); 
            buf.clear(); 
        } 
        }catch(Exception e){
        e.printStackTrace();
        log.debug(" exception failed");
        bodyLength=0;
           headLength=0;
           ctx.reset();
           buf.clear();
        }
}


return true;
}

package com.siebre.itx.ccb.codec;



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

import org.apache.mina.core.buffer.IoBuffer;


public class Context { 
    private final CharsetDecoder decoder;
    private IoBuffer buf; 
    private int msgLength = 0; 
    private int overflowPosition = 0; 
    private static Charset charset = Charset.defaultCharset();

    /**
     * 
     * 
     */ 
    public Context() { 
        decoder = charset.newDecoder(); 
        buf = IoBuffer.allocate(20000).setAutoExpand(true); 
    } 

    /**
     * 
     * 
     * @return CharsetDecoder
     */ 
    public CharsetDecoder getDecoder() { 
        return decoder; 
    } 

    /**
     * 
     * 
     * @return IoBuffer
     */ 
    public IoBuffer getBuffer() { 
        return buf; 
    } 

    /**
     * 
     * 
     * @return overflowPosition
     */ 
    public int getOverflowPosition() { 
        return overflowPosition; 
    } 

    /**
     * 
     *
     * @return matchCount
     */ 
    public int getMsgLength() { 
        return msgLength; 
    } 

    /**
     * 
     * 
     * @param matchCount
     *            报文长度
     */ 
    public void setMsgLength(int msgLength) { 
        this.msgLength = msgLength; 
    } 

    /**
     * 
     * 
     */ 
    public void reset() { 
        this.buf.clear(); 
        this.overflowPosition = 0; 
        this.msgLength = 0; 
        this.decoder.reset(); 
    } 

    /**
     * 
     * @param in
     *            输入流
     */ 
    public void append(IoBuffer in) { 
        getBuffer().put(in); 

    } 
  

猜你喜欢

转载自collegeyuan.iteye.com/blog/2121764