tcp协议的面向字节流介绍,粘包问题(解决的本质)

目录

面向字节流

引入

介绍

比喻

处理数据 

粘包问题

引入

介绍

解决的本质


面向字节流

引入

对于udp来说,它是面向数据报的

  • 一旦要发送数据,因为没有发送缓冲区,且不需要维护连接,直接封装完报头就发出去了
  • 依靠报头中的udp长度字段,可以拆分出报文然后交付给上层
  • 一个报文里就是一次响应/请求的全部数据

但是对于tcp协议来说

  • 它需要维护一个持续的连接,数据也就得是连续的
  • 并且他有两个缓冲区,所以读写操作不需要一一匹配
  • 比如,一次写了100字节,然后分10次读 / 分10次写完100字节,一次读出,这都是可以的
  • 它可以根据需要,写入/读取任意长度的数据,tcp会负责将这些数据分割成合适大小的报文段进行传输

 

介绍

对于tcp来说,假设我们发送了4个请求给对方:

  • 应用层看来,是4个请求报文
  • 但从传输层看来,这些只是若干个字节数据,它只保证如何安全地可靠地将这些数据发送给对方,并且发送的数量不定,由对方的接收能力决定
  • 当对方的传输层接收到后,也同样只认识字节,它不管,它只管往上交付若干字节

所以,实际上只有用户层有报文的概念

在传输层看来:

  • 就是有若干字节数据进缓冲区->出缓冲区->进缓冲区->出缓冲区
  • 于是就有了字节流动的概念,这就叫面向字节流 

比喻

其实面向字节流很像水流

  • 传输层是一条水管,它不管水是哪来的,只管运输
  • 另一方无论是用杯子接,用盆接都行,接多少都行,只要还有水

处理数据 

但交付的这些字节并不能保证就是一份报文

  • 所以需要在应用层定义一个缓冲区一直读,边读边对数据进行解析(要么不读,要么就读上来一份完整的数据)
  • 解析成功后就拿走,剩下的继续重复上述步骤

我们在网络计算器里也正是这样做的

  • 这些处理属于我们之前的encode/decode范畴,和序列化/反序列化有上下层关系

但是边读边解析效率比较低

  • 我们已经介绍过tcp的传输控制机制,能知道 -- 如果自己的接收窗口更大,对方就会动态调整自己的滑动窗口大小,可以传过来更多的数据,可以提高传输效率
  • 所以,我们最好是一有数据就全部读到用户层,再慢慢处理

 

粘包问题

引入

如果它没有制定协议,没有任何的处理,直接读

  • 读上来的就是未知字节数的数据,可能是半个报文/一个半/多个
  • 总之它处理不了,只能丢弃,但丢弃了就很大概率会影响之后的处理(因为数据不完整了)
  • 而这样的情况,就叫做数据报粘包问题

就像:

  • 蒸包子/馒头,蒸好后去拿,你本来只想拿一个,但拿起来了一个多/多个/半个

介绍

粘包只是针对用户层的概念

  • 因为传输层面向字节流,对它来说没有报文的概念,自然也就不存在粘包问题

而解决粘包的方法就是制定协议

  • 在之前的网络计算器里就有体现,我们封装了数据长度和特殊字符,使用encode/decode函数做封装和解包

其实不仅只有应用层要解决,下层也需要

  • 因为他们处理数据也得先分出一份完整报文,才能进行封装报头/其他处理
  • 而传递的数据还是以字节为单位

解决的本质

总结一下,解决粘包问题的本质是 -- 在应用层通过协议,明确报文之间的边界

  • 定长报文
  • 使用特殊字符
  • 自描述字段+定长报文 (udp)
  • 自描述字段+特殊字符 (网络计算器,http -- 报头里记录了有效载荷的长度,但报头长度不固定,所以添加特殊字符(空行)作为报头结束的标志)

分离报文后,才进入序列化/反序列化的逻辑

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/26013.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决Vue项目Network: unavailable的问题

在vscode使用 npm run serve 运行 Vue项目时发现一个问题,项目只能通过Local访问而不能通过Network访问,终端显示如下: 碰到这种情况的解决方法:在环境变量的path中添加“C:\Windows\System32\Wbem” 1.找到“环境变量”&#xf…

Apollo9.0 PNC源码学习之Control模块(二)

前面文章:Apollo9.0 PNC源码学习之Control模块(一) 本文将对具体控制器以及原理做一个剖析 1 PID控制器 1.1 PID理论基础 如下图所示,PID各参数(Kp,Ki,Kd)的作用: 任何闭环控制系统的首要任务是要稳、准、快的响…

【JavaEE】Spring Boot MyBatis详解(一)

一.MyBatis的基本概念与相关配置. 1.基本概念 MyBatis是一款优秀的持久层框架,用于简化JDBC的开发。MyBatis本是Apache的一个开源项目iBatis,2010年这个项目由apache迁移到了google code,并且改名为MyBatis. 2013年11月迁移到Github.持久层…

.net core webapi跨域

var builder WebApplication.CreateBuilder(args);// Add services to the container. // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen();//此处1 …

13 RTP包的使用

RTP RTP包最主要的就是Sequence number。 对于发送者来说,视频的每一个帧都有很多包组成。对于接收端来接收的时候是有一个队列进行接收的。这个队列大小都是通过计算的。有了队列之后就会不断的往队列中插入数据。当队列中有的数据超时一直组不成包的时候&#xf…

