for (int i = 0; i < size; i ++) { // 重点,获取到解码的数据后在进行传播 ctx.fireChannelRead(out.get(i)); } out.recycle(); } } else { // 非ByteBuf类型,则直接继续传播 ctx.fireChannelRead(msg); } }
protectedvoidcallDecode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out){ try { // 读取所有数据,知道读完为止 while (in.isReadable()) { int outSize = out.size(); // 记录当前可读数据长度,后续需要用到这个判断每一次的读写是否完成 // 用于处理半包的情况,如果未半包。则不再继续,等到下次在进行处理 int oldInputLength = in.readableBytes(); //调用子类实现进行解码 decode(ctx, in, out);
// Check if this handler was removed before continuing the loop. // If it was removed, it is not safe to continue to operate on the buffer. // // See https://github.com/netty/netty/issues/1664 if (ctx.isRemoved()) { break; } // 如果decode读到了数据,那么out里面肯定就有值了,这里肯定就不糊相等 // 如果decode没有读取到数据,那么这里则会相等,然后在判断所读取的数据是否与之前相当,相等说以个字节的数据都没有读取完,可能存在半包的问题,则直接跳出 if (outSize == out.size()) { if (oldInputLength == in.readableBytes()) { break; } else { continue; } }
if (oldInputLength == in.readableBytes()) { thrownew DecoderException( StringUtil.simpleClassName(getClass()) + ".decode() did not read anything but decoded a message."); }
/** * A decoder that splits the received {@link ByteBuf}s by the fixed number * of bytes. For example, if you received the following four fragmented packets: * <pre> * +---+----+------+----+ * | A | BC | DEFG | HI | * +---+----+------+----+ * </pre> * A {@link FixedLengthFrameDecoder}{@code (3)} will decode them into the * following three packets with the fixed length: * <pre> * +-----+-----+-----+ * | ABC | DEF | GHI | * +-----+-----+-----+ * </pre> */ publicclassFixedLengthFrameDecoderextendsByteToMessageDecoder{
privatefinalint frameLength;
/** * Creates a new instance. * * @param frameLength the length of the frame */ publicFixedLengthFrameDecoder(int frameLength){ if (frameLength <= 0) { thrownew IllegalArgumentException( "frameLength must be a positive integer: " + frameLength); } this.frameLength = frameLength; }
/** * Create a frame out of the {@link ByteBuf} and return it. * * @param ctx the {@link ChannelHandlerContext} which this {@link ByteToMessageDecoder} belongs to * @param in the {@link ByteBuf} from which to read data * @return frame the {@link ByteBuf} which represent the frame or {@code null} if no frame could * be created. */ protected Object decode( @SuppressWarnings("UnusedParameters") ChannelHandlerContext ctx, ByteBuf in) throws Exception { if (in.readableBytes() < frameLength) { returnnull; } else { return in.readSlice(frameLength).retain(); } } }