【计网】一起聊聊TCP的粘包拆包问题吧

TCP粘包和拆包 Socket为TCP长连接,TCP为了保证可靠传输并减少额外的开销(每次发包都要验证),采用了基于流的传输,基于流的传输不认为消息是一条一条的,是无保护消息边界的(保护消息边界:指传输协议把数据当做一条独立的消息在网上传输,接收端一次只能接受一条独立的消息)。会存在粘包拆包问题。UDP则是面向消息传输的,是有保护消息边界的,接收方一次只接受一条独立的信息,所以不存在粘包拆包问题。TCP是个流协议,就是没有界限的一串数据。TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分,所 阅读详情

1、介绍

在TCP中,粘包和拆包问题是十分常见的,如基于TCP协议的RPC框架、Netty等。

粘包(Packet Stickiness)指的是在网络通信中,发送方连续发送的多个小数据包被接收方一次性接收的现象。这可能是因为底层传输层协议(如TCP)会将多个小数据包合并成一个大的数据块进行传输,导致接收方在接收数据时一次性接收了多个数据包,造成粘连。

拆包(Packet Splitting)指的是在网络通信中,发送方发送的一个大数据包被接收方拆分成多个小数据包进行接收的现象。这可能是因为底层传输层协议(如TCP)将一个大数据包拆分成多个小的数据块进行传输,导致接收方在接收数据时分别接收了多个小数据包,造成拆开。

来自于百度词典:粘包读zhān bāo而非nián bāo

2、为什么会出现粘包/拆包问题

2.1、TCP协议

那就需要先了解 TCP 的定义。TCP(Transmission Control Protocol)传输控制协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议。

其中跟粘包/拆包关系最大的就是基于字节流这个特点。字节流可以理解为一个双向的通道里流淌的数据,这个数据其实就是我们常说的二进制数据,简单来说就是一大堆 01 串。这些 01 串之间没有任何边界。

image-20230724093813101

应用层传到 TCP 协议的数据,不是以消息报为单位向目的主机发送,而是以字节流的方式发送到下游,这些数据可能被切割和组装成各种数据包,接收端接收到这些数据包后没有正确还原之前的消息,因此出现粘包/拆包现象。

2.2、粘包问题

由于TCP是面向流的协议,发送方将数据流切割成数据块并通过网络发送,而接收方则将接收到的数据块重新组装成数据流。当发送方连续发送多个小数据块时,这些数据块可能会被合并成一个大的数据块,从而产生粘包现象。造成粘包问题的主要原因有以下几点:

  • 数据发送速度快于接收方处理速度:当发送方连续发送多个小数据块时,由于网络传输延迟等原因,接收方的缓冲区可能无法及时处理所有数据块,从而导致这些数据块被合并成一个大的数据块;
  • TCP缓冲区合并:TCP协议在发送端和接收端都有缓冲区,TCP层可能在缓冲区中将多个小数据块合并为一个大数据块再进行传输。

2.3、拆包问题

同样,由于TCP是面向流的协议,发送方将数据流切割成数据块并通过网络发送,而接收方则将接收到的数据块重新组装成数据流。当发送方发送一个较大的数据块时,在网络传输过程中,可能会被拆分成多个小的数据块进行传输,从而产生拆包现象。造成拆包问题的主要原因有以下几点:

  • 数据发送速度慢于接收方处理速度:当发送方发送一个较大的数据块时,由于网络传输延迟等原因,接收方的缓冲区可能无法一次性接收所有数据块,从而导致数据被拆分成多个小的数据块;
  • TCP缓冲区拆分:TCP协议在发送端和接收端都有缓冲区,TCP层可能在缓冲区中将一个大数据块拆分成多个小数据块再进行传输。

3、粘包/拆包场景

因为TCP是面向流,没有边界,而操作系统在发送TCP数据时,会通过缓冲区来进行优化,例如缓冲区为1024个字节大小。

如果一次请求发送的数据量比较小,没达到缓冲区大小,TCP则会将多个请求合并为同一个请求进行发送,这就形成了粘包问题。

如果一次请求发送的数据量比较大,超过了缓冲区大小,TCP就会将其拆分为多次发送,这就形成了拆包问题。

关于粘包和拆包可以参考下图的几种情况:

  • 正常的理想情况,两个包恰好满足TCP缓冲区的大小或达到TCP等待时长,分别发送两个包;
  • 粘包:两个包较小,间隔时间短,发生粘包,合并成一个包发送;
  • 拆包:一个包过大,超过缓存区大小,拆分成两个或多个包发送;
  • 拆包和粘包:Packet1过大,进行了拆包处理,而拆出去的一部分又与Packet2进行粘包处理。

