TCP拆包和粘包的作用是什么

简介: 首先我们思考一个问题,应用层的传输一个10M的文件是一次性传输完成,而对于传输层的协议来说,为什么不是一次性传输完成呢。这个有很多原因,比如稳定性,一次发送的数据越多,出错的概率越大。再比如说为了效率,网络中有时候存在并行的路径,拆分数据包就就能更好的利用这些并行的路径。再有,比如发送和接收数据的时候,都存在缓冲区,缓冲区是在内存中开辟的一块空间,目的是缓冲大量的应用频繁的通过网卡收发数据,这个时候,网卡只能一个一个处理应用的请求。当网卡忙不过来的时候,数据就需要排队了。也就是将数据放入缓冲区。如果每个应用都随意发送很大的数据,可能导致其他应用的实时性遭到破坏。

首先我们思考一个问题,应用层的传输一个10M的文件是一次性传输完成,而对于传输层的协议来说,为什么不是一次性传输完成呢。

这个有很多原因,比如稳定性,一次发送的数据越多,出错的概率越大。再比如说为了效率,网络中有时候存在并行的路径,拆分数据包就就能更好的利用这些并行的路径。再有,比如发送和接收数据的时候,都存在缓冲区,缓冲区是在内存中开辟的一块空间,目的是缓冲大量的应用频繁的通过网卡收发数据,这个时候,网卡只能一个一个处理应用的请求。当网卡忙不过来的时候,数据就需要排队了。也就是将数据放入缓冲区。如果每个应用都随意发送很大的数据,可能导致其他应用的实时性遭到破坏。

所以,就是传输层的封装包不能太大。这种限制,一般是以缓冲区大小为单位的,也就是TCP协议,会将数据拆分为不超过缓冲区大小的一个个部分。每个部分叫做TCP段(TCP Segment)。

在接收数据的时候,一个个TCP段被重组成原来的数据。

像这样,数据经过拆分,然后传输,然后在目的地重组,就叫拆包。所以拆包就是将数据拆分为多个TCP段传输。有时候,如果发往一个目的地的多个数据太小了,为了防止多次发送占用资源,TCP协议有可能将它们合并成一个TCP段发送,在目的地再还原成多个数据,这个过程叫做粘包。所以粘包就是将多个数据合并成一个TCP段发送。

TCP Segment,下面是一个TCP段的格式:

image.png

TCP拆包和粘包的作用是什么
1、Source Port 、Destination Port 描述的是发送端口号和目标端口号,代表发送数据的应用程序和接收数据的应用程序

2、Sequence Number和Acknowledgment Number 是保证稳定性的关键因素,

3、Data Offset是一个偏移量,TCP Header部分的长度是可变的,因此需要一个数值描述数据是从哪个节点开始的。

4、Reserved是很多协议涉及都会保留的一个区域,方便后期的扩展。

5、URG/ACK/PSH/RST/SYN/FIN是标志位,用于描述TCP段的行为,也就是TCP封包的具体作用是干啥的。

5.1URG,代表一个紧急的操作,比如是远程用户操作的Ctrl+C,

5.2ACK,代表响应,所有的消息都必须有ACK,这是确保稳定性的一环。

5.3PSH,代表发送数据

5.4SYN,代表发送同步请求,申请握手

5.5FIN,代表结束请求,也是挥手。

以上这个5个标识位,每个占一个比特,可以混合使用,比如ACK+SYN可以同时为1,代表,同步请求和响应请求被合并了。

6、Window也是TCP保证稳定性并进行流量控制的工具,

7、Checksum 是校验和,用于校验 TCP 段有没有损坏

8、Urgent Pointer 指向最后一个紧急数据的序号(Sequence Number)。它存在的原因是:有时候紧急数据是连续的很多个段,所以需要提前告诉接收方进行准备。

9、Options 中存储了一些可选字段

10、Padding 存在的意义是因为 Options 的长度不固定,需要 Pading 进行对齐。

对于传输数据,稳定性要求数据无损的传输,也就是说拆包获得数据,又需要恢复到原来的样子,所以就要保证顺序行。这个主要是通过这两个值来保证。

image.png

