看面经时,看到有面试官问TCP的粘包问题。想起来研一做购物车处理数据更新时遇到粘包问题,就总结一下吧。

1 什么是粘包现象

  TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。

2 为什么出现粘包现象

       (1)发送方原因

  我们知道,TCP默认会使用Nagle算法。而Nagle算法主要做两件事:

1)只有上一个分组得到确认,才会发送下一个分组;   2)收集多个小分组,在一个确认到来时一起发送。

什么是尼格拉算法?

如果一个应用程序一次只产生一个字节的数据,而这一个字节的数据又要以网络数据包的形式发送到远端服务器,那么就很容易导致网络由于太多的数据包而过载。1字节的有效数据每次却需要40字节包头的额外开销,这种极低的有效载荷利用率极易引发网络拥塞瘫痪。尼格拉算法的提出是为了提高网络的利用率。

但是也会发生某种程度上的延时和数据包的粘包问题。

尼格拉算法的思想是:发送端即使还有应该发送的数据,但是如果这部分数据比较少的时候,则进行延迟发送!

该算法要求一个TCP连接上最多只能有一个未被确认的未完成的小分组,在该分组的确认到来之前不发送其他的小分组。相反,TCP收集这些少量的分组,并在确认到来之时以一个分组的形式发送出去,或者该数据是紧急数据会即时发送。这样,就能够减少网络中小分组的数量,提高数据包的利用率。

算法优势:自适应,确认到达的越快,数据发送也就越快。

TCP中的Negla算法是默认开启的

  所以,正是Nagle算法造成了发送方有可能造成粘包现象。

  (2)接收方原因

  TCP接收到分组时,并不会立刻送至应用层处理,或者说,应用层并不一定会立即处理;实际上,TCP将收到的分组保存至接收缓存里,然后应用程序主动从缓存里读收到的分组。这样一来,如果TCP接收分组的速度大于应用程序读分组的速度,多个包就会被存至缓存,应用程序读时,就会读到多个首尾相接粘到一起的包。

3 什么时候需要处理粘包现象

  (1)如果发送方发送的多个分组本来就是同一个数据的不同部分,比如一个很大的文件被分成多个分组发送,这时,当然不需要处理粘包的现象;

  (2)但如果多个分组本毫不相干,甚至是并列的关系,我们就一定要处理粘包问题了。比如,我当时要接收的每个分组都是一个有固定格式的商品信息,如果不处理粘包问题,每个读进来的分组我只会处理最前边的那个商品,后边的就会被丢弃。这显然不是我要的结果。

4 如何处理粘包现象

  (1)发送方

  对于发送方造成的粘包现象,我们可以通过关闭Nagle算法来解决,使用TCP_NODELAY选项来关闭Nagle算法

  (2)接收方

  遗憾的是TCP并没有处理接收方粘包现象的机制,我们只能在应用层进行处理。

  (3)应用层处理

  应用层的处理简单易行!并且不仅可以解决接收方造成的粘包问题,还能解决发送方造成的粘包问题。

  解决方法就是循环处理:应用程序在处理从缓存读来的分组时,读完一条数据时,就应该循环读下一条数据,直到所有的数据都被处理;

但是如何判断每条数据的长度呢?

  两种途径:

    1)格式化数据:每条数据有固定的格式(开始符、结束符),这种方法简单易行,但选择开始符和结束符的时候一定要注意每条数据的内部一定不能出现开始符或结束符;

    2)发送长度:发送每条数据的时候,将数据的长度一并发送,比如可以选择每条数据的前4位是数据的长度,应用层处理时可以根据长度来判断每条数据的开始和结束。

  当时在做购物车的时候,我最开始的做法是设置开始符(0x7e)和结束符(0xe7),但在测试大量数据的时候,发现了数据异常。正如我所猜测,在调试过程中发现某些数据内部包含了它们。因为要处理的数据是量非常庞大,为做到万无一失,最后我采用了发送长度的方式。再也没有因为粘包而出过问题。