STM32 UART串口与RTOS的结合使用

STM32 UART串口与RTOS的结合使用 摘要: 实时操作系统(RTOS)为嵌入式系统提供了多任务处理和实时性能。STM32微控制器结合RTOS,可以有效地管理串口通信任务,提高系统的响应速度和稳定性。本文将探讨STM32 UART串口与RT…

MacOS升级ruby版本

MacOS自带ruby版本是2.x,可以通过“ruby -v”查看版本号 $ ruby -v ruby 2.6.10p210 (2022-04-12 revision 67958) [universal.x86_64-darwin22]homebrew安装的ruby版本号可以通过“brew info ruby”命令参看 $ brew info ruby > ruby: stable 3.3.2 (bottled)…

深度学习的可微渲染

深度学习的可微渲染 可微渲染(Differentiable Rendering)是深度学习领域的一个重要概念,它将传统的计算机图形学与深度学习结合起来,通过使渲染过程可微分(differentiable),以便于在深度学习模…

SpringMVC01-初始SpringMVC

SpringMVC 回顾MVC 什么是MVC MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范。是将业务逻辑、数据、显示分离的方法来组织代码。MVC主要作用是降低了视图与业务逻辑间的双向偶合。MVC不是一种设计模式,MVC是一种架构模…

如何使用Pandas处理数据?

一、技术难点 Pandas是Python中一个强大的数据处理和分析库,它提供了高效、灵活且易于使用的数据结构,主要用于数据清洗、转换、聚合和可视化等任务。然而,在使用Pandas处理数据时,也会遇到一些技术难点。 数据导入与导出&#…

Python装饰器:打造强大的日志记录系统

题目:Python装饰器:打造强大的日志记录系统 摘要: 在Python编程中,装饰器是一种强大的工具,它允许我们以一种非常灵活的方式增强函数的功能。本文将详细介绍如何使用装饰器来实现日志记录,这是一种在开发过程中追踪函数调用和执行情况的有效手段。我们将从装饰器的基本…

Go singlefight 源码详解|图解

写在前面 通俗的来说就是 singleflight 将相同的并发请求合并成一个请求,进而减少对下层服务的压力,通常用于解决缓存击穿的问题。 详解 基础结构 golang.org/x/sync/singleflight singleflight结构体: type call struct {wg sync.WaitGro…

Linux系统下非高精度对时实操

测试对时偏差 使用 ntpdate -d 选项, 挑选一个合适的ntp对时地址比如 ntp.tencent.com 或者 time.pool.aliyun.com 使用 /usr/sbin/ntpdate -d ntp.tencent.com, 可以看到如下结果, 其中offset 就代表NTP服务器时间- 系统时间, 所以offset 0.012036 sec 就代表系统时间比NTP服…

[Java] TDengine时序数据库时间戳(timestamp)字段插入数据的实现方法

👉原文阅读 目录 👉[原文阅读](https://b1ankc-mov.github.io/posts/tdengine_timestamp/) 📘正文开始实体类Mapper接口Controller控制器 📘正文开始 实体类 定义实体类,插入数据分别代表打卡时间、员工id&#xff0…

如何在WPS中加载EndNote X9插件

如何在WPS中加载EndNote X9插件 步骤1:关闭WPS 确保所有WPS文档和窗口都已关闭。 步骤2:修改文件后缀 打开文件资源管理器,导航到路径:C:\Program Files (x86)\EndNote X9\Product-Support\CWYW。找到文件 Cwyw_X86.dat&#…

正排索引和倒排索引的区别

正排索引和倒排索引是数据库中常见的两种索引方式,它们有以下区别: 1. 数据结构不同:正排索引是按照文档的顺序存储索引,而倒排索引是根据关键词来存储索引。 2. 查询方式不同:正排索引适合按文档顺序进行查询&a…

glibc函数malloc的工作原理

glibc提供了malloc函数来动态分配内存,我们只知道调用malloc会返回给我们一个指针,指向一块内存空间或NULL,那么malloc的工作原理是什么呢? 概述: 1.小于128kB的空间,使用内存池(在堆上&#…

高效能光伏监控解决方案 —— ARMxy工业计算机深度解析

在浩瀚的戈壁滩上,一座现代化的光伏电站正沐浴在烈日之下,将无尽的阳光转化为清洁的电能。这背后,离不开一项关键技术的支撑——ARMxy工业计算机,它如同一位智慧的指挥官,精确掌控着这座绿色能源基地的心跳。 面对广袤…

鱼香肉丝ROS一键安装

鱼香肉丝ROS一键安装实际上是指通过特定的脚本和工具,快速地在Ubuntu系统上安装ROS(Robot Operating System,机器人操作系统)。由于“鱼香肉丝”并非与ROS安装直接相关的术语,我猜测这里可能是对某个特定ROS安装脚本或…

王学岗鸿蒙开发(北向)——————(十三)音乐播放器

AudioRenderer适合录音 AVPlayer:简单的本地单曲播放 MP3文件放置的地方 import media from ohos.multimedia.media import common from ohos.app.ability.common; Entry Component struct Index {//第1步:avPlayer:media.AVPlayer nullasync onPageShow(){//第…