image

4、解决方案

4.1、固定长度的数据包

发送端将每个数据包封装为固定长度(不够的可以通过补0填充),这样接收端每次从接收缓冲区中读取固定长度的数据就自然而然的把每个数据包拆分开来。

下图每个包的固定长度为 4,接收端很容易进行区分。

image-20230724095906283

4.2、特殊字符或标记

在数据包中使用特殊的字符或标记来标识数据包的边界,接收端根据特殊字符或标记进行数据解析和处理。

如下图,在每个包的后面加上特殊字符:/

image-20230724100117377

4.3、消息头

在数据包的开头添加一个消息头,用来记录数据包的长度或其他信息,接收端先读取消息头来确定数据包的长度,然后根据长度进行数据解析和处理。

如下图,在每个包前面加上包的实际长度。

image-20230724100229901

当然,还有一种常见的方法就是通过自定义协议进行粘包和拆包的处理。但对于个人开发而已,这种成本就相对比较高了。

5、为什么UDP没有粘包/拆包问题

UDP(User Datagram Protocol)是一个无连接的、不可靠的传输协议,与TCP不同,它并不提供像TCP那样的可靠数据传输和流控制机制。因为UDP没有像TCP那样的字节流特性,所以在UDP中不存在粘包和拆包问题。

在UDP中,每个数据报(Datagram)都是独立的,包含了完整的数据和目标地址信息。每次发送的数据都会被封装成一个独立的数据报,而接收端也会逐个接收每个数据报,不会将多个数据报合并成一个大的数据块,也不会将一个大的数据块拆分成多个小的数据块。

由于UDP的无连接特性,它不会进行流控制、拥塞控制和重传等机制,因此在传输过程中可能会丢失数据包,也可能会乱序。但是,由于每个数据报都是独立的,所以在UDP中不存在粘包和拆包问题。

TCP的粘包和拆包 TCP粘包问题解析与解决方案 摘要: TCP作为面向连接的可靠传输协议,其流式传输特性会导致粘包和拆包问题。本文系统分析了粘包成因,包括Nagle算法、缓冲区机制等底层因素,并归纳了三种典型场景。针对粘包问题,提出了四类应用层解决方案:固定长度协议适合简单指令,分隔符协议适用于文本传输,长度头协议处理二进制数据效率最佳,混合协议则兼具健壮性。此外,还探讨了底层优化配置(如禁用Nagle算法)和高级处理技巧(滑动窗口解析)。文章最后对比了TCP与UDP的特性差异,为协议设计提供了实践指导。 阅读详情

相关推荐

响应式编程(三)什么是粘包、拆包?如何解决?

响应式编程(三)什么是粘包、拆包?如何解决?

ACGkaka的博客 2618

解决TCP粘包/拆包问题的方法及示例

还有一种解决TCP粘包/拆包问题的方法是使用定长协议,即规定每次发送的数据包都是固定长度,例如规定每次发送的数据包长度为固定的100个字节,如果发送的数据长度不足100字节,则在后面填充空格或者其他特定字符,如果超过100字节,则进行截断处理。由于网络的不可靠性,TCP为了提高传输效率,会将多个小数据块打包成一个大的数据块一起发送(称为TCP粘包),或者将一个大的数据块拆分成多个小的数据块发送(称为TCP拆包)。由于TCP是面向流的协议,发送的数据流会被自动分段,可能出现多个短消息被粘在一起发送的情况。

polsnet的专栏 4373

计网简简单单复习一下

计算机网络基础 HTTP TCP IP ARP PING WebSocket 网络攻击 CDN 跨域

weixin_43739821的博客 1565

聊聊TCP协议的粘包、拆包以及http是如何解决的?

TCP协议的粘包、拆包以及http是如何解决的

cj_eryue的博客 2万+

水文模型大合集---SWAT模型、VIC模型、HEC-HMS模型、HSPF模型、FVCOM模型、Delft3D模型、HYPE模型.......

1.1 面源污染概要1.2 SWAT模型及应用1.3 SWAT模型原理1.4 SWAT模型输入文件1.5 ArcGIS与SWAT关系。

jwwkyjspt的博客 4348

RocketMQ 5.3.1 集成 Spring Boot 3.4.3 就这么简单

