TCP(下):三次握手四次挥手 动态控制

欢迎浏览高耳机的博客

希望我们彼此都有更好的收获

感谢三连支持!  

 TCP(上):成熟可靠的传输层协议-CSDN博客

        🥝在上篇博客中,我们针对TCP的特性,报文结构,连接过程以及相对于其他协议的区别进行了探讨,提供了初步的理解和概览。本篇中,我们将重点展开包括TCP的三次握手和四次挥手过程、滑动窗口、拥塞控制、捎带应答、延迟应答以及粘包等问题,这些都是TCP协议的关键组成部分。 

目录

连接管理 

 三次握手

四次挥手

滑动窗口 

流量控制

拥塞控制

延迟应答&捎带应答

粘包问题 

异常处理 

TCP小结


连接管理 

 🥥三次握手,四次挥手 是TCP中一个形象且重要的建立连接的机制 也是最常考的机制。

 所谓的 建立连接 ,就是通信双方各自保存对方的信息。

 三次握手

        SYN是"Synchronize"的缩写,在网络中意为“同步”。在三次握手过程中,SYN标志位用来同步连接双方的序列号,确保数据传输的顺序性和可靠性。通过交换SYN标志位的数据包,TCP连接的两端可以确认彼此都准备好进行数据传输,并且可以正确地识别和排序收到的数据包。

        ACK是"Acknowledgment"的缩写,在网络中意为“确认”。ACK标志位用于确认收到的数据包。当一个TCP段被成功接收并且没有错误时,接收方会发送一个带有ACK标志位的数据包给发送方,以告知发送方该数据包已经被成功接收。

🍇明明是"三次握手",可为什么有四个连接步骤??

将第二第三次连接步骤合并,便是三次握手的完整形态: 

        🍈如上图所示。而之所以将其合并,主要目的是提高建立连接的效率和减少延迟,服务器端可以在确认客户端的SYN请求的同时,发送自己的SYN请求,这样双方就可以在一次数据包交换中完成序列号的同步和确认,提高了建立连接的效率。同时也有节省带宽的考虑。这种设计使得TCP能够在保证可靠性的同时,提高网络通信的性能。这里运用了捎带应答的机制,下面会介绍到。

四次挥手

 

        FIN是"Finish"的缩写,FIN标志位用于终止一个已经建立的连接。FIN标志位的发送和接收标志着连接的结束阶段

  1. 第一次挥手(客户端)

    客户端决定关闭连接,并向服务器发送一个FIN标志位的数据包。这个FIN包不包含任何数据,它的作用是告诉服务器:“我这边没有数据要发送了,你可以关闭连接了。”
  2. 第二次挥手(服务器)

    服务器接收到客户端的FIN包后,会发送一个ACK标志位的数据包作为响应,确认已经收到客户端的FIN请求。这个ACK包告诉客户端:“我收到了你的关闭请求。”
  3. 第三次挥手(服务器)

    如果服务器还有未发送完的数据,它会先发送完这些数据。一旦所有数据都发送完毕,服务器也会发送一个FIN标志位的数据包给客户端,告诉客户端:“我这边也没有数据要发送了,可以关闭连接了。”
  4. 第四次挥手(客户端)

    客户端接收到服务器的FIN包后,会发送一个ACK标志位的数据包作为响应,确认已经收到服务器的FIN请求。这个ACK包告诉服务器:“我收到了你的关闭请求,现在可以关闭连接了。”

        🍉TCP四次挥手的过程中,不进行合并的原因与三次握手的情况有所不同,主要基于以下几个方面:

  1. 连接终止的单向性

    • 三次握手是建立双向通信的过程,双方都需要准备好发送和接收数据,因此需要同步序列号。
    • 四次挥手是终止连接的过程,通常是由一方(通常是客户端)发起,另一方(通常是服务器)响应。连接的终止可以是单向的,意味着一方可能还有数据要发送,而另一方可能已经没有数据要发送了。
  2. 确保数据传输完成

    • 在TCP连接中,当一方想要关闭连接时,它需要确保所有已经发送的数据都被对方接收。这通常涉及到等待数据传输的确认。
    • 四次挥手中的FIN标志位用来告知对方“我这边没有数据要发送了”,但这并不意味着所有的数据都已经被对方接收。因此,需要等待对方确认收到FIN,并且等待所有未确认的数据包被确认接收。
  3. 避免混淆状态

    • 如果在挥手过程中合并FIN和ACK,可能会导致状态混淆。例如,如果一个FIN+ACK包被发送,接收方可能会不清楚这是一个新的连接请求还是一个连接终止请求。
  4. 确保可靠性

    • 在TCP中,确保数据的可靠传输是非常重要的。在四次挥手中,每个FIN都需要一个对应的ACK来确认,这样可以确保双方都知道连接即将关闭,并且所有数据都已经被接收和处理。

        综上所述,四次挥手不进行合并是为了确保数据的可靠传输,避免状态混淆,以及确保资源的正确释放。这个过程虽然看起来效率较低,但它确保了TCP连接的可靠性和稳定性。

