1. 消息体的作用
socket 通信时避免分包,沾包等情况,制定消息体格式
2. 定义接口类 IMessageProtocol.java
/**
* @Description: 消息数据格式
*/
public interface IMessageProtocol {
/**
* 获取包头的长度
*
* @return
*/
int getHeaderLength();
/**
* 获取数据包体的长度,根据协议包体长度应该写在包头中,在读取数据时用到
*
* @param header
* @param byteOrder
* @return
*/
int getBodyLength(byte[] header, ByteOrder byteOrder);
/**
* 根据协议打包消息格式,返回 byte 数组
* @param sender
* @return
*/
byte[] pack(byte[] sender);
}
3. 实现定义接口类,创建 DefaultMessageProtocol.java
/**
* @Description: 默认的消息协议
*/
public class DefaultMessageProtocol implements IMessageProtocol {
@Override
public int getHeaderLength() {
return 4;//包头的长度,用来保存 body 的长度值
}
@Override
public int getBodyLength(byte[] header, ByteOrder byteOrder) {
if (header == null || header.length < getHeaderLength()) {
return 0;
}
ByteBuffer byteBuffer = ByteBuffer.wrap(header);
byteBuffer.order(byteOrder);
// body 的长度以int的形式保存在 header
return byteBuffer.getInt();
}
@Override
public byte[] pack(byte[] sender) {
//消息头的长度
int headerLength = getHeaderLength();
ByteBuffer byteBuffer = ByteBuffer.allocate(headerLength + sender.length);
//以大端的形式存放数据
byteBuffer.order(ByteOrder.BIG_ENDIAN);
//存放 body 的长度
byteBuffer.putInt(sender.length);
//存放 body 内容
byteBuffer.put(sender);
return byteBuffer.array();
}
}
4. 测试方法及输出结果
//测试消息体方法
private void initMessage() {
String str = "Hello Word !";
DefaultMessageProtocol messageProtocol = new DefaultMessageProtocol();
byte[] data = messageProtocol.pack(str.getBytes());
byte[] header = {data[0], data[1], data[2], data[3]};
//byte[] header = new byte[4];
//ByteBuffer.wrap(data).get(header);
//header = data;
int bodyLength = messageProtocol.getBodyLength(header, ByteOrder.BIG_ENDIAN);
//截取数组
Log.i(TAG + "Message", "headerLength: " + header.length + " bodyLength: " + bodyLength + " dataLength: " + data.length);
//输出结果: headerLength: 4 bodyLength: 12 dataLength: 16
}