Netty的编解码

一、Netty编解码

 Netty涉及到编解码的组件有Channel、ChannelHandler、ChannelPipe等,先大概了解下这几个组件的作用。

1、ChannelHandler

ChannelHandler充当了处理入站和出站数据的应用程序逻辑容器。例如,实现ChannelInboundHandler接口(或 ChannelInboundHandlerAdapter),你就可以接收入站事件和数据,这些数据随后会被你的应用程序的业务逻辑处理。当你要给连接的客户端发送响应时,也可以从ChannelInboundHandler冲刷数据。你的业务逻辑通常写在一个或者多个ChannelInboundHandler中。ChannelOutboundHandler原理一样,只不过它是用来处理出站数据的。

 

2、ChannelPipeline

ChannelPipeline 提供了ChannelHandler链的容器。

以客户端应用程序为例,如果事件的运动方向是从客户端到服务端的,那么我们称这些事件为出站的,即客户端发送给服务端的数据会通过pipeline中的一系列ChannelOutboundHandler(它的调用是从tailhead方向逐个调用每个handler的逻辑),并被这些Handler处理;反之则称为入站的,入站只调用pipeline里的 ChannelInboundHandler逻辑(它的调用是从headtail方向逐个调用每个handler的逻辑)。

扫描二维码关注公众号,回复: 8290501 查看本文章

编码解码器

       当你通过Netty发送或者接受一个消息的时候,就将会发生一次数据转换。入站消息会被解码:从字节转换为另一种格式(比如java对
象);如果是出站消息,它会被编码成字节 。

      Netty提供了一系列实用的编码解码器,他们都实现了 ChannelInboundHadnler 或者 ChannelOutcoundHandler 接口 。

      Netty提供了很多编解码器,比如编解码字符串的 StringEncoderStringDecoder,编解码对象的 ObjectEncoderObjectDecoder 

当然也可以通过集成MessageToByteDecoder自定义编解码器。

二、Netty粘包拆包

1、粘包的现象

TCP粘包拆包是指发送方发送的若干包数据到接收方接收时粘成一包或某个数据包被拆开接收。如下图所示,client发了两个数据包D1和D2,但是server端可能会收到如下几种情况的数据。

2、为什么出现粘包现象

TCP 是面向连接的, 面向流的, 提供高可靠性服务。 收发两端(客户端和服务器端) 都要有成对的 socket,因此, 发送端为了将多个发给接收端的包, 更有效的发给对方, 使用了优化方法(Nagle 算法),将多次间隔较小且数据量小的数据, 合并成一个大的数据块,然后进行封包。 这样做虽然提高了效率, 但是接收端就难于分辨出完整的数据包了, 因为面向流的通信是无消息保护边界的。

3、解决方案

(1)格式化数据:每条数据有固定的格式(开始符、结束符),这种方法简单易行,但选择开始符和结束符的时候一定要注意每条数据的内部一定不能出现开始符或结束符。
(2)发送长度:发送每条数据的时候,将数据的长度一并发送,比如可以选择每条数据的前4位是数据的长度,应用层处理时可以根据长度来判断每条数据的开始和结束。
第二种方案更稳妥;



猜你喜欢

转载自www.cnblogs.com/yufeng218/p/12088723.html