`
san_yun
  • 浏览: 2638600 次
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

FrameDecoder介绍

 
阅读更多

FrameDecoder 负责 decodes the received ChannelBuffer s into a meaningful frame object.

In a stream-based transport such as TCP/IP, packets can be fragmented and reassembled during transmission even in a LAN environment. For example, let us assume you have received three packets:

 +-----+-----+-----+
 | ABC | DEF | GHI |
 +-----+-----+-----+
 

because of the packet fragmentation, a server can receive them like the following:

 +----+-------+---+---+
 | AB | CDEFG | H | I |
 +----+-------+---+---+
 

FrameDecoder   helps you defrag the received packets into one or more meaningful  frames   that could be easily understood by the application logic. In case of the example above, your  FrameDecoder   implementation could defrag the received packets like the following:

 +-----+-----+-----+
 | ABC | DEF | GHI |
 +-----+-----+-----+
 

The following code shows an example handler which decodes a frame whose first 4 bytes header represents the length of the frame, excluding the header.

 MESSAGE FORMAT
 ==============

 Offset:  0        4                   (Length + 4)
          +--------+------------------------+
 Fields:  | Length | Actual message content |
          +--------+------------------------+

 DECODER IMPLEMENTATION
 ======================

 public class IntegerHeaderFrameDecoder extends FrameDecoder {

   protected Object decode(ChannelHandlerContext ctx,
                           Channel channel,
                           ChannelBuffer buf) throws Exception {

     // Make sure if the length field was received.
     if (buf.readableBytes() < 4) {
        // The length field was not received yet - return null.
        // This method will be invoked again when more packets are
        // received and appended to the buffer.
        return null

;
     }

     // The length field is in the buffer.

     // Mark the current buffer position before reading the length field
     // because the whole frame might not be in the buffer yet.
     // We will reset the buffer position to the marked position if
     // there's not enough bytes in the buffer.
     buf.markReaderIndex();

     // Read the length field.
     int length = buf.readInt();

     // Make sure if there's enough bytes in the buffer.
     if (buf.readableBytes() < length) {
        // The whole bytes were not received yet - return null.
        // This method will be invoked again when more packets are
        // received and appended to the buffer.

        // Reset to the marked position to read the length field again
        // next time.
        buf.resetReaderIndex();

        return null

;
     }

     // There's enough bytes in the buffer. Read it.
     ChannelBuffer frame = buf.readBytes(length);

     // Successfully decoded a frame.  Return the decoded frame.
     return frame

;
   }
 }
 

Returning a POJO rather than a  ChannelBuffer

Please note that you can return an object of a different type than  ChannelBuffer   in your  decode()   and  decodeLast() implementation. For example, you could return a  POJO   so that the next  ChannelUpstreamHandler   receives a  MessageEvent which contains a POJO rather than a  ChannelBuffer .

Replacing a decoder with another decoder in a pipeline

If you are going to write a protocol multiplexer, you will probably want to replace a  FrameDecoder   (protocol detector) with another  FrameDecoder   or  ReplayingDecoder   (actual protocol decoder). It is not possible to achieve this simply by callingChannelPipeline.replace(ChannelHandler, String, ChannelHandler) , but some additional steps are required:

 public class FirstDecoder extends FrameDecoder {

     public FirstDecoder() {
         super(true); // Enable unfold
     }

     protected Object decode(ChannelHandlerContext ctx, Channel ch, ChannelBuffer buf) {
         ...
         // Decode the first message
         Object firstMessage = ...;

         // Add the second decoder
         ctx.getPipeline().addLast("second", new SecondDecoder());

         // Remove the first decoder (me)
         ctx.getPipeline().remove(this);

         if (buf.readable()) {
             // Hand off the remaining data to the second decoder
             return new Object[] { firstMessage, buf.readBytes(buf.readableBytes()) };
         } else {
             // Nothing to hand off
             return firstMessage;
         }
     }
 }

 

分享到:
评论

相关推荐

    粘包和分包及FrameDecoder源码解析.rar

    在提供的压缩包文件"粘包和分包及FrameDecoder源码解析.rar"中,你将能够找到对`FrameDecoder`源码的深入分析视频和相关的示例项目。通过观看视频和运行示例,你可以更好地理解`FrameDecoder`的工作原理,以及如何在...

    netty-frameDecoder:换行符,自定义分隔符,定长度解码器

    netty-frameDecoder换行符,自定义分隔符,定长度解码器说明使用tcp传送数据,由于缓存区大小的设置,MSS的tcp分段等因素,数据传输时会出现TCP粘包/拆包的问题。但是底层的tcp无法理解上层的业务数据,所以在底层也...

    mina和protobuf整合教程

    《mina和protobuf整合教程》 在Java开发领域,MINA(Multi-purpose Infrastructure for Network Applications)是一个功能强大的网络应用框架,而Protocol Buffers是Google推出的一种高效的数据序列化协议。...

    C#简易串口调试软件-零壹电子

    在本文中,我们将深入探讨如何使用C#语言开发一个简易串口调试软件,该软件具有发送和接收数据的功能。此项目特别关注了串口通信、UI界面美化以及UI进程分离等关键技术。 首先,让我们了解串口通信的基础。...

    Netty源码阅读笔记

    Netty提供了多种不同策略的FrameDecoder实现,如基于分隔符的FrameDecoder和基于长度字段的FrameDecoder。 最后,ReplayingDecoder是Netty中一个特殊的解码器,它利用了ChannelBuffer的标记和重放特性,简化了粘包...

    netty 心跳检测

    本示例将详细介绍Netty如何实现心跳检测。 在Netty中,心跳检测通常通过自定义的`FrameDecoder`、`FrameEncoder`和`ChannelInboundHandler`来完成。下面我们将逐步解释这些组件的作用以及如何构建心跳检测机制。 1...

    netty源码阅读笔记.pdf

    11. **FrameDecoder**:FrameDecoder是Netty中用于解码网络数据包的组件,它将接收到的数据分割成有意义的帧。例如,DelimiterBasedFrameDecoder基于分隔符解码,而LengthFieldBasedFrameDecoder则根据长度字段进行...

    netty基于protobuf的简单示例

    服务端通过 `ProtobufVarint32FrameDecoder` 和 `ProtobufDecoder` 解码接收到的数据,然后通过 `ServerHandler` 处理业务逻辑。同样地,我们需要用 `ProtobufVarint32LengthFieldPrepender` 和 `ProtobufEncoder` ...

    DotNetty系列四:自定义协议,序列化类库MessagePack,项目代码

    例如,我们可能会定义一个`FrameDecoder`来分割接收到的数据,以及一个`FrameEncoder`来编码待发送的消息。这些处理器应该能识别并解析特定格式的报头,然后处理消息体。 在自定义协议中引入MessagePack,我们需要...

    Unity socket 案例包含粘包处理

    下面将详细介绍Unity中的Socket通信以及粘包处理的相关知识。 Unity中的Socket通信: Socket是网络编程的基础,它提供了一种进程间通信的方式,使得运行在不同计算机上的程序能够通过网络交换数据。在Unity中,我们...

    netty搭建tcp服务,粘拆包解决

    2. **使用FrameDecoder**:Netty的ChannelInboundHandlerAdapter中有多个预定义的解码器,例如LengthFieldBasedFrameDecoder,它可以基于前导长度字段来拆分消息。用户需要指定长度字段的位置、长度、偏移量等参数,...

    Netty面试专题1

    以上就是Netty面试专题1中的核心知识点,包括对BIO、NIO、AIO的理解,NIO组件的详细说明,Netty线程模型,TCP粘包/拆包问题的解决,以及序列化协议的介绍。理解这些内容对于深入学习Netty和提升网络编程技能至关重要...

    netty 断线重连

    下面将详细介绍如何使用Netty实现心跳检测以及断线后的自动重连功能。 1. **心跳机制** - 心跳包:在网络通信中,心跳包用于检测连接的活性。当连接长时间没有数据传输时,双方可以通过发送心跳包来确认对方是否还...

    project.7z

    其中服务器端可能已经实现了自定义的编解码器,但遇到了TCP粘包的问题,这需要开发者深入理解TCP协议,优化编码解码过程,或者利用Netty提供的解决方案,如使用合适的FrameDecoder来避免粘包问题。客户端部分则可能...

    Java面试题10道Java高级必备的Netty面试题!.pdf

    - 如何处理粘包和拆包问题,以及如何选择合适的FrameDecoder? 6. **零拷贝** - 什么是零拷贝?Netty是如何实现零拷贝的? - 零拷贝在什么场景下能显著提高性能? 7. **心跳机制** - 在Netty中如何实现心跳...

    Netty4的一些技术栈示例代码并辅以博文讲解

    Netty 提供了 ProtobufVarint32FrameDecoder 和 ProtobufDecoder 等组件,方便在 Netty 应用中使用 Protobuf 进行数据传输。 通过学习这些示例代码和相关博客,开发者可以深入理解 Netty 的工作原理,提高网络编程...

    NettyDemo Netty使用实例,对象传递调用

    为了解决这个问题,Netty提供了一些内置的FrameDecoder,如LineBasedFrameDecoder。LineBasedFrameDecoder通过识别消息中的特定分隔符(通常是换行符\n或回车换行符\r\n)来分割数据包。这样,我们可以确保每个接收...

    netty实现简单的聊天

    然而,这也意味着需要处理TCP粘包和拆包问题,通过自定义的FrameDecoder可以解决这个问题,确保每条消息都能正确解析。 在Android环境下使用Netty,需要注意线程安全和内存管理,因为Android的主线程不能进行耗时...

    Spring Boot中使用RSocket的示例代码

    .frameDecoder(PayloadDecoder.ZERO_COPY) .transport(TcpClientTransport.create(7000)) .start() .block(); } @Bean RSocketRequester rSocketRequester(RSocketStrategies rSocketStrategies) { return ...

    netty+protobuf入门案例

    可以使用 ` ProtobufVarint32FrameDecoder` 和 `ProtobufEncoder` 分别进行解码和编码。 4. **编写业务逻辑**:在处理器中,你可以使用 Protobuf 生成的 Java 类进行数据操作。比如,接收一个 `Person` 消息,处理...

Global site tag (gtag.js) - Google Analytics