package org.springblade.jfpt.nettyTcpServer;
|
|
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.Unpooled;
|
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.handler.codec.ByteToMessageDecoder;
|
import java.util.List;
|
|
/**
|
* 自定义解码器
|
*
|
*/
|
public class MyNettyDecode extends ByteToMessageDecoder {
|
public final int BASE_LENGTH = 4 + 4 ;
|
|
// @Override
|
// protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
|
// System.out.println("byteBuf = " + byteBuf.readableBytes());
|
// // 可读长度必须大于基本长度
|
// if (byteBuf.readableBytes() >= BASE_LENGTH) {
|
// // 防止socket字节流攻击
|
// // 防止,客户端传来的数据过大
|
// // 因为,太大的数据,是不合理的
|
// if (byteBuf.readableBytes() > 202048) {
|
// byteBuf.skipBytes(byteBuf.readableBytes());
|
// }
|
//
|
// // 记录包头开始的index
|
// int beginReader;
|
//
|
// while (true) {
|
// // 获取包头开始的index
|
// beginReader = byteBuf.readerIndex();
|
// // 标记包头开始的index
|
// byteBuf.markReaderIndex();
|
// // 读到了协议的开始标志,结束while循环
|
// if (byteBuf.readInt() == NettyConstant.HEAD_DATA) {
|
// break;
|
// }
|
//
|
// // 未读到包头,略过一个字节
|
// // 每次略过,一个字节,去读取,包头信息的开始标记
|
// byteBuf.resetReaderIndex();
|
// byteBuf.readByte();
|
//
|
// // 当略过,一个字节之后,
|
// // 数据包的长度,又变得不满足
|
// // 此时,应该结束。等待后面的数据到达
|
// if (byteBuf.readableBytes() < BASE_LENGTH) {
|
// return;
|
// }
|
// }
|
//
|
// // 消息的长度
|
//
|
// int length = byteBuf.readInt();
|
// // 判断请求数据包数据是否到齐
|
// if (byteBuf.readableBytes() < length) {
|
// // 还原读指针
|
// byteBuf.readerIndex(beginReader);
|
// return;
|
// }
|
//
|
// // 读取data数据
|
// byte[] data = new byte[length];
|
// byteBuf.readBytes(data);
|
// System.out.println("byteBuf末尾 = " + byteBuf);
|
//
|
// NettyProPool protocol = new NettyProPool(data.length, data);
|
// list.add(protocol);
|
// System.out.println("list = " + list);
|
// }
|
// }
|
|
static final int PACKET_SIZE = 110088;
|
|
// 用来临时保留没有处理过的请求报文
|
ByteBuf tempMsg = Unpooled.buffer();
|
|
/**
|
* @param ctx
|
* @param in 请求的数据
|
* @param out 将粘在一起的报文拆分后的结果保留起来
|
* @throws Exception
|
*/
|
@Override
|
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
|
System.out.println(Thread.currentThread() + "收到了一次数据包,长度是:" + in.readableBytes());
|
|
// 合并报文
|
ByteBuf message = null;
|
int tmpMsgSize = tempMsg.readableBytes();
|
System.out.println("tmpMsgSize = " + tmpMsgSize);
|
// 如果暂存有上一次余下的请求报文,则合并
|
if (tmpMsgSize > 0) {
|
message = Unpooled.buffer();
|
message.writeBytes(tempMsg);
|
message.writeBytes(in);
|
System.out.println("合并:上一数据包余下的长度为:" + tmpMsgSize + ",合并后长度为:" + message.readableBytes());
|
} else {
|
message = in;
|
}
|
|
int size = message.readableBytes();
|
int counter = size / PACKET_SIZE;
|
for (int i = 0; i < counter; i++) {
|
byte[] request = new byte[PACKET_SIZE];
|
// 每次从总的消息中读取220个字节的数据
|
message.readBytes(request);
|
|
// 将拆分后的结果放入out列表中,交由后面的业务逻辑去处理
|
out.add(Unpooled.copiedBuffer(request));
|
}
|
|
// 多余的报文存起来
|
// 第一个报文: i+ 暂存
|
// 第二个报文: 1 与第一次
|
size = message.readableBytes();
|
if (size != 0) {
|
System.out.println("多余的数据长度:" + size);
|
// 剩下来的数据放到tempMsg暂存
|
tempMsg.clear();
|
tempMsg.writeBytes(message.readBytes(size));
|
}
|
}
|
}
|