com.zusmart.base.network.message.fixedlength.FixedLengthMessageProtocol Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of zusmart-base Show documentation
Show all versions of zusmart-base Show documentation
提供基础的工具类及方法类,Logging,Scanner,Buffer,NetWork,Future,Thread
package com.zusmart.base.network.message.fixedlength;
import java.util.ArrayList;
import java.util.List;
import com.zusmart.base.buffer.Buffer;
import com.zusmart.base.buffer.support.ByteArrayBuffer;
import com.zusmart.base.buffer.support.LinkedBuffer;
import com.zusmart.base.network.message.Message;
import com.zusmart.base.network.message.MessageEncodeException;
import com.zusmart.base.network.message.MessageProtocol;
import com.zusmart.base.network.message.support.SkipMessage;
/**
* 支持大文件分包,但不建议传输大文件
*
* @author Administrator
*
*/
public class FixedLengthMessageProtocol implements MessageProtocol {
private static final int HEAD_LENGTH = 4 + 1 + 4 + 4;
private static final byte MSG_TYPE_HEAD = 1;
private static final byte MSG_TYPE_BODY = 2;
private static final byte MSG_TYPE_FOOT = 3;
private static final byte MSG_TYPE_FULL = 4;
private final int maxLength;
private byte[] head;
private byte[] foot;
private List body;
public FixedLengthMessageProtocol(int maxLength) {
this.maxLength = maxLength;
}
public FixedLengthMessageProtocol() {
this.maxLength = 1024 * 8;
}
@Override
public Buffer encode(Message message) throws Exception {
if (null == message) {
return null;
}
if (message instanceof FixedLengthMessage) {
FixedLengthMessage msg = (FixedLengthMessage) message;
if (null == msg.getContent() || msg.getContent().length == 0) {
throw new MessageEncodeException("message content is blank");
}
return split(this.maxLength, msg.getContent());
}
return null;
}
@Override
public Message decode(Buffer buffer) throws Exception {
if (null == buffer) {
return null;
}
if (buffer.remaining() < HEAD_LENGTH) {
return null;
}
int length = buffer.getInt();
if (length < 0) {
return null;
}
byte type = buffer.get();
int start = buffer.getInt();
int end = buffer.getInt();
byte[] content = new byte[end - start];
if (type == MSG_TYPE_FULL) {
buffer.get(content);
return new FixedLengthMessage(content);
} else if (type == MSG_TYPE_HEAD) {
buffer.get(content);
this.head = content;
return SkipMessage.INSTANCE;
} else if (type == MSG_TYPE_FOOT) {
buffer.get(content);
this.foot = content;
byte[] value = merge(this.head, this.foot, this.body);
this.head = null;
this.foot = null;
this.body = null;
return new FixedLengthMessage(value);
} else {
buffer.get(content);
if (null == this.body) {
this.body = new ArrayList();
}
this.body.add(content);
return SkipMessage.INSTANCE;
}
}
private static final byte[] merge(byte[] head, byte[] foot, List body) {
int total = 0;
if (null != head) {
total += head.length;
}
if (null != foot) {
total += foot.length;
}
if (null != body && body.size() > 0) {
for (byte[] data : body) {
total += data.length;
}
}
byte[] content = new byte[total];
int start = 0;
if (null != head) {
System.arraycopy(head, 0, content, start, head.length);
start += head.length;
}
if (null != body && body.size() > 0) {
for (byte[] data : body) {
System.arraycopy(data, 0, content, start, data.length);
start += data.length;
}
}
if (null != foot) {
System.arraycopy(foot, 0, content, start, foot.length);
start += foot.length;
}
return content;
}
private static final Buffer split(int maxLength, byte[] content) {
int length = content.length;
int packet = maxLength - HEAD_LENGTH;// 单包总包长度 - 头信息长度
if (length < maxLength) {
Buffer buffer = ByteArrayBuffer.allocate(length + HEAD_LENGTH);
buffer.putInt(length);
buffer.put(MSG_TYPE_FULL);
buffer.putInt(0);
buffer.putInt(length);
buffer.put(content);
return buffer;
}
int page = (length + packet - 1) / packet;
Buffer[] buffers = new Buffer[page];
for (int i = 0; i < buffers.length; i++) {
int start = i * packet;
int end = i + 1 == page ? length : (i + 1) * packet;
int len = end - start;
Buffer buffer = ByteArrayBuffer.allocate(len + HEAD_LENGTH);
buffer.putInt(length);
if (i == 0) {
buffer.put(MSG_TYPE_HEAD);
} else if (i == page - 1) {
buffer.put(MSG_TYPE_FOOT);
} else {
buffer.put(MSG_TYPE_BODY);
}
byte[] temp = new byte[len];
System.arraycopy(content, start, temp, 0, temp.length);
buffer.putInt(start);
buffer.putInt(end);
buffer.put(temp);
buffers[i] = buffer.flip();
}
Buffer buffer = new LinkedBuffer(buffers);
buffer.position(buffer.limit());
return buffer;
}
}