Netty万字详解 - 高级进阶

本文深入探讨了Netty中遇到的粘包和半包问题,分析了其原因并提供了多种解决方案。接着,文章讨论了协议的解析与设计,包括MyBatis、Http协议以及自定义协议的设计要素。此外,还提到了Netty中的空闲连接检测和心跳包机制,以确保连接的稳定性和可靠性。
摘要由CSDN通过智能技术生成

粘包与半包

滑动窗口

为了提高 TCP 传输的效率,传输端 & 接收端 会维护一个数组动态储存维护一定数量的 TCP 连接。

现象分析

粘包

  • 现象:发送 abc def,接收 abcdef

  • 原因:

    • 应用层:接收方 ByteBuf 设置较大(Netty 默认 1024)

    • 滑动窗口:接收方未及时处理数据且窗口大小足够大,滑动窗口中缓存了多个报文就会粘包

    • Nagle 算法1:会造成粘包

半包

  • 现象:发送 abcdef,接收 abc def

  • 原因:

    • 应用层:接收方 ByteBuf 小于实际发送的数据量

    • 滑动窗口:窗口大小较小且发送方报文较大,窗口容量不足只能部分发送数据造成半包

    • MSS 限制:当发送到数据超过 MSS 限制后会将数据切分发送,造成半包

本质原因:TCP 无边界

解决方案

  1. 客户端每次发送完数据后及时关闭连接

     @Override // Channel 连接建立成功后触发
     public void channelActive(ChannelHandlerContext ctx) {
         ByteBuf buf = ctx.alloc().buffer(16);
         buf.writeBytes(new byte[] {'1','2','3','4','5','6','7','8','9','0','a','s','d','f','g','h'});
         ctx.writeAndFlush(buf);
         ctx.channel().close();
     }
  2. 服务端采用固定长度接收

     @Override
     protected void initChannel(NioSocketChannel channel) {
         channel.pipeline().addLast(new StringDecoder())
             .addLast(new FixedLengthFrameDecoder(16)) // 每 16 字节解码一次
             .addLast(new LoggingHandler(LogLevel.DEBUG));
     }
  3. 服务端采用换行符分割接收

     @Override
     protected void initChannel(NioSocketChannel channel) {
         channel.pipeline().addLast(new StringDecoder())
             .addLast(new LineBasedFrameDecoder(1024)) // 最大寻找长度限制
             .addLast(new LoggingHandler(LogLevel.DEBUG));
     }
  4. 服务端采用协议解析

    数据写入时先声明数据长度,服务端根据协议内容直接进行解析

         public static void main(String[] args) {
             EmbeddedChannel channel = new EmbeddedChannel(
                     new LengthFieldBasedFrameDecoder(1024, 0, 4, 0, 4/*剥离数据的长度*/),
                     new StringDecoder(StandardCharsets.UTF_8),
                     new LoggingHandler(LogLevel.DEBUG)
             );
             ByteBuf buf = ByteBufAllocator.DEFAULT.buffer();
             for (int i = 0; i < 3; ++ i) {
                 byte[] bytes = "你好IllTamer".getBytes(StandardCharsets.UTF_8);
          
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值