网络:TCP粘包问题?如何解决?相关推荐

  1. TCP粘包问题以及解决方法

    粘包问题分析与对策 TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾. 出现粘包现象的原因是多方面的,它既可能由发送方造成,也可能由接收方 ...

  2. Socket编程实践(5) --TCP粘包问题与解决

    TCP粘包问题 由于TCP协议是基于字节流且无边界的传输协议, 因此很有可能产生粘包问题, 问题描述如下 对于Host A 发送的M1与M2两个各10K的数据块, Host B 接收数据的方式不确定, ...

  3. tcp粘包及如何解决

    1. 什么是粘包 流式套接字 首先说说TCP为什么叫流式套接字,顾名思义,是指TCP的数据传输跟流动的水一样,大家可以想象一下,水是连成一片的,它是没有分界线的,而TCP数据传输也是一样的,是没有界限 ...

  4. Netty学习总结(5)——Netty之TCP粘包/拆包问题的解决之道

    无论是服务端还是客户端,读取或者发送消息的时候,都需要考虑TCP底层的粘包/拆包机制. TCP粘包/拆包 TCP是个"流"协议. 流:没有界限的一串数据.如同河里的流水,它们是连成 ...

  5. Netty解决TCP粘包/拆包导致的半包读写问题

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

  6. 【Netty入门】TCP 粘包/拆包问题产生原因

    TCP粘包/分包问题的由来 因为TCP是以流的方式来处理数据,一个完整的包可能会被TCP拆分成多个包进行发送,也可能把小的封装成一个大的数据包发送. 这样说可能比较抽象,下面举例来说明TCP拆包/粘包 ...

  7. TCP——粘包/拆包

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

  8. TCP粘包/拆包问题

    目录 TCP粘包/拆包 TCP粘包/拆包问题说明 TCP粘包/拆包发生的原因 粘包问题的解决策略 未考虑TCP粘包导致功能异常案例  TimeServer的改造 TimeClient的改造 利用Lin ...

  9. Netty权威指南(四)TCP粘包/拆包问题

    TCP粘包/拆包问题解决之道 上一章 一.介绍 1.1 TCP粘包/拆包问题说明 1.2 TCP粘包/拆包发生的原因 1.3 粘包问题的解决策略 二.未考虑TCP粘包导致的功能异常案例 2.1 Tim ...

  10. 解决TCP网络传输“粘包”问题

    当前在网络传输应用中,广泛采用的是TCP/IP通信协议及其标准的socket应用开发编程接口(API).TCP/IP传输层有两个并列的协议:TCP和UDP.其中TCP(transport contro ...

最新文章

  1. tomcat+bean例子
  2. 在网易有道做语音算法工程师是一种怎样的体验?
  3. STM32开发 -- 系统软复位
  4. iPhone5帮助了谁?
  5. 在微软工作一年,我学会了什么
  6. C++ primer 第7章 类
  7. 超越 YOLOv5 的目标检测开源项目又上新了
  8. 【ElasticSearch】深入理解 ElasticSearch Doc Values
  9. [BZOJ4568][SCOI2016]幸运数字(倍增LCA,点分治+线性基)
  10. OpenGL入门程序一:绘制简单的矩形
  11. 了区块链开放平台baas_区块链开放平台 BaaS 系统开发,区块链智能合约撰写服务...
  12. 在人工智能中对TSP问题的求解
  13. 易筋SpringBoot 2.1 | 第十九篇:SpringBoot的常用注解
  14. TNS-12555报错的解决方案
  15. PPT转word可以使用什么软件
  16. 主数据管理系统(MDM)的四种实现风格
  17. 管道软件_软件管道工的就业市场过热
  18. 聚焦人机交互智能应用领域,APISIX 在希沃网关的应用与实践
  19. ubuntu上安装视频插件
  20. matlab将多项式通分,matlab多项式因式分解

热门文章

  1. Zabbix+shell监控报警任意web
  2. Android官方网站
  3. nginx 及 php 配置
  4. python config
  5. 中国农业银行数据中心智能布线系统
  6. Lighttpd源码分析之状态机与插件
  7. Windows下一个比较完美的线程池实现
  8. Python与MySQL
  9. OpenCV的图像处理——iOS与OpenCV之间图像转换
  10. 吴恩达深度学习课程deeplearning.ai课程作业:Class 1 Week 4 assignment4_1