1. 粘包现象及产生原因

1)概念

TCP协议中,发送方发送的若干个包数据到接收方接收时粘成一包。发送方粘包:发送方把若干个要发送的数据包封装成一个包,一次性发送,减少网络IO延迟;接收方粘包:接收方接到的数据是若干个数据包个封装成的,而不是一个一个的数据包接收到。

一般实际开发中所说的粘包问题都是指接收方粘包现象。

2)原因分析

我们知道,我们写的应用程序是无法直接操作硬件,都是通过调用操作系统给应用程序封装的接口间接来操作硬件。

如上图所示,一个C/S系统,当你的程序要给要给远程发送数据时,其实是先把数据从用户态(程序内存)拷贝到内核态(系统内存)。为了提高传输效率,此时系统内存不会立即把数据发往接收端,TCP socket会根据优化算法(Nagle算法),将多个时间间隔较小且数据量较小的数据合并成大的数据块,然后封包,一次性从管道发出去。

对于接收方,操作系统内存会先接收到这个数据块,并缓存在内存中,然后应用程序从操作系统内存中提取数据。然而,由于应用程序不知道这个数据块中每个小数据包之间的界限,不知道一次性取多少数据合适,所以有可能这次只取了半个数据包,下次取了3个数据包,这就产生了粘包问题。

剩余的数据会继续存在缓存中,等待应用程序的下次拷贝。此时,发送方会继续从管道中发送数据过来,接收方收到后会与之前操作系统内存中的数据缓存在一起,等待应用程序提取。

TCP协议是面向流的协议,所以接收端接收到的数据是一个整体(可能由多个包合成),或着说是一个流,每个小数据包之间是无边界的,这也是容易出现粘包问题的原因。因此若要解决此问题,需提供科学的拆包机制,把一个大数据包中的小数据包一个个的解封出来。

网络编程-SOCKET开发之----2. TCP粘包现象产生分析的更多相关文章

  1. 第六章|网络编程-socket开发

    1.计算机基础 作为应用开发程序员,我们开发的软件都是应用软件,而应用软件必须运行于操作系统之上,操作系统则运行于硬件之上,应用软件是无法直接操作硬件的,应用软件对硬件的操作必须调用操作系统的接口,由 ...

  2. 网络编程——socket开发

    Socket套接字方法 socket 实例类(8-10分钟) socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None) ...

  3. 网络编程-socket开发

    练习: 1.什么是C/S架构? 2.互联网协议是什么?分别介绍五层协议中每一层的功能? 3.基于tcp协议通信,为何建立链接需要三次握手,而断开链接却需要四次挥手 4.为何基于tcp协议的通信比基于u ...

  4. 练习题|网络编程-socket开发

    1.什么是C/S架构? C指的是client(客户端软件),S指的是Server(服务端软件),C/S架构的软件,实现服务端软件与客户端软件基于网络通信. 2.互联网协议是什么?分别介绍五层协议中每一 ...

  5. TCP粘包拆包问题分析及应对方案

    粘包拆包问题是处于网络比较底层的问题,在数据链路层.网络层以及传输层都有可能发生.我们日常的网络应用开发大都在传输层进行,由于UDP有消息保护边界,不会发生粘包拆包问题,因此粘包拆包问题只发生在TCP ...

  6. 02网络编程( socket套接字+TCP粘包 )

    目录 02 网络编程 一.socket套接字编程 二.简易代码模板 2.1 服务端 2.2 客户端 三.通信循环及代码优化 四.黏包现象 五.struct模块 六.简易版本报头 七.上传文件数据 * ...

  7. 网络编程----socket介绍、基于tcp协议的套接字实现、基于udp协议的套接字实现

    一.客户端/服务器架构(C/S架构)                                                即C/S架构,包括: 1.硬件C/S架构(打印机) 2.软件C/S架 ...

  8. 网络编程-SOCKET开发之----3. socket通信工作流程

    1. TCP的socket通信流程 服务端 1)socket----创建socket对象. 2)bind----绑定本机ip+port. 3)listen----监听来电,若在监听到来电,则建立起连接 ...

  9. Python之路(第三十一篇) 网络编程:简单的tcp套接字通信、粘包现象

    一.简单的tcp套接字通信 套接字通信的一般流程 服务端 server = socket() #创建服务器套接字 server.bind() #把地址绑定到套接字,网络地址加端口 server.lis ...

随机推荐

  1. 【ShaderToy】基本操作——旋转

    *继续:ShaderToy基础学习中d(`・∀・)b 对每个像素点进行旋转,其实加个公式就ok了啊. 对网格进行旋转: 代码如下: #define TUTORIAL 2 #define PI 3.14 ...

  2. shell 批量修改较长字符串 字符串内容之间更换位置

    cat 1.txt src='http://img2.tgbusdata.cn/v2/thumb/jpg/MkY5Myw2NTUsMzAzLDksMywxLC0xLDAscms1MCwxOTIuMTY ...

  3. ansible初识

    ansible: 运维自动化的工具, 基本功能, 基于ssh远程连接, 连接验证(ssh-keygen ssh-copy-id  ip) 下载: 1. 安装epel源 wget -O /etc/yum ...

  4. 1、Altium Designer 入门

    一.新建工程 File-->new-->Project-->newPCB Project 1.添加原理图 在Project面板选中项目,右键Add New to Project--& ...

  5. [Kubernetes]深入理解StatefulSet

    前面我写的一系列博客,如果你能够耐心看到这一篇,那你应该对一个概念就不是太陌生了:Deployment. 为什么提这个概念呢,这就要说到Deployment的一个不足了.Deployment不足以覆盖 ...

  6. linux中gcc和g++的区别

    1.两者都是编译器 2.gcc编译c语言:g++既可以编译c语言,也可以编译c++语言 3.gcc不能自动链接库文件,一般用g++来链接库文件,非要用gcc的话,一般使用gcc -lstdc++命令 ...

  7. HTML 文本内容居中

    简单描述:使用bootstrap 的model弹出框,里边的标题内容是靠左的,想把内容居中. 操作:给标题的class加上"text-center". 另外 我发现,在使用mode ...

  8. python中hasattr()、getattr()、setattr()函数的使用

    1. hasattr(object, name) 判断object对象中是否存在name属性,当然对于python的对象而言,属性包含变量和方法:有则返回True,没有则返回False:需要注意的是n ...

  9. 有关js获取屏幕宽度问题

    offsetWidth是指包括滚动条的部分,而document.documentElement.clientWidth是去除滚动条的部分,所以这两个值是不一样的.

  10. oh-my-zsh: 让终端飞

    上一次推文写了JupyterLab:程序员的笔记本神器,介绍的是如何在web端打造一个便捷的开发环境,发出后反响还不错 因此我决定再写几篇能提升程序员工作以及学习效率的文章,如果能形成一个系列那是最好 ...