TCP粘包、拆包

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

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

分析TCP粘包、拆包问题产生的原因“

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

  2、进行MSS大小的TCP分段

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

下面看一下粘包的现象:

Client端连续发送3次数据,下面看一下Server端的打印结果:

可以看到,Server端接收到的结果是连接在一起的,

这就是粘包的现象。

TCP粘包、拆包问题解决方案

粘包拆包问题的解决方案,根据业界的主流协议,有三种方案:

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

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

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

netty提供了一些基础累:

1分隔符类DelimiterBasedFrameDecoder(自定义分隔符)

2FixedLengthFrameDecoder(定长)

下面看一下如何使用自定义分隔符进行拆包的,

在Server端,

接收到Client端传来的buf数据,然后通过 DelimiterBasedFrameDecoder 把数据解析成String类型的数据,看一下下面的相关实现:

我这边是通过“$_”这个字符串作为分隔符,下面看一下ServerHandler里面的响应代码:

因为在前面已经转换成String类型了,这边只是确保一下类型,进行了一下强转,这边向客户端发送的数据要是原先的buf数据,不然客户端没办法去解析,

同样的看一下Client端的程序,Client端的程序与Server端的程序类似:

看一下ClientHandler代码,ClientHandler端就把server端响应的代码进行了打印:

看一下运行结果,和原先没有使用分隔F的进行一下对比,看看有什么区别:

Server端接收到3条Client端发送的数据,没有发生粘包的现象。Client端也收到Server端响应的3条数据。

这是第一种处理TCP拆包粘包的处理方式,下面我们看一下第二种处理方式:

只需要把使用的类替换掉,并定义字节的长度,不过需要自己传输的字符串自己添加空格,如果不添加,或者设置的字节太短,都会出现粘包的现象。

TCP粘包、拆包的更多相关文章

  1. Netty(三)TCP粘包拆包处理

    tcp是一个“流”的协议,一个完整的包可能会被TCP拆分成多个包进行发送,也可能把小的封装成一个大的数据包发送,这就是所谓的TCP粘包和拆包问题. 粘包.拆包问题说明 假设客户端分别发送数据包D1和D ...

  2. TCP粘包/拆包问题

    无论是服务端还是客户端,当我们读取或者发送消息的时候,都需要考虑TCP底层的粘包/拆包机制. TCP粘包/拆包 TCP是个"流"协议,所谓流,就是没有界限的一串数据.大家可以想想河 ...

  3. TCP 粘包/拆包问题

    简介    TCP 是一个’流’协议,所谓流,就是没有界限的一串数据. 大家可以想想河里的流水,是连成一片的.期间并没有分界线, TCP 底层并不了解上层业务数据的具体含义 ,它会根据 TCP 缓冲区 ...

  4. TCP粘包/拆包问题的解决

    TCP粘包拆包问题 一个完整的包可能被TCP拆分成多个包,或多个小包封装成一个大的数据包发送. 解决策略 消息定长,如果不够,空位补空格 在包尾增加回车换行符进行分割,例如FTP协议 将消息分为消息头 ...

  5. Netty(二)——TCP粘包/拆包

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/7814644.html 前面讲到:Netty(一)--Netty入门程序 主要内容: TCP粘包/拆包的基础知 ...

  6. 第四章 TCP粘包/拆包问题的解决之道---4.1---

    4.1 TCP粘包/拆包 TCP是一个“流”协议,所谓流,就是没有界限的一串数据.TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可 ...

  7. Java网络编程基础之TCP粘包拆包

    TCP是个"流"协议,所谓流,就是没有界限的一串数据.大家可以想象河里的流水,他们是连成一片的,其间并没有分界线.TCP底层并不了解上层业务数据的具体含义,他会根据TCP缓冲区的实 ...

  8. TCP粘包/拆包 ByteBuf和channel 如果没有Netty? 传统的多线程服务器,这个也是Apache处理请求的模式

    通俗地讲,Netty 能做什么? - 知乎 https://www.zhihu.com/question/24322387 谢邀.netty是一套在java NIO的基础上封装的便于用户开发网络应用程 ...

  9. netty之==TCP粘包/拆包问题解决之道(一)

    一.TCP粘包/拆包是什么 TCP是一个“流”协议,所谓流,就是没有界限的一长串二进制数据.TCP作为传输层协议并不不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行数据包的划分,所以在 ...

  10. Netty使用LineBasedFrameDecoder解决TCP粘包/拆包

    TCP粘包/拆包 TCP是个”流”协议,所谓流,就是没有界限的一串数据.TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可能会被TC ...

随机推荐

  1. jsfl 常用自定义方法

    //创建文件夹 function creatFile(fileURl) { if (FLfile.createFolder(fileURl)) { //alert("创建成功 "+ ...

  2. UI5-学习篇-3-Local SAP WEB IDE下载

    1.下载地址 https://tools.hana.ondemand.com/#sapui5 有两个版本,针对各自系统环境选择对应的个人版本下载后解压. 个人版:个人试用 生产版:在云平台SCP付费订 ...

  3. Python的几种主流框架

    参考:https://www.cnblogs.com/linkenpark/p/5881586.html

  4. redis 学习笔记3(哨兵模式下分布式锁的实现以及全局唯一id的生成)

    redis实现分布式锁和全局唯一id应该是较为常见的应用. 实现基于redis的setNX,以及incr命令.还是比较简单的! 搭建环境以及配置好sping整合,做了下测试,有兴趣的载下来看看,自己做 ...

  5. vue:图片切换动态显示

    <img :src="切换条件 ? require('xxx.png') : require('xxx.png')" />

  6. HashSet和LinkedHashSet解析

    一.简介 1.Set概念 Set可以理解为集合,非常类似数据概念中的集合,集合三大特征:1.确定性:2.互异性:3.无序性,因此Set实现类也有类似的特征. 2.HashSet HashSet继承自A ...

  7. unity 脚本说明

    MonoBehavour void OnEnable(){ //OnEnable执行在Wake和之前 } void Awake(){ // } void Start(){ } void OnEnabl ...

  8. 【365】拉格朗日乘子法与KKT条件说明

    参考:知乎回答 - 通过山头形象描述 参考:马同学 - 如何理解拉格朗日乘子法? 参考: 马同学 - 如何理解拉格朗日乘子法和KKT条件? 参考:拉格朗日乘数 - Wikipedia 自己总结的规律 ...

  9. 虚拟机安装VMware tools

    选择虚拟机菜单栏--安装VMware tools 2 然后在CentOS系统中弹出的VMware tools窗口中 右击VMwaretools-9.6.0-1294478.tar.gz 解压缩到 3 ...

  10. 安装vue CLI后, 出现安装权限问题

    问题:安装vue CLI后,出现:npm WARN checkPermissions Missing write access to /usr/local/lib/node_modules/usr/l ...