TCP拆包和粘包的作用是什么
上图中,发送方发送了100个字节的数据,而接受说明到(Seq=100和Seq=0)两个封包,都是针对发送方(Seq=0)这个封包的。发送100个字节,所以接收到的ACK刚好是100,说明(Seq=0和Seq100)这两个封包是针对接收到第100个字节数据后,发送回来的。这样来确定顺序。对于字节数是200的数据,返回的ACK也是200,所以这个就排列到ACK=300,的前面。而对于字节数是500的字节的数据,返回的ACK应该也是500,所以他排在ACK=300的后面。

所以这个顺序的排列是根据SequenceNumber 和AcknowledgementNumer 两个值共同决定的。

SequenceNumber 和Acknowledgement Number

在TCP协议中的设计当中,数据被拆分成很多个部分,部分增加了协议头。合并成一个TCP段,进行传输,这个过程,叫做拆包。这些TCP段经过复杂的网络结构,由底层的IP协议,负责传输到目的地,然后进行重组。

总结,TCP拆包的作用是将任务拆分处理,降低整体任务出错的概率,以及减小底层网络处理的压力。拆包过程需要保证数据经过网络的传输,又能恢复到原始的顺序。这中间,需要数学提供保证顺序的理论依据。TCP利用(发送字节数和接收字节数)的唯一性来确定封包之间的顺序。粘包是为了防止数据量过小,导致大量的传输,而将多个TCP段合并成一个发送。

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
8月前
|
数据可视化 搜索推荐
Ollama-Deep-Researcher-本地Mac结合魔搭社区模型搭建网页研究助手
Ollama Deep Researcher 是一款完全本地化的网络研究助手,可使用Ollama托管的任何 LLM 。输入一个主题,它将生成网络搜索查询,收集网络搜索结果(默认通过Tavily),总结网络搜索结果,反思总结以检查知识差距,生成新的搜索查询以解决差距,搜索并改进总结,循环次数由用户定义。它将为用户提供最终的 markdown 摘要,其中包含所有使用的来源。
328 2
|
存储 自然语言处理 算法
“无”中生有:基于知识增强的RAG优化实践
本文作者基于自身在RAG技术领域长达半年的实践经验,分享了从初识RAG的潜力到面对实际应用挑战的心路历程,以及如何通过一系列优化措施逐步解决这些挑战的过程。
1258 20
“无”中生有:基于知识增强的RAG优化实践
|
11月前
|
存储 安全 大数据
数据安全中心:云上全域数据防泄漏与安全解决方案
在数字化转型中,企业面临数据安全挑战。为应对《个人信息保护法》等法规要求,我们推出“数据安全中心”,提供云上全域数据防泄漏与安全解决方案。该产品涵盖敏感数据自动识别、分级分类、大数据审计、数据脱敏及列加密等功能,帮助企业轻松实现数据治理,确保合规并保护客户信任。欢迎参加12月11日晚7:30阿里云中小企业直播间了解更多。
229 2
|
资源调度 Java Apache
实时计算 Flink版操作报错合集之错误代码是130如何解决
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
225 3
|
传感器
SFNC —— 采集控制(四)(上)
SFNC —— 采集控制(四)
362 3
|
存储 IDE 开发工具
探索Android开发之旅:从新手到专家
【10月更文挑战第26天】在这篇文章中,我们将一起踏上一段激动人心的旅程,探索如何在Android平台上从零开始,最终成为一名熟练的开发者。通过简单易懂的语言和实际代码示例,本文将引导你了解Android开发的基础知识、关键概念以及如何实现一个基本的应用程序。无论你是编程新手还是希望扩展你的技术栈,这篇文章都将为你提供价值和启发。让我们开始吧!
|
Java
SpringBoot解决跨域问题 几种方案
SpringBoot解决跨域问题 几种方案
187 0
|
Java Spring 容器
SpringMVC之注解配置SpringMVC
【1月更文挑战第20天】SpringMVC之注解配置SpringMVC
175 0
|
XML Java 测试技术
Java RESTful中的POST请求:资源的创建与数据传递
在RESTful架构中,POST请求是一种用于创建新资源的重要操作。它不仅可以传递数据到服务器,还能够在服务器端创建新的资源并返回相应的状态。本文将带您深入了解Java中使用POST请求构建RESTful API,探讨其特点、实现方式、用例以及在实际应用中的优势。

热门文章

最新文章