当前位置: 首页 > news >正文

深入理解TCP网络协议(3)

目录

1.前言

2.流量控制

2.阻塞控制

3.延时应答

4.捎带应答

5.面向字节流

6.缓冲区

7.粘包问题

8.TCP异常情况

9.小结


1.前言

   在前面的博客中,我们重点介绍了TCP协议的一些属性,有连接属性的三次握手和四次挥手,还有保证数据安全的重传机制和确认应答,还有为了提高效率所用的滑动窗口等.然而TCP协议的特性远不止这些,在这篇博客中,我们将更深入的了解决TCP协议的其它特性.

2.流量控制

  滑动窗口我们知道是用来提升传输效率的,这个窗口如果越大的话,那么自然传输效率也就越高,那么这个窗口可以无限增大吗?答案是否定的,首先从接收方的角度来看,接收方是有接收缓冲区的,如果这个窗口过大,发的数据过多,极有可能把这个缓冲区占满,那么就会引起一系列的问题.站在发送方的角度来看,也不能一次发送太多数据,因为我们不知道路上的网络线路是否通畅,能不能一次承担这么多的数据而不损失稳定性(这个我们一会在介绍).

   首先我们站在接收方的角度,其实接收方返回给发送方的ACK报头里面,是有一个窗口大小属性的,这个属性的大小取决于接收缓冲区剩余的内存大小.我们来画图说明一下.

有了接收方这个窗口大小这个字段,发送方就知道自己一次性发送多大的数据合适,就可以进行不影响可靠性的前提下提升效率了.

2.阻塞控制

在前面我们提到过,不仅仅是接收方要进行流量控制,告诉发送方要发多大的.在发送方这里,由于物理线路的影响,我们也得知道我们发送多大的合适,那么在TCP协议里,是如何知道网络的情况,以决定我们发送多大的数据合适呢?

