Netty框架之TCP粘包/半包解决方案


谈到TCP粘包/半包的解决方案,我们不妨先认识造成TCP粘包/半包的原因有哪些,以便于更深刻理解解决方案的原理

一.TCP粘包

1.现象:发送:abc,def,接收:abcdef
2.原因:

  • 应用层:接受数据的Bytebuf缓冲区设置太大(Netty默认为1024)存储了多个TCP包,一次性取的时候取出缓冲区所有数据,导致多个包粘在一起.
  • 滑动窗口:发送方发送消息太快,接收方接收消息也快,但是处理消息太慢,并且接收窗口足够大,那么此时消息就会堆积在接收窗口,那么就会导致多个包粘在一起
  • Nagle算法:Nagle算法是操作系统底层自动实现的,为了减少发送次数,提高效率,操作系统会在缓冲区未满的时候等待消息填充,直到缓冲区满的时候一并发送,造成粘包

二.TCP半包

1.现象:发送:abcdef,接收:abc,def
2.原因:

  • 应用层:接受数据的Bytebuf缓冲区设置太小(Netty默认为1024)存储不了一个完整的TCP包,一次性只能取出TCP包的部分数据
  • 滑动窗口:发送方发送窗口较大,接收方接收窗口较小,导致接收方只能接收TCP包的部分数据,导致TCP半包
  • MSS限制:为了限制TCP包的大小,会将大的TCP包分组成多个小的TCP包发送,导致半包问题

三.TCP粘包/半包解决方案

1.FixedLengthFrameDecoder定长解析器

向pipeline中加入FixedLengthFrameDecoder(int length)定长解析器,取出指定字节长度的数据作为完成数据,不过这要求完整数据的长度是定长

使用方法,请尝试理解下面源码

public class FixedLengthFrameDecoderTest {
   
   
    public static ByteBuf Message(){
   
   

        StringBuilder sb = new StringBuilder();
        char c = 'a';
        for(int i=0;i<20;i++){
   
   
            sb.append(c);
            c++;
        }
        return Unpooled.copiedBuffer(sb.toString(),StandardCharsets.UTF_8);
    }
    public static void main(String[] args) {
   
   
        EmbeddedChannel channel = new EmbeddedChannel(
                //定长解析器,取出指定字节长度的数据
                new FixedLengthFrameDecoder(10),
                new SimpleChannelInboundHandler<ByteBuf>() {
   
   
                    @Override
                    protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值