🍊TCP三次握手四次挥手的完整过程:

 🍋三次握手四次挥手建立连接的意义:
1.投石问路,抛砖引玉,确认当前通信路径的通畅

2.协商参数,通信双方共同确认一些通信中的必备参数数值

!!!注意!!!

TCP可靠性的保证不是三次握手四次挥手,而是确认应答和超时重传~

滑动窗口 

        🍍在上篇以及连接管理中,都涉及到了确认应答策略,对每一个发送的数据段,都要回复一个ACK确认应答。收到ACK后再发送下一个数据段。这样做有一个比较大的缺点,就是性能较差。尤其是数据往返的时间较长的时候。

        既然一发一收的方式性能较低,那么一次发送多条数据,就可以大大的提高性能(其实是将多个段的等待时间重叠在了一起)。

        窗口大小指的是无需等待确认应答而可以继续发送数据的最大值。上图的窗口大小就是4000个字节(四个段)。

        发送前四个段的时候,不需要等待任何ACK,直接发送;收到第一个ACK后,滑动窗口向后移动,继续发送第五个段的数据,依此类推;操作系统内核为了维护这个滑动窗口,需要开辟发送缓冲区来记录当前还有哪些数据没有应答;只有确认应答过的数据,才能从缓冲区删掉;窗口越大,则网络的吞吐率就越高。

        🍎如果在滑动窗口中出现丢包:若ACK丢失,则可以通过后续的ACK进行确认,问题不大;若数据包丢失,则ACK会一直返回丢包前的对应序列号,发送端就会重新发送这一部分数据,这种机制被称为"高速重发控制"。

流量控制

        🍑接收端处理数据的速度是有限的。如果发送端发得太快,导致接收端的缓冲区被塞满,这个时候如果发送端继续发送,数据无处存放,就会造成丢包,继而引起丢包重传等一系列连锁反应。

        因此TCP支持根据接收端的处理能力来决定发送端的发送速度,这个机制就叫做流量控制(Flow Control)。

        接收端将自己可以接收的缓冲区大小放入TCP首部中的“窗口大小”字段,通过ACK端通知发送端。窗口大小字段越大,说明网络的吞吐量越高。接收端一旦发现自己的缓冲区快满了,就会将窗口大小设置成一个更小的值通知给发送端。发送端接收到这个窗口之后,就会减慢自己的发送速度。如果接收端缓冲区满了,就会将窗口置为0;这时发送方不再发送数据,但是需要定期发送一个窗口探测数据段,使接收端把窗口大小告诉发送端。

        接收端如何把窗口大小告诉发送端呢?TCP首部中有一个16位窗口字段,存放了窗口大小信息。

        🍓那么,16位数字最大表示65535,那么TCP窗口最大就是65535字节么?实际上,TCP首部40字节选项中还包含了一个窗口扩大因子M,实际窗口大小是窗口字段的值左移M位。在位运算中,左移一位代表着乘以2,那么左移M位则是乘以2的M次方。

如果说滑动窗口是TCP在踩油门_那么流量控制就是TCP在踩刹车

并且,流量控制并不是TCP所独有的,数据链路层中的某些协议,也有流量控制机制

