在使用Netty进行通信开发,如何选择编码器?在TCP粘包/拆包的问题如何解决?服务端在启动 流程是什么样的?连接服务流程是什么?
在网络传输的过程中,数据都是以字节流的方式进行传递。客户端在进行数据传递的时候 将原来的数据格式转化为字节,叫编码。服务端将字节转化为原来的格式,叫解码。统称 codec。 编解码器分为两部分-编码器和解码器,编码器负责出站,解码器负责入站。
解码器负责入站操作,那么也一定要实现ChannelInboundHandler接口,所以解码器本质 上也是ChannelHandler。我们自定义编解码器只需要继承ByteToMessageDecoder(Netty提供抽象类,继承 ChannelInboundHandlerAdapter),实现decode()。Netty提供一些常用的解码器实现, 开箱即用。如下:
Netty也提供了MessageToMessageDecoder,将⼀种格式转化为另⼀种格式的解码器,也提供了⼀些 实现,如下:
1 字节解码器
2 Handler
3 在pipeline中添加解码器
将原来的格式转化为字节。我们要实现自定义解码器只要继承MessageToByteEncoder (实现了ChannelOutboundHandler接⼝),本质上也是ChannelHandler。 Netty中一些实现的编码器,如下:
Netty也提供了MessageToMessageEncoder,将⼀种格式转化为另⼀种格式的编码器,也提供了⼀些 实现:
通过Netty中提供的http的解码器,进行http服务器开发。
JDK序列化使⽤是⽐较⽅便,但是性能较差,序列化后的字节⽐较⼤,所以⼀般在项⽬中不 会使⽤⾃带的序列化,⽽是会采⽤第三⽅的序列化框架Hessian编解码。
2. 使用ReplayingDecoder进行优化
继承ReplayingDecoder,错误示例和修改
ByteToIntegerDecoder2的实现
TCP是流传递的,所谓流,就是没有界限的数据。服务端接受客户端数据,并不知道是一条还是多条。 服务端如何拆包并不知道。
因此服务端和客户端进行数据传递的时候,要制定好拆包规则。客户端按照该规则进行粘包,服务端 按照该规则拆包。如果有任意违背该规则,服务端就不能拿到预期的数据。
什么时候进⾏更新selector的主从事件?最终在io.netty.channel.nio.AbstractNioChannel#doBeginRead()⽅法中完成的
而不是使用hannel.writeAndFlush(data);EventLoop的任务调度直接放入到channel所对应的EventLoop的执行队列,后者会导致线程切换。备注:在writeAndFlush的底层,如果没有通过eventLoop执行的话,就会启动新的线程。
如果channelhandler是⽆状态的(即不需要保存任何状态参数),那么使⽤Sharable注解,并在 bootstrap时只创建⼀个实例,减少GC。否则每次连接都会new出handler对象。
注意:ByteToMessageDecoder之类的编解码器是有状态的,不能使⽤Sharable注解。
更多Java相关内容。请关注微信公众号 花花与Java
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。