接受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);
}
}
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);
}
}