这就要讲到我们的阻塞控制了.  我先来说一下基本的原理,我们可以先呈指数倍的发送数据,看有没有ack响应,如果都没问题的话,到了一定的阈值,我们可以在逐渐增大,一直到有数据丢失了(即没有收到ack,说明网络线路出问题了,可能到了它能承受的最大值,我们就接着降下去,在逐渐增大. 这是一个动态平衡的过程.这种思绪想是一种实验的方式来测试.

 当TCP开始启动的时候,慢启动阈值等于窗口最大值;
在每次超时重发的时候,慢启动阈值会变成原来的一半,同时拥塞窗口置回1;
少量的丢包,我们仅仅是触发超时重传;大量的丢包,我们就认为网络拥塞;
当TCP通信开始后,网络吞吐量会逐渐上升;随着网络发生拥堵,吞吐量会立刻下降;
拥塞控制,归根结底是TCP协议想尽可能快的把数据传输给对方,但是又要避免给网络造成太大压力的折中方案

还有一个问题就是,我们到底是根据发送方的阻塞控制来确定窗口大小,还是根据接收方的流量控制来决定呢?

事实是,哪个小我们就遵守哪个.有点类似于木桶效应

3.延时应答

 如果接受数据的时候立即响应ack,这时候返回的窗口可能就比较小,为了解决这种问题.TCP协议内部还有一个延时应答的机制.

假设接收端缓冲区为1M。一次收到了500K的数据;如果立刻应答,返回的窗口就是500K;
但实际上可能处理端处理的速度很快,10ms之内就把500K数据从缓冲区消费掉了;
在这种情况下,接收端处理还远没有达到自己的极限,即使窗口再放大一些,也能处理过
来;
如果接收端稍微等一会再应答,比如等待200ms再应答,那么这个时候返回的窗口大小就是
1M
事实上,这个时间的延时在用户眼里是非常小的,所以我们完全可以为了提升传输效率(返回的窗口大一些)使用延时应答机制.我们的目的是确保网络不拥堵的情况下,尽量提高传输效率.

那么所有的包都可以延迟应答么?肯定也不是;
数量限制:每隔N个包就应答一次;
时间限制:超过最大延迟时间就应答一次;
具体的数量和超时时间,依操作系统不同也有差异;一般N取2,超时时间取200ms

4.捎带应答

在延迟应答的基础上,我们发现,很多情况下,客户端服务器在应用层也是 "一发一收" 的。意味着客户端给服务器说了 "are  you ok?",服务器也会给客户端回一个 "very ok";
那么这个时候ACK就可以搭顺风车,和服务器回应的 "very ok" 一起回给客户端
 

5.面向字节流

TCP协议发送和接收的数据都是面向字节流的,我们可以给它传入一个byte数组,把我们想要的数据给转化成二进制的形势发送过去.接收的时候在转成对应的格式即可.

6.缓冲区

创建一个TCP的socket,同时在内核中创建一个 发送缓冲区 和一个 接收缓冲区;
调用write时,数据会先写入发送缓冲区中;
如果发送的字节数太长,会被拆分成多个TCP的数据包发出;
如果发送的字节数太短,就会先在缓冲区里等待,等到缓冲区长度差不多了,或者其他合适
的时机发送出去;
接收数据的时候,数据也是从网卡驱动程序到达内核的接收缓冲区;
然后应用程序可以调用read从接收缓冲区拿数据;
另一方面,TCP的一个连接,既有发送缓冲区,也有接收缓冲区,那么对于这一个连接,既
可以读数据,也可以写数据。这个概念叫做 全双工
由于缓冲区的存在,TCP程序的读和写不需要一一匹配,例如:
写100个字节数据时,可以调用一次write写100个字节,也可以调用100次write,每次写一
个字节;
读100个字节数据时,也完全不需要考虑写的时候是怎么写的,既可以一次read 100个字
节,也可以一次read一个字节,重复100次


7.粘包问题

TCP协议没有像UDP 一样有一个报文长度这样的字段,但是有一个序号这个字段.在传输层的角度,TCP报文是一个一个传输过来的,排列好的数据在缓冲区中,但是在应用层的角度,只是看到了一连串的字节数据,那么应用层看到的这些数据,就不知道应该从哪一部分到哪一步部分是一块的, 是不是一个完整的应用层数据报.

如何解决这个问题呢?我们三种方案

1.对于定包的长,我们每次都读取固定大小的的数据即可,

2.对于边长的包,我们可以在包头设置一个总包长度的字段,从而就知道了包结束的位置.

3.我们也可以在包和包中间使用明确的分隔符(应用层协议是程序员自己约定的,只要不影响数据,即正文的数据不和这个分隔符冲突久可.

粘包问题只是在TCP协议中会出现,并不会在UDP中出现,这是因为UDP是把英国摇滚乐数据交给应用层,要么收到完整的数据报,要么不收,不会出现半个的问题.所以不会有粘包问题.

8.TCP异常情况

我们知道TCP是有连接的,那么在出现异常的时候,TCP是如何断开连接的呢?我们分别来说明

进程中止:进程中止会释放文件描述符,仍然可以发送断开连接的FIN,和正常关闭没啥区别.

机器重启:重启的时候也会释放文件描述符,所以和进程中止的情况一样.

机器断网/断电:

1.如果断电的是接受方,发送方会发现没有ack了,会重传,重传几次还是不行, 就会进行复位操作,(相对于清楚原来的TCP中的临时数据重新开始)会用到RST这个复位报文段(和ack,fin,syn这些一样的报文段,另外,PSH是催促对方快点给我发消息,URG是TCP外带数据,语言写特殊的数据报会携带一些特殊功能的数据)  此时是RST也不会有ack,这个时候发送方就会单方面放弃连接.

2.如果是发送方接收了,发送方迟迟等不到数据,他会发送一个"心跳包",来询问对方的情况,如果这个"心跳包"一直没有得到回应,自然也会单方面释放连接了,这个心跳包是一个周期性的,如果没有心跳就会认为对端挂了,在以后的分布式系统中,服务器之间的互相调用也需要心跳包来确定存货状态.

9.小结

其实TCP协议非常复杂,它不仅仅是有我们前面几篇博客和这篇博客中强调的特性,还有其它的特性,希望各位大佬程序员这条路的修炼中,刻苦钻研,努力发掘.让自己的技术和对底层的 理解更上一层楼.

相关文章:

深入理解TCP网络协议(3)

目录 1.前言 2.流量控制 2.阻塞控制 3.延时应答 4.捎带应答 5.面向字节流 6.缓冲区 7.粘包问题 8.TCP异常情况 9.小结 1.前言 在前面的博客中,我们重点介绍了TCP协议的一些属性,有连接属性的三次握手和四次挥手,还有保证数据安全的重传机制和确认应答,还有为了提高效率…...

JavaScript实现归并排序及vscode输出乱码解决

思路 归并排序思路:11.6 归并排序 - Hello 算法 总体上来讲就是 递归分解 归并排序 代码如下↓ 代码 //归并排序 function merge(left, right){console.log(flag);console.log(left);console.log(right);let result new Array();let il 0, ir 0;//左右两个数…...

Redis面试题40

人工智能如何影响医疗保健行业? 答:人工智能对医疗保健行业产生了深远的影响,为医疗保健提供了更高效、准确和个性化的服务。以下是一些人工智能在医疗保健领域的应用示例: 疾病诊断:人工智能可以利用机器学习和深度学…...

2024年危险化学品经营单位安全管理人员证考试题库及危险化学品经营单位安全管理人员试题解析

题库来源:安全生产模拟考试一点通公众号小程序 2024年危险化学品经营单位安全管理人员证考试题库及危险化学品经营单位安全管理人员试题解析是安全生产模拟考试一点通结合(安监局)特种作业人员操作证考试大纲和(质检局&#xff0…...

Kafka相关内容复习

为什么要用消息队列 解耦 允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束。 可恢复性 系统的一部分组件失效时,不会影响到整个系统。消息队列降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队…...

JVM之Java内存区域

JVM-Java内存区域 Java内存区域是Java虚拟机(JVM)管理的内存资源的逻辑划分,用于存储程序运行时所需的数据。Java内存区域的合理划分和管理对于程序的性能和稳定性具有重要影响。本文将深入探讨Java内存区域的各个部分,包括方法区…...

几个MySQL系统调优工具

几个MySQL系统调优工具 可以使用下面几个工具来做基准测试: sysbench:一个模块化,跨平台以及多线程的性能测试工具。 https://github.com/akopytov/sysbench iibench-mysql:基于Java的MySQL / Percona / MariaDB 索引进行插入性能…...

Linux内核与驱动面试经典“小”问题集锦(2)

接前一篇文章:Linux内核与驱动面试经典“小”问题集锦(1) 问题2 问:spin_lock和spin_lock_irq以及spin_lock_irqsave的区别是什么?也可以说它们之间有什么区别和联系? 备注:此题是自旋锁问题的…...

windws安装mysql详细步骤

1.下载地址: https://dev.mysql.com/downloads/mysql/2.下载好mysql安装包后,将其解压到指定目录,并记下解压的目录,后续用于环境变量配置: 3. 在bin目录同级下创建一个文件,命名为my.ini [mysqld] # 设…...

Linux的库文件

目录 概述: 静态库: 静态库概述: 静态库的制作 共享库(动态库) 共享库概述 动态库制作 动态库临时生效 动态库长期生效 动态库的升级 位置无关代码 概述: 库文件一般就是编译好的二进制文件&…...

JAVA Web 学习(五)Nginx、RPC、JWT

十二、反向代理服务器——Nginx 支持热部署,几乎可以做到 7 * 24 小时不间断运行,即使运行几个月也不需要重新启动,还能在不间断服务的情况下对软件版本进行热更新。性能是 Nginx 最重要的考量,其占用内存少、并发能力强、能支持…...

Python编程的十大神奇依赖库

Python是一门广受欢迎的编程语言,其生态系统丰富多彩,拥有许多令人惊叹的依赖库,可以帮助程序员们在各种领域中创造出令人瞠目结舌的应用。在这篇文章中,我们将探讨Python编程的十大神奇依赖库,它们像魔法一样&#xf…...

Java类的继承

XHTMLMapper继承 XWPFDocumentVisitor&#xff1a; 由于endVisitTableCell是抽象方法&#xff0c;XHTMLMapper中必须要实现&#xff1b; existErr()子类是否重写都是自由的&#xff1b; public abstract class XWPFDocumentVisitor<T, O extends Options, E extends IXWPFM…...

【DC渗透系列】DC-4靶场

主机发现 arp-scan -l┌──(root㉿kali)-[~] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:6b:ed:27, IPv4: 192.168.100.251 Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.100.1 00:50:56:c0:00:08 …...

开源软件全景解析:驱动技术创新与行业革新的力量

目录 什么是开源 开源的核心 开源软件的特点 为什么程序员应该拥抱开源 1.学习机会&#xff1a; 2.社区支持&#xff1a; 3.提高职业竞争力&#xff1a; 4.加速开发过程&#xff1a; 5.贡献和回馈&#xff1a; 开源软件的影响力 开源软件多元分析&#xff1a; 开源…...

目标检测及相关算法介绍

文章目录 目标检测介绍目标检测算法分类目标检测算法模型组成经典目标检测论文 目标检测介绍 目标检测是计算机视觉领域中的一项重要任务&#xff0c;旨在识别图像或视频中的特定对象的位置并将其与不同类别中的对象进行分类。与图像分类任务不同&#xff0c;目标检测不仅需要…...

跟着cherno手搓游戏引擎【20】混合(blend)

抽象&#xff1a; Renderer.h: #pragma once #include"RenderCommand.h" #include "OrthographicCamera.h" #include"Shader.h" namespace YOTO {class Renderer {public:static void Init();static void BeginScene(OrthographicCamera& …...

leetcode 3.无重复字符的最长字串(滑动窗口) (C++)DAY2

文章目录 1.题目示例提示 2.解答思路3.实现代码结果 4.总结 1.题目 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例 示例 1: 输入: s “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”&#xff0c;所以其长度为 3。 示…...

Android Build 依赖项

在项目中的Build.Gradle文件中dependencies代码块中添加指定依赖项。 有三种不同类型的依赖项 本地模块依赖项 implementation project(:mylibrary)这个mylibrary 必须在 settings.gradle 中使用的库名称相同 本地文件依赖项 implementation fileTree(dir: libs, include:…...

SpringMVC精简知识点

SpringMVC 数据格式化基本数据类型和字符串自动转换特殊数据类型和字符串自动转换 验证及国际化应用实例注意事项和使用细节注解的结合使用数据类型转换校验核心类-DatBinder取消某个属性的绑定中文乱码解决处理json和HttpMessageConverter<T>作业布置SpringMVC文件上传自…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

Pinocchio 库详解及其在足式机器人上的应用

Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库&#xff0c;专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性&#xff0c;并提供了一个通用的框架&…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

wpf在image控件上快速显示内存图像

wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像&#xff08;比如分辨率3000*3000的图像&#xff09;的办法&#xff0c;尤其是想把内存中的裸数据&#xff08;只有图像的数据&#xff0c;不包…...