拥塞控制

        🫐虽然TCP有了滑动窗口这个利器,能够高效可靠的发送大量的数据。但是如果在刚开始阶段就发送大量的数据,仍然可能引发问题。因为网络上有很多的计算机,可能当前的网络状态就已经比较拥堵。在不清楚当前网络状态下,贸然发送大量的数据,是很有可能雪上加霜的。

        所以TCP引入慢启动机制,先发少量的数据,探探路,摸清当前的网络拥堵状态,再决定按照多大的速度传输数据。

        此处引入一个概念称为拥塞窗口。发送开始的时候,定义拥塞窗口大小为1;每次收到一个ACK应答,拥塞窗口加1;每次发送数据包的时候,将拥塞窗口和接收端主机反馈的窗口大小做比较,取较小的值作为实际发送的窗口。

        像上面这样的拥塞窗口增长速度,是指数级别的。“慢启动”只是指初始时慢,但是增长速度非常快。为了不增长的那么快,因此不能使拥塞窗口单纯的加倍。此处引入一个叫做慢启动的阈值。当拥塞窗口超过这个阈值的时候,不再按照指数方式增长,而是按照线性方式增长。当TCP开始启动的时候,慢启动阈值等于窗口最大值;在每次超时重发的时候,慢启动阈值会变成原来的一半,同时拥塞窗口置回1。

        🥝少量的丢包,仅仅是触发超时重传;大量的丢包,就会认为网络拥塞。当TCP通信开始后,网络吞吐量会逐渐上升;随着网络发生拥堵,吞吐量会立刻下降。这是TCP的动态控制机制。 

        拥塞控制,归根结底是TCP协议想尽可能快地把数据传输给对方,但是又要避免给网络造成太大压力的折中方案。

面多加水_水多加面!

延迟应答&捎带应答

        🍇如果接收数据的主机立刻返回ACK应答,这时候返回的窗口可能会比较小。假设接收端缓冲区为1M,一次收到了500K的数据;如果立刻应答,返回的窗口就是500K。但实际上可能处理端处理的速度很快,10ms之内就把500K数据从缓冲区消费掉了。

        在这种情况下,接收端处理还远没有达到自己的极限,即使窗口再放大一些,也能处理过来。如果接收端稍微等一会再应答,比如等待200ms再应答,那么这个时候返回的窗口大小就是1M。窗口越大,网络吞吐量就越大,传输效率就越高。在保证网络不拥塞的情况下尽量提高传输效率。这便是延迟应答
        

       🥥 很多情况下,在延迟应答的基础上,客户端服务器在应用层也是“一发一收”的。意味着客户端给服务器说了"How are you",服务器也会给客户端回一个"Fine, thank you"。这个时候ACK就可以搭顺风车,和服务器回应的"Fine, thank you"一起回给客户端。就比如在TCP三次握手中,第二次握手的ACK与SYN同时返回。这便是捎带应答

    

粘包问题 

我们知道TCP是面向字节流的协议。

        🍉粘包问题中的“包”是指的应用层的数据包。在TCP的协议头中,没有如同UDP一样的“报文长度”这样的字段,但是有一个序号这样的字段。站在传输层的角度,TCP是一个一个报文传输过来的,按照序号排好序放在缓冲区中。站在应用层的角度,看到的只是一串连续的字节数据。那么应用程序看到了这么一连串的字节数据,就不知道从哪个部分开始到哪个部分结束是一个完整的应用层数据包。

        解决粘包问题的关键就是明确"两个包之间的边界"。对于定长的包,保证每次都按固定大小读取即可;对于变长的包,可以在包头的位置约定一个包总长度的字段,从而就知道了包的结束位置;还可以在包和包之间使用明确的分隔符,只要保证分隔符不和正文冲突即可。

        🍊对于UDP协议来说,是否也存在“粘包问题”?对于UDP,如果还没有上层交付数据,UDP的报文长度仍然在。同时,UDP是一对一把数据交付给应用层,就有很明确的数据边界。站在应用层的角度,使用UDP的时候,要么收到完整的UDP报文,要么不收,不会出现如上的情况。

