美文网首页
boy-learning-netty | 08 Netty 是如

boy-learning-netty | 08 Netty 是如

作者: BruceOuyang | 来源:发表于2019-10-17 17:15 被阅读0次

    相关源码:boy-learning-netty
    个人博客:http://bruce.bugmakers.club
    内容来自《极客时间 - Netty源码剖析与实战》

    Netty 是如何处理 TCP 粘包、半包等问题的

    • 什么是粘包和半包

    • 为什么 TCP 应用中会出现粘包和半包现象

    • 解决粘包和半包问题的集中常用方法

    • Netty 对三种常用封帧方式的支持

    • 解读 Netty 处理粘包、半包的源码

    什么是粘包和半包

    粘包

    客户端多次发送 ABC, 服务端接收到 ABC? 如:ABCA, ABCAB, ABCABC

    主要原因:

    • 发送方每次写入数据 < 套接字缓冲区大小
    • 接收方读取套接字缓冲区数据不及时

    半包

    客户端多次发送 ABC, 服务端接收到 A? B? 如:AB, BC, CA

    主要原因:

    • 发送方每次写入数据 > 套接字缓冲区大小
    • 发送的数据大于协议的 MTU(Maximum Transmission Unit, 最大传输单元),必须拆包

    换个角度看粘包和半包

    • 收发
      • 一个发送可能被多次接收,多个发送可能被一次接收
    • 传输
      • 一个发送可能占用多个传输包,多个发送可能公用一个传输包

    为什么 TCP 应用中会出现粘包和半包现象

    根本原因:

    TCP 是流式协议,消息无边界。

    提醒:UDP 像邮寄的包裹,虽然一次运输多个,但每个包裹都有“界限”,一个一个签收,所以无粘包、半包问题。

    解决粘包和半包问题的集中常用方法

    根本手段:找出消息的边界。

    方式\比较 寻找消息边界的方式 优点 缺点 推荐度
    TCP 连接改成短连接,一个请求一个短连接 建立连接到释放连接之间的信息即为传输信息 简单 效率低下 不推荐
    封装成帧 Framing - 固定长度 满足固定长度即可 简单 浪费空间 不推荐
    封装成帧 Framing - 分隔符 分隔符之间 空间不浪费,也比较简单 内容本身出现分隔符时需要转义,所以需要扫描内容,耗费资源 一般
    封装成帧 Framing - 固定长度字段储存内容长度信息 先解析固定长度字段,再读取后续内容 精确定位用户数据,也不用转义 长度理论上有限制,需提前预知可能的最大长度从而定义长度占用字节数 推荐
    封装成帧 Framing - 其他方式 每种都不同,如JSON可以看{}是否应已经成对 衡量实际场景 衡量实际场景 很多是对现有协议的支持

    Netty 对三种常用封帧方式的支持

    方式\支持 解码 编码
    封装成帧 Framing - 固定长度 FixedLengthFrameDecoder 简单
    封装成帧 Framing - 分隔符 DelimiterBasedFrameDecoder 简单
    封装成帧 Framing - 固定长度字段储存内容长度信息 LengthFieldBasedFrameDecoder LengthFieldPrepender

    解读 Netty 处理粘包、半包的源码

    • 解码核心工作流程
      ByteToMessageDecoder 入手

    • 解码中两种数据累计器(Cumulator)的区别

      第一种 MERGE_CUMULATOR(默认):内存复制
      第二种 COMPOSITE_CUMULATOR:逻辑视图

    • 三种解码器的常用额外控制参数有哪些

      长度
      分隔符(支持一个或多个)
      固定长度字段等

    相关文章

      网友评论

          本文标题:boy-learning-netty | 08 Netty 是如

          本文链接:https://www.haomeiwen.com/subject/mfjvmctx.html