Socket粘包问题终极解决方案—Netty版(2W字)! (6)

最终的执行结果如下图所示:

image.png


从上述结果中可以看出,Netty 可以正常使用了,它已经不存在粘包和半包问题了。

2.封装消息解决粘包问题

此解决方案的核心是将消息分为消息头 + 消息体,在消息头中保存消息体的长度,从而确定一条消息的边界,这样就避免了粘包和半包问题了,它的实现过程如下图所示:

image.png


在 Netty 中可以通过 LengthFieldPrepender(编码)和 LengthFieldBasedFrameDecoder(解码)两个类实现消息的封装。和上一个解决方案类似,我们需要分别在服务器端和客户端通过设置通道(Channel)来解决粘包问题。

服务器端的核心代码如下:

/** * 服务端通道初始化 */ static class ServerInitializer extends ChannelInitializer<SocketChannel> { // 字符串编码器和解码器 private static final StringDecoder DECODER = new StringDecoder(); private static final StringEncoder ENCODER = new StringEncoder(); // 服务器端连接之后的执行器(自定义的类) private static final NettyExample.ServerHandler SERVER_HANDLER = new NettyExample.ServerHandler(); /** * 初始化通道的具体执行方法 */ @Override public void initChannel(SocketChannel ch) { // 通道 Channel 设置 ChannelPipeline pipeline = ch.pipeline(); // 18 行:消息解码:读取消息头和消息体 pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 0, 4, 0, 4)); // 20 行:消息编码:将消息封装为消息头和消息体,在消息前添加消息体的长度 pipeline.addLast(new LengthFieldPrepender(4)); // 设置(字符串)编码器和解码器 pipeline.addLast(DECODER); pipeline.addLast(ENCODER); // 服务器端连接之后的执行器,接收到消息之后的业务处理 pipeline.addLast(SERVER_HANDLER); } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzfpwx.html