异常处理 

        进程崩溃/终止:进程终止会释放文件描述符,仍然可以发送FIN。和正常关闭没有什么区别。

        机器重启:和进程终止的情况相同。

        机器掉电/网线断开:接收端认为连接还在,一旦接收端有写入操作,接收端发现连接已经不在了,就会进行reset。即使没有写入操作,TCP自己内置了一个保活定时器,会定期询问对方是否还在。如果对方不在,也会把连接释放。

        🍋另外,应用层的某些协议,也有一些这样的检测机制。例如HTTP长连接中,也会定期检测对方的状态。例如QQ,在QQ断线之后,也会定期尝试重新连接。

TCP小结

 TCP(上):成熟可靠的传输层协议-CSDN博客

        在本系列博客中,我们深入探讨了TCP的核心特性,包括🍍确认应答、🍋超时重传、🍎连接管理、🍑滑动窗口、🫐流量控制、🍓拥塞控制、🍇延时应答、🍊捎带应答以及🍉面向字节流和🥝异常处理。这些特性共同确保了TCP在网络通信中的可靠性和效率。通过理解这些机制,我们能够更好地把握网络通信的复杂性,并在现实中有效地利用TCP。

        TCP协议的深度和广度远不止于此,希望大家继续探索和学习,我期待在未来的探索中与您同行。如果您有任何疑问或想要进一步讨论的话题,请随时留言。


希望这篇博客能为你理解TCP及网络提供一些帮助

如有不足之处请多多指出

我是高耳机

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

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

相关文章

后端——接口文档(API)

一、概念 后端的接口文档(API文档)——全称为应用程序编程接口(Application Programming Interface)文档,是详细阐述特定软件应用程序或Web服务所开放接口的具体使用指南。这份文档为开发者提供了与这些接口进行交互的…

【Linux:epoll】

目录 epoll与select、poll的区别: epoll操作函数: int epoll_create(int size); epoll_ctl: epoll_wait: epoll与select、poll的区别: select,poll底层是一个线性表的结构,而epoll是一个红黑树结构。epoll、poll不能跨平台…

Java基础——多线程

1. 线程 是一个程序内部的一条执行流程程序中如果只有一条执行流程,那这个程序就是单线程的程序 2. 多线程 指从软硬件上实现的多条执行流程的技术(多条线程由CPU负责调度执行) 2.1. 如何创建多条线程 Java通过java.lang.Thread类的对象…

使用Redis的一些经验总结

目录 一、Redis中的key和value的设计 1.key的命名规范 2.避免出现BigKey 3.value中选择恰当的数据类型 例1:比如存储一个User对象,我们有三种存储方式: ①方式一:json字符串 ②方式二:字段打散 ③方式三&#x…

如何在 Ubuntu 上配置 Kotlin 应用环境 ?

Kotlin 是一种运行在 Java 虚拟机 (JVM) 上的现代编程语言,它同时支持函数式和面向对象编程。它可与 Java 互操作,并以其简洁的语法而闻名。在本指南中,我们将介绍在 Ubuntu 系统上准备好 Kotlin 开发环境的要点,包括 Java、Kotli…

2024强化学习的结构化剪枝模型RL-Pruner原理及实践

[2024] RL-Pruner: Structured Pruning Using Reinforcement Learning for CNN Compression and Acceleration 目录 [2024] RL-Pruner: Structured Pruning Using Reinforcement Learning for CNN Compression and Acceleration一、论文说明二、原理三、实验与分析1、环境配置在…

嵌入式硬件电子电路设计(五)MOS管详解(NMOS、PMOS、三极管跟mos管的区别)

引言:在我们的日常使用中,MOS就是个纯粹的电子开关,虽然MOS管也有放大作用,但是几乎用不到,只用它的开关作用,一般的电机驱动,开关电源,逆变器等大功率设备,全部使用MOS管…

蓝桥杯每日真题 - 第14天

题目:(2022) 题目描述(13届 C&C B组A题) 解题思路: 定义状态: 使用一个二维数组 dp[j][k] 来表示将数字 k 拆分为 j 个不同正整数的方案数。 初始化: 初始状态设定为 dp[0][0]…

