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

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

三、解决 Netty 粘包问题


在 Netty 中,解决粘包问题的常用方案有以下 3 种:


  1. 设置固定大小的消息长度,如果长度不足则使用空字符弥补,它的缺点比较明显,比较消耗网络流量,因此不建议使用;


  1. 使用分隔符来确定消息的边界,从而避免粘包和半包问题的产生;


  1. 将消息分为消息头和消息体,在头部中保存有当前整个消息的长度,只有在读取到足够长度的消息之后才算是读到了一个完整的消息。


接下来我们分别来看后两种推荐的解决方案。


1.使用分隔符解决粘包问题


在 Netty 中提供了 DelimiterBasedFrameDecoder 类用来以特殊符号作为消息的结束符,从而解决粘包和半包的问题。


它的核心实现代码是在初始化通道(Channel)时,通过设置


DelimiterBasedFrameDecoder 来分隔消息,需要在客户端和服务器端都进行设置,具体实现代码如下。


服务器端核心实现代码如下:


/**
 * 服务端通道初始化
 */
static class ServerInitializer extends ChannelInitializer<SocketChannel> {
    // 字符串编码器和解码器
    private static final StringDecoder DECODER = new StringDecoder();
    private static final StringEncoder ENCODER = new StringEncoder();
    // 服务器端连接之后的执行器(自定义的类)
    private static final ServerHandler SERVER_HANDLER = new ServerHandler();
    /**
     * 初始化通道的具体执行方法
     */
    @Override
    public void initChannel(SocketChannel ch) {
        // 通道 Channel 设置
        ChannelPipeline pipeline = ch.pipeline();
        // 19 行:设置结尾分隔符【核心代码】(参数1:为消息的最大长度,可自定义;参数2:分隔符[此处以换行符为分隔符])
        pipeline.addLast(new DelimiterBasedFrameDecoder(1024, Delimiters.lineDelimiter()));
        // 设置(字符串)编码器和解码器
        pipeline.addLast(DECODER);
        pipeline.addLast(ENCODER);
        // 服务器端连接之后的执行器,接收到消息之后的业务处理
        pipeline.addLast(SERVER_HANDLER);
    }
}


核心代码为第 19 行,代码中已经备注了方法的含义,这里就不再赘述。

客户端的核心实现代码如下:


/**
 * 客户端通道初始化类
 */
static class ClientInitializer extends ChannelInitializer<SocketChannel> {
    // 字符串编码器和解码器
    private static final StringDecoder DECODER = new StringDecoder();
    private static final StringEncoder ENCODER = new StringEncoder();
    // 客户端连接成功之后业务处理
    private static final ClientHandler CLIENT_HANDLER = new ClientHandler();
    /**
     * 初始化客户端通道
     */
    @Override
    public void initChannel(SocketChannel ch) {
        ChannelPipeline pipeline = ch.pipeline();
        // 17 行:设置结尾分隔符【核心代码】(参数1:为消息的最大长度,可自定义;参数2:分隔符[此处以换行符为分隔符])
        pipeline.addLast(new DelimiterBasedFrameDecoder(1024, Delimiters.lineDelimiter()));
        // 设置(字符串)编码器和解码器
        pipeline.addLast(DECODER);
        pipeline.addLast(ENCODER);
        // 客户端连接成功之后的业务处理
        pipeline.addLast(CLIENT_HANDLER);
    }
}
相关文章
|
3月前
|
网络协议
【Netty 网络通信】Socket 通信原理
【1月更文挑战第9天】【Netty 网络通信】Socket 通信原理
|
4月前
|
编解码 缓存 移动开发
TCP粘包/拆包与Netty解决方案
TCP粘包/拆包与Netty解决方案
45 0
|
7月前
|
移动开发 网络协议 算法
由浅入深Netty粘包与半包解决方案
由浅入深Netty粘包与半包解决方案
50 0
|
13天前
|
网络协议 Java 物联网
Spring Boot与Netty打造TCP服务端(解决粘包问题)
Spring Boot与Netty打造TCP服务端(解决粘包问题)
26 1
|
3月前
|
编解码
Netty Review - 优化Netty通信:如何应对粘包和拆包挑战_自定义长度分包编解码码器
Netty Review - 优化Netty通信:如何应对粘包和拆包挑战_自定义长度分包编解码码器
46 0
|
3月前
|
网络协议
Netty Review - 优化Netty通信:如何应对粘包和拆包挑战
Netty Review - 优化Netty通信:如何应对粘包和拆包挑战
50 0
|
4月前
|
存储 网络协议 算法
Netty使用篇:半包&粘包
Netty使用篇:半包&粘包
|
5月前
|
监控
在Netty底层监控消息发送到Socket的时间
在Netty底层监控消息发送到Socket的时间
38 0
|
8月前
|
网络协议 网络安全
python-- socket 粘包、实现 ssh
python-- socket 粘包、实现 ssh
|
8月前
|
Nacos
Netty自定义消息协议的实现逻辑处理粘包拆包、心跳机制
Netty自定义消息协议的实现逻辑处理粘包拆包、心跳机制
106 0