TCP的粘包现象
看面经时,看到有面试官问TCP的粘包问题。想起来研一做购物车处理数据更新时遇到粘包问题,就总结一下吧。
1 什么是粘包现象
TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。
2 为什么出现粘包现象
(1)发送方原因
我们知道,TCP默认会使用Nagle算法。而Nagle算法主要做两件事:1)只有上一个分组得到确认,才会发送下一个分组;2)收集多个小分组,在一个确认到来时一起发送。
所以,正是Nagle算法造成了发送方有可能造成粘包现象。
(2)接收方原因
TCP接收到分组时,并不会立刻送至应用层处理,或者说,应用层并不一定会立即处理;实际上,TCP将收到的分组保存至接收缓存里,然后应用程序主动从缓存里读收到的分组。这样一来,如果TCP接收分组的速度大于应用程序读分组的速度,多个包就会被存至缓存,应用程序读时,就会读到多个首尾相接粘到一起的包。
3 什么时候需要处理粘包现象
(1)如果发送方发送的多个分组本来就是同一个数据的不同部分,比如一个很大的文件被分成多个分组发送,这时,当然不需要处理粘包的现象;
(2)但如果多个分组本毫不相干,甚至是并列的关系,我们就一定要处理粘包问题了。比如,我当时要接收的每个分组都是一个有固定格式的商品信息,如果不处理粘包问题,每个读进来的分组我只会处理最前边的那个商品,后边的就会被丢弃。这显然不是我要的结果。
4 如何处理粘包现象
(1)发送方
对于发送方造成的粘包现象,我们可以通过关闭Nagle算法来解决,使用TCP_NODELAY选项来关闭Nagle算法。
(2)接收方
遗憾的是TCP并没有处理接收方粘包现象的机制,我们只能在应用层进行处理。
(3)应用层处理
应用层的处理简单易行!并且不仅可以解决接收方造成的粘包问题,还能解决发送方造成的粘包问题。
解决方法就是循环处理:应用程序在处理从缓存读来的分组时,读完一条数据时,就应该循环读下一条数据,直到所有的数据都被处理;但是如何判断每条数据的长度呢?
两种途径:
1)格式化数据:每条数据有固定的格式(开始符、结束符),这种方法简单易行,但选择开始符和结束符的时候一定要注意每条数据的内部一定不能出现开始符或结束符;
2)发送长度:发送每条数据的时候,将数据的长度一并发送,比如可以选择每条数据的前4位是数据的长度,应用层处理时可以根据长度来判断每条数据的开始和结束。
当时在做购物车的时候,我最开始的做法是设置开始符(0x7e)和结束符(0xe7),但在测试大量数据的时候,发现了数据异常。正如我所猜测,在调试过程中发现某些数据内部包含了它们。因为要处理的数据是量非常庞大,为做到万无一失,最后我采用了发送长度的方式。再也没有因为粘包而出过问题。
I Am So Brilliant !
TCP的粘包现象的更多相关文章
- python 全栈开发,Day35(TCP协议 粘包现象 和解决方案)
一.TCP协议 粘包现象 和解决方案 黏包现象让我们基于tcp先制作一个远程执行命令的程序(命令ls -l ; lllllll ; pwd)执行远程命令的模块 需要用到模块subprocess sub ...
- socket基于TCP(粘包现象和处理)
目录 6socket套接字 7基于TCP协议的socket简单的网络通信 AF_UNIX AF_INET(应用最广泛的一个) 报错类型 单一 链接+循环通信 远程命令 9.tcp 实例:远程执行命令 ...
- tcp的粘包现象与解决方案
粘包现象: 粘包1:连续的小包,会被优化机制给合并 粘包2:服务端一次性无法完全就收完客户端发送的数据,第二再次接收的时候,会接收到第一次遗留的内容 模拟一个粘包现象 服务端 import socke ...
- Python之路(第三十一篇) 网络编程:简单的tcp套接字通信、粘包现象
一.简单的tcp套接字通信 套接字通信的一般流程 服务端 server = socket() #创建服务器套接字 server.bind() #把地址绑定到套接字,网络地址加端口 server.lis ...
- 2、粘包现象(struct模块)
昨天我们所做的套接字是有漏洞的,它会出现粘包现象,没有发现这个问题的我们今天会进行演示.今天也会稍微讲解一下基于udp的套接字. 一.基于udp的套接字 udp是无链接的,先启动哪一端都不会报错 ud ...
- python3全栈开发-什么是粘包、粘包现象、如何解决粘包
一.粘包现象 让我们基于tcp先制作一个远程执行命令的程序(1:执行错误命令 2:执行ls 3:执行ifconfig) 注意注意注意: res=subprocess.Popen(cmd.decode( ...
- python 网络编程之TCP传输&粘包传输
只有TCP有粘包现象,UDP永远不会粘包. 所谓粘包问题主要还是C/S两端数据传输时 因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的 根本原因:粘包是由TCP协议本身造成的,T ...
- 29、粘包现象(struct模块)
昨天我们所做的套接字是有漏洞的,它会出现粘包现象,没有发现这个问题的我们今天会进行演示.今天也会稍微讲解一下基于udp的套接字. 本篇导航: 基于udp的套接字 粘包现象 粘包 解决粘包方法 stru ...
- 什么是粘包? socket 中造成粘包的原因是什么? 哪些情况会发生粘包现象?
只有TCP有粘包现象,UDP永远不会粘包! 粘包:在接收数据时,一次性多接收了其它请求发送来的数据(即多包接收).如,对方第一次发送hello,第二次发送world, 在接收时,应该收两次,一次是he ...
随机推荐
- ASP.NET MVC程序播放H.264视频
在这篇之前,Insus.NET不管是在ASP.NET还是ASP.NET MVC实现很多视频播放,你可以参考这篇链接:http://www.cnblogs.com/insus/category/4650 ...
- [水煮 ASP.NET Web API2 方法论](3-6)万能路由
问题 定义什么样的路由,可以不会受请求参数类型和数量的限制,而被全部捕获? 解决方案 在路由模板中,给参数添加一个"*"前缀,例如 {*param},只要请求的 URL 能够和路由 ...
- jQuery+CSS3实现404背景动画特效
效果:http://hovertree.com/texiao/jquery/74/ 源码下载:http://hovertree.com/h/bjaf/ko0gcgw5.htm 效果图如下: 代码如下: ...
- iOS阶段学习第18天笔记(Plist-Archiver-归档与解归档操作)
iOS学习(OC语言)知识点整理 一.归档与解归档的操作 1)归档是一个过程,将一个或多个对象存储起来,以便以后可以还原,包括将对象存入文件,以后再读取 将数据对象归档成plist文件 2)plist ...
- 微信、QQ、微博、陌陌……社交网络的底层逻辑是什么?
两 年前的社交产品泛滥犹在眼前,场景之胜几乎到了言必谈社交的地步.时任阿里新CEO陆兆禧举全集团之力,力推新社交产品“来往”,动作之大震惊整个互联 网.如今,陆兆禧早早退场,只留下一个硬汉的孤独背 ...
- EC笔记,第一部分:3.尽量使用const
03.尽量使用const 1.const概述 2.返回const 为何要返回一个const? 因为如果不返回const,程序员可能写出fun(a,b)=c;这样的代码,也许是因为打字错误可能写出类似i ...
- PostgreSQL获取年月日
1.获取当前日期的年份 select to_char(t.detect_date,'YYYY') select extract(year from now())为double precision 格式 ...
- javaweb——Servlet作为控制器
1.文件预览 JSP:login.jsp--用户登陆,jsp只是用于向客户端展示信息,处理信息的是servlet. welcome.jsp--用户登陆成功,显示给用户的界面. jsp文件是位于webC ...
- 事件委托 documentFragment
如果有一个列表页,页面结构是外面一个BODY, 里面有一万个子DIV,每个DIV里面有一些文字,这些文字都不相同.需求是,点击一个DIV,要求弹个alert框,将DIV里的文字显示出来.你会怎么做. ...
- JVM的生命周期、体系结构、内存管理和垃圾回收机制
一.JVM的生命周期 JVM实例:一个独立运行的java程序,是进程级别 JVM执行引擎:用户运行程序的线程,是JVM实例的一部分 JVM实例的诞生 当启动一个java程序时.一个JVM实例就诞生了, ...