利用云计算实现高效的数据备份与恢复策略

💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 利用云计算实现高效的数据备份与恢复策略 利用云计算实现高效的数据备份与恢复策略 利用云计算实现高效的数据备份与恢复策略 引…

thinkphp6配置多应用项目及多域名访问路由app配置

这里写一写TP6下配置多应用。TP6默认是单应用模式(单模块),而我们实际项目中往往是多应用的(多个模块),所以在利用TP6是就需要进行配置,开启多应用模式。 1、安装ThinkPHP6 1.1安装ThinkPHP6.…

JavaScript:浏览器对象模型BOM

BOM介绍 浏览器对象模型(Brower Object Model,BOM)提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是window BOM由一系列相关的对象构成,并且每个对象都提供了很多方法和属性。 BOM与DOM区别 DOM是文档对…

SpringBoot 2.2.10 无法执行Test单元测试

很早之前的项目今天clone现在,想执行一个业务订单的检查,该检查的代码放在test单元测试中,启动也是好好的,当点击对应的方法执行Test的时候就报错 tip:已添加spring-boot-test-starter 所以本身就引入了junit5的库 No…

前后端、网关、协议方面补充

这里写目录标题 前后端接口文档简介前后端视角对于前端对于后端代码注册路由路由处理函数 关于httpGET/POST底层网络关于前端的获取 路由器网关路由器的IP简介公网IP(WAN IP)私网IP(LAN IP)无线网络IP(WIFI IP)查询路由器私网IP路由器公网IP LAN口与WIFI简介基本原理 手动配置电…

英伟达基于Mistral 7B开发新一代Embedding模型——NV-Embed-v2

我们介绍的 NV-Embed-v2 是一种通用嵌入模型,它在大规模文本嵌入基准(MTEB 基准)(截至 2024 年 8 月 30 日)的 56 项文本嵌入任务中以 72.31 的高分排名第一。此外,它还在检索子类别中排名第一(…

【计算机网络】TCP网络特点2

断开连接 四次挥手 原因 TCP 四次挥手是为了满足 TCP 连接的全双工特性:两个方向都可以自由传输 保证数据传输的完整性:两方都完成了数据发送和接收并且都同意断开连接 可靠地终止连接以及避免数据混淆和错误等需求:每个方向都需要单独确认导致四次挥手过程 这些…

Opengl光照测试

代码 #include "Model.h" #include "shader_m.h" #include "imgui.h" #include "imgui_impl_glfw.h" #include "imgui_impl_opengl3.h" //以上是放在同目录的头文件#include <glad/glad.h> #include <GLFW/glfw3.…

【MySQL】SQL语言

【MySQL】SQL语言 文章目录 【MySQL】SQL语言前言一、SQL的通用语法二、SQL的分类三、SQLDDLDMLDQLDCL 总结 前言 本篇文章将讲到SQL语言&#xff0c;包括SQL的通用语法,SQL的分类,以及SQL语言的DDL,DML,DQL,DCL。 一、SQL的通用语法 在学习具体的SQL语句之前&#xff0c;先来…

.netcore + postgis 保存地图围栏数据

一、数据库字段 字段类型选择(Type) 设置对象类型为&#xff1a;geometry 二、前端传递的Json格式转换 前端传递围栏的各个坐标点数据如下&#xff1a; {"AreaRange": [{"lat": 30.123456,"lng": 120.123456},{"lat": 30.123456…

T265相机双目鱼眼+imu联合标定(全记录)

最近工作用到t265&#xff0c;记录一遍标定过程 1.安装驱动 首先安装realsense驱动&#xff0c;因为笔者之前使用过d435i&#xff0c;装的librealsense版本为2.55.1&#xff0c;直接使用t265会出现找不到设备的问题&#xff0c;经查阅发现是因为realsense在2.53.1后就不再支持…

【C语言指南】C语言内存管理 深度解析

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《C语言指南》 期待您的关注 引言 C语言是一种强大而灵活的编程语言&#xff0c;为程序员提供了对内存的直接控制能力。这种对内存…