RocketMQ 是一个分布式消息中间件,支持发布/订阅模型,具有高吞吐量、高可用性和事务消息等特性。它广泛应用于日志处理、订单系统和异步任务等场景。Spring Boot 3.4.3 集成 RocketMQ 5.3.1 的过程异常简单,仅需少量配置即可实现消息的生产和消费。本文从环境搭建到代码实现,覆盖了核心步骤。

lssffy的博客 1379

【目录】博客目录 & 先点这里

为了方便索引,请移步这里哟 ! !

长路漫漫的歇脚处 7294

暑期实习前端面试笔试总结汇总

腾讯2020暑期实习——前端视频面试(1)回顾 腾讯2020暑期实习——前端视频面试(2)回顾 腾讯2020暑期实习——前端视频面试(3)回顾 腾讯2020暑期实习——前端视频面试(4)回顾 蘑菇街2020暑期实习——前端视频面试回顾 二、笔试 奇安信前端实习笔试总结 vivo笔试(2020年3月8日) ...

明媚 3062

TCP的粘包与拆包

一文带你搞懂TCP的粘包与拆包问题

goat的博客 998

在天问block环境下LU-ASR01与51单片机的基础运用

正确步骤将模块和电脑连接后,仍然显示未连接(如4.1中图片中的编译下载后面显示未连接),可以尝试关闭软件后尝试,如果仍然不行换一条type-c线再试;以上方式都不行,可能要怀疑ASR01硬件损坏,跟商家联系!!!

BUG7073的博客 1万+

Mellanox CX7网卡搭配400G光模块实战:从选型到部署的完整指南

本文详细解析了Mellanox CX7网卡与400G光模块的选型策略与部署实践,涵盖硬件对比、兼容性验证及性能调优。重点介绍了OSFP光模块的选择要点和常见问题排查方法,帮助用户构建高性能网络基础设施,适用于AI训练、金融交易等场景。

efc1234567的博客 1279

什么是TCP的粘包、拆包问题?

作为一名编程博客专家,我深知程序员在日常工作中对网络通信的重视。TCP(传输控制协议)作为互联网的核心协议之一,其可靠性和有序性是其最大的优势。然而,TCP在数据传输过程中也会遇到一些问题,其中最常见的就是粘包(Sticky Packet)和拆包(Packet Fragmentation)问题。本文将深入探讨TCP的粘包、拆包问题,帮助你全面理解其工作原理及实际应用。TCP的粘包和拆包问题是网络通信中常见的问题,主要发生在发送方发送的数据包较小且频繁或较大且网络环境不稳定的情况下。

xycxycooo的博客 1928

【异常】OpenClaw 项目 `fetch failed` 报错问题排查与解决方案Response interrupted: TypeError: fetch failed

针对无超时控制、异常兜底缺失导致的请求中断,封装标准化的安全请求工具,一次性解决超时控制、异常捕获、日志埋点三大问题,全项目替换原生。:将项目运行的 Node.js 版本升级至 18.x 及以上 LTS 版本,使用 Node.js 内置的稳定版。实现的网络请求环节,包括但不限于:第三方开放接口调用、内部服务接口通信、跨域资源请求、外部配置拉取等场景。:针对无法升级 Node.js 版本的存量环境,通过社区稳定兼容包替换原生。类型异常,直接造成业务请求响应中断。第二步:业务代码改造,替换原生。

奶爸的编程之路,也就一周冷个三天 362

tcp的粘包和拆包及解决方案

TCP的粘包和拆包问题是由于TCP的字节流特性和网络传输效率的需要所导致的。解决这一问题的关键是在应用层引入一定的协议来定义消息的边界,常见的方法包括消息定长、设置消息边界、长度字段等。选择哪种方法取决于具体的应用场景和需求。

坚定目标,超越自我 1131

手把手教你学simulink(36.1)--ACAC变换器场景示例:基于 Simulink 的矩阵变换器(Matrix Converter)

矩阵变换器(Matrix Converter, MC)是一种直接将交流电(AC)转换为不同频率和幅值的交流电的电力电子设备。与传统的基于直流环节的变频器不同,矩阵变换器不需要中间的直流环节,而是通过双向开关直接在输入和输出之间进行能量传递。这种结构使得矩阵变换器具有更高的效率、更小的体积和更好的动态响应。在本项目中,我们将使用 MATLAB/Simulink 来建模和仿真一个矩阵变换器,并分析其性能。Simulink 是一个强大的仿真工具,特别适合用于电力电子系统的建模和仿真。

MHD0815的博客 1055

基于Xilinx K7-410T的高速DAC之AD9129开发笔记(一)

