• Netty_TCP拆包粘包解决方案


    一、问题

      熟悉tcp编程的可能都知道,无论是服务器端还是客户端,当我们读取或者发送数据的时候,都需要考虑TCP底层的粘包/拆包机制。

      TCP是一个“流”协议,所谓流就是没有界限的遗传数据,大家可以想象下如果河里的水就好比数据,他们是连成一片的,没有分界线,TCP底层并不了解上层的业务数据具体的含义,它会根据TCP缓冲区的实际情况进行包的划分,也就是说,在业务上我们一个完成的包可能会被TCP分成多个包进行发送,也可能把多个小包封装成一个大的数据发送出去,这就所谓的TCP粘包、拆包问题。

    1)分析TCP粘包、拆包问题的产生原因:

          1、应用程序write写入的字节大小大于套接口发送缓冲区的大小

          2、进行MSS大小的TCP分段

          3、以太网帧的payload大于MTU进行IP分片

    2)粘包、拆包问题解决方案,三种方案:

         1、消息定长,例如每个报文的大小固定为200个字节,如果不够,空位补空格;

         2、在包尾部增加特殊字符进行分割,例如加回车等

         3、讲消息分为消息头河消息体,在消息头中包含表示消息总长度的字段,然后进行业务逻辑处理

    二、采用特殊字符进行分割

    Server只需要加三行:

     1.根据$_进行截取字符串

     2.DelimiterBasedFrameDecoder:是自定义的分隔符解码,构造函数的第一个参数表示单个消息的最大长度,当达到该长度后仍然没有查到分隔符,就抛出TooLongFrameException异常,防止由于异常码流缺失分隔符导致的内存溢出。

     3.LineBasedFrameDecoder:依次编译bytebuf中的可读字符,判断看是否有“ ”或者“ ”,如果有,就以此位置为结束位置,从可读索引到结束位置区间的字节就组成了一行。它是以换行符为结束标志的解码器,支持携带结束符或者不携带结束符两种解码方式,同时支持单行的最大长度。如果连续读取到最大长度后,仍然没有发现换行符,就会抛出异常,同时忽略掉之前读到的异常码流。(具体例子介绍在《Netty(三)TCP粘包拆包处理》

     4. FixedLengthFrameDecoder:是固定长度解码器,它能按照指定的长度对消息进行自动解码,开发者不需要考虑TCP的粘包等问题。利用FixedLengthFrameDecoder解码,无论一次性接收到多少的数据,他都会按照构造函数中设置的长度进行解码;如果是半包消息,FixedLengthFrameDecoder会缓存半包消息并等待下一个包,到达后进行拼包,直到读取完整的包。

    client只需要加三行:

     

    执行结果

    反之:客户端也是一样写法。

  • 相关阅读:
    Spring温故而知新 – bean的装配
    Lambda表达式和表达式树
    委托的内部机制
    委托(C#)
    linux wdcp安装
    linux各个文件夹作用
    linux基本命令
    python调用html内的js方法
    Win10在右键菜单添加“在此处打开命令窗口”设置项
    python read文件的r和rb的区别
  • 原文地址:https://www.cnblogs.com/steven520213/p/7078414.html
Copyright © 2020-2023  润新知