如何在Netty 4中添加头部和尾部定界符帧解码器?

如何在Netty 4中添加头部和尾部定界符帧解码器?,netty,Netty,我刚开始在Netty 4上编码,发现它似乎只支持单数分隔符,尽管它声称支持多个分隔符。事实上,它支持交替使用多个分隔符,而不是同时使用 我之所以需要头部和尾部分隔符,是为了在出现数据包丢失或接收到的数据包出现故障时提高速度。 例如,我的帧看起来如下:${LEN}{DATA}\r\n 因此,我的头分隔符是$,而尾分隔符是\r\n 假设在一个帧中接收到多个数据包,而一些中间数据包在传输过程中丢失,如果没有$,解码器必须继续搜索\r\n以确定结束。如果\r\n也丢失了,那么它必须搜索下一条消息,\r\

我刚开始在Netty 4上编码,发现它似乎只支持单数分隔符,尽管它声称支持多个分隔符。事实上,它支持交替使用多个分隔符,而不是同时使用

我之所以需要头部和尾部分隔符,是为了在出现数据包丢失或接收到的数据包出现故障时提高速度。 例如,我的帧看起来如下:${LEN}{DATA}\r\n

因此,我的头分隔符是$,而尾分隔符是\r\n

假设在一个帧中接收到多个数据包,而一些中间数据包在传输过程中丢失,如果没有$,解码器必须继续搜索\r\n以确定结束。如果\r\n也丢失了,那么它必须搜索下一条消息,\r\n而不是点击导致新消息的$

但似乎现有的Netty FrameDecoder无法支持上面我想要的内容。我应该如何实现我自己的目标


在我看来,Netty FrameDecoder的设计没有考虑到数据包丢失或打包机缺货的情况?我和内蒂在这方面可能是错的。如果有人能告诉我这一点,请原谅。

我认为DelimiterFrameDecoder假定输入流是无损有序的。如果管道中的较低级别传输层不是无损有序连接,然后,您需要实现自己的帧解码器,通过实现校验和和、帧ID或其他一些协议策略来处理丢失的数据和无序帧。

我最终使用了Netty的LengthFieldBasedFrameDecoder,以实现对客户端和服务器端数据包帧解码都很重要的简洁性和效率。我的邮件的格式如下:\r\n$LEN$DATA\r\n$LEN$DATA

ChannelPipeline p = ch.pipeline();
p.addLast(new LengthFieldBasedFrameDecoder(1024,2,4,0,6)); 

根据客户端环境的不同,Netty库可能用于客户端连接和通信,也可能不用于客户端连接和通信。但是有了这种消息结构,通过编写一个相对健壮和高效的帧解码代码总是可以轻松实现。

在嘈杂的无线网络环境中,数据包丢失或无序是很常见的。但我认为Netty中提供的DelimiterFrameDecoder或其他DelimiterFrameDecoder确实支持从混合有损坏或丢失字节的传入字节流中恢复(我指的是最终找到正确起始数据包的能力)。对我来说,这些解码器之间的主要区别在于效率:1)定位新的良好开端数据包的速度;2) 在获得好的数据包时浪费更少的字节;但是我发现了一种使用LengthFieldBasedFrameDecoder的更简单的方法。此外,对于数据包损坏或丢失,我实现了应用程序级逻辑,通过依赖接收方的ACK消息来执行有保证的消息传递。当然,在接收ACK之前必须先缓存消息,并在从接收方接收ACK后将其删除。您使用的是udp流还是tcp流?在udp流上,您通常不会重新触发接收到的bytestcp流:服务器在云数据中心运行,客户端设备通过WiFi LAN或3G/2G SIM移动无线WAN连接。因此,网络可能不稳定,容易受到网络干扰的影响,而网络干扰通常会导致数据包丢失……请注意,tcp保证数据保持原样(因此无需修改),或者连接错误。这意味着数据包的任何部分都不会丢失TTCP不能保证传递,但它可以保证数据包将在超时(4分钟IIRC)内被传递和确认,或者您将得到错误响应。如果出现错误(例如数据包丢失),Netty会引发异常和/或忽略丢失的数据包,但会继续读取其他数据包……无论哪种情况,数据包丢失都会发生,特别是在无线环境中,使用良好的帧分隔符解码器是我们在设计中应该做出的技术选择。