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);

}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值