引言:从本文开始,我们介绍下项目中设计的并行LVDS高速DAC接口设计,包括DAC与FPGA硬件接口设计、软件设计等。项目设计高速DAC采用了ADI公司的AD9129,该芯片最大更新速率5.7Gsps,该芯片在宽带通信应用、LTE、雷达信号产生、干扰机等领域有广泛应用。

FPGA_Designer 2531

TCP粘包及拆包详解

一、 TCP粘包 TCP粘包 就是指发送方发送的若干包数据到达接收方时粘成了一包,从接收缓冲区来看,后一包数据的头紧接着前一包数据的尾,出现粘包的原因是多方面的,可能是来自发送方,也可能是来自接收方。 正常情况: 出现粘包现象: 二、出现TCP粘包的原因 发送方原因 TCP默认使用Nagle算法(主要作用:减少网络中报文段的数量),而Nagle算法主要做两件事: 只有上一个分组得到确认,才会...

qq_35887546的博客 2347

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

TCP的粘包拆包技术

TCP 是一个面向「流」的协议,所谓流就是没有界限的一长串二进制数据。在实际的传输过程中,TCP 会根据网络情况将数据包进行拆分或者拼装,如果业务没有定义一个明确的界限规则,在应用层的业务上就会出现粘包拆包的现象。 平时大家在网络编程过程中可能会遇到这样一种现象:客户端发送了一长串消息,服务端接受的消息揉在一起或者被拆分了,这样就会造成消息难以被正确理解。比如说有一天你特别想喝奶茶,看了一下外卖,「一点点」的奶茶看着不错,(一点点赶紧给我打钱 doge),于是你在群里发了一条消息,想找几个人拼奶茶: 一

Free雅轩的博客 3179

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

网络编程:TCP粘包问题——各层粘包/拆包、Nagle 算法、Go实现长度字段协议解决TCP粘包、使用TCP的应用层协议设计

需要注意的是,即使是连续发送大量数据,在正常的网络环境和合理的数据处理方式下,TCP通常可以保持数据包的完整性和顺序,不会出现粘包。当发送方过于迅速发送数据而使接收方无法跟上或处理不当,此时**可能**发生粘包问题。注意,TCP粘包问题并非TCP协议设计上的缺陷,而是由于TCP协议的数据传输特性和网络条件的影响所致。解决TCP粘包问题通常需要应用层协议设计或使用特定的数据分隔方式来确的数据传输和解析。长度字段协议(Length-Field Protocol):发送方在每个数据包前部添加一个表示数据包长度的字

Pistachiout的学习博客 4572

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

TCP粘包和拆包问题及其解决方法

TCP粘包和拆包问题及其解决方法

AGangyaa的博客 5029

一文搞懂!TCP 粘包和拆包原理详解!

粘包是指多个应用层独立发送的数据包在传输过程中被合并为一个 TCP 数据包到达接收方,接收方无法区分这是一个还是多个数据包。拆包是指一个应用层发送的数据包被分割成多个 TCP 数据包到达接收方,接收方需要将这些分段数据重组才能完整获取原始消息。TCP作为流式协议,没有内置的消息边界机制,这导致了粘包和拆包的问题。粘包是多个消息被合并为一个数据包,拆包是一个消息被分割为多个数据包。解决粘包和拆包的关键在于应用层协议的设计,通过固定长度、分隔符或长度字段等方式明确消息的边界。

Java架构师之路的博客 1399

TCP 拆包和粘包原因及解决方案

文章目录1. 拆包和粘包的概念2. 产生拆包和粘包的原因3. 解决方案 1. 拆包和粘包的概念 2. 产生拆包和粘包的原因 3. 解决方案

谈谈1974 3709

TCP中的拆包和粘包

拆包和粘包是在网络编程中比较常见的现象。因为TCP协议底层是面向流的传输。所以数据在传输的过程中,会被分割成一个个的数据包,接收端在接收数据的时候需要重新组装数据包,但是TCP协议不保证数据包与应用层的数据交互一一对应。所以就有可能造成数据不完整的问题。因此候选人在回答这个问题之前,必须要了解这个问题的发生背景。否则回答不到点上,就会错过这次机会。

qq_46130027的博客 293
上一篇: 【计网】什么是三次握手四次挥手
下一篇: 【计网】TCP在可靠传输中都干了啥
陈宝子
陈宝子 新星创作者: Java技术领域 新星创作者: Java技术领域
博客等级 码龄5年 8672粉丝 77原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈宝子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值