南昌市物联网技防平台-后台
Administrator
2021-03-04 a08f28be2302ce139aecb34765296e2b47afd129
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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));
        }
    }
}