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