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

news2024/11/17 7:11:13

欢迎浏览高耳机的博客

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

感谢三连支持!  

 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.coloradmin.cn/o/2242018.html

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

相关文章

24 年第十届数维杯国际数模竞赛赛题浅析

本次万众瞩目的数维杯国际大学生数学建模赛题已正式出炉,无论是赛题难度还是认可度,该比赛都是数模届的独一档,含金量极高,可以用于综测加分、保研、简历添彩等各方面。考虑到大家解题实属不易,为了帮助大家取得好成绩…

菲涅耳全息图

菲涅耳全息图:记录介质在物光波场的菲涅耳衍射区(物体到记录介质表面的距离在菲涅耳衍射区内)。 一、点源全息图的记录和再现 1.1 记录 设物光波和参考光波是从点源O(xo, yo, zo)和点源 R(xr, yr, zr)发出的球面波, 波长为λ1, 全息底片位于z0 的平面上, 与两个点源…

Pygame坦克大战游戏开发实验报告

✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…

微搭低代码入门05循环

目录 1 for 循环2 while 循环3 do...while 循环4 break 语句5 循环展示组件总结 在编程中,循环是一种非常强大的控制结构,它允许我们重复执行一段代码直到满足某个条件为止。在微搭中,我们一般用循环来处理我们数据库返回的结果。 在微搭中&a…

C++:基于红黑树封装map和set

目录 红黑树的修改 红黑树节点 红黑树结构 红黑树的迭代器 红黑树Insert函数 红黑树的默认成员函数 修改后完整的红黑树 set、map的模拟实现 set map 测试封装的set和map 红黑树的修改 想要用红黑树封装map和set,需要对之前实现的key-value红黑树进行修…

【深度学习基础 | 预备知识】数据预处理

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈PyTorch深度学习 ⌋ ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上,结合当代大数据和大算力的发展而发展出来的。深度学习最重…

前端面试笔试(四)

目录 一、数据结构算法等综合篇 1.线性探查法解决哈希冲突 2.请求分页系统中文件区和对换区 3.RADIUS认证协议,运行在哪个网络协议上 二、代码输出篇 1.res[1,2,100].map(parseInt) 如果我们想要输出为[1,2,100],可以: 还可以换map里…

从零开始学习 sg200x 多核开发之 milkv-duo256 编译运行 sophpi

sophpi 是 算能官方针对 sg200x 系列的 SDK 仓库 https://github.com/sophgo/sophpi ,支持 cv180x、cv81x、sg200x 系列的芯片。 SG2002 简介 SG2002 是面向边缘智能监控 IP 摄像机、智能猫眼门锁、可视门铃、居家智能等多项产品领域而推出的高性能、低功耗芯片&a…

【客户服务】互联网时代客户投诉处理金点子

互联网时代客户投诉新特点 客户投诉渠道广投诉的内容涉及到企业的各个方面客户维权意识越来越强负面效应很难管 卓越客户体验成为企业核心竞争力 移动互联网与社会化媒体背景下,客户的全方位感知、情感、卓越体验、高效需求成为驱动技术、应用、终端以及服务持续…

SQL 审核在 CloudQuery 的四大场景应用

数据库作为数据的核心载体,其安全性和稳定性对业务的影响至关重要。而在我们日常业务中,SQL 编写不当是引起数据库故障的一个重要原因,轻则影响数据库性能,重则可能直接导致「雪崩」。因此,SQL 审核作为 SQL 代码投入生…

【前端知识】Javascript前端框架Vue入门

前端框架VUE入门 概述基础语法介绍组件特性组件注册Props 属性声明事件组件 v-model(双向绑定)插槽Slots内容与出口 组件生命周期完整示例1. 创建 Vue 项目(如果还没有)2. 定义和使用组件3. 在主应用中使用组件4. 运行应用完整项目结构 参考文献 概述 V…

Jmeter基础篇(24)Jmeter目录下有哪些文件夹是可以删除,且不影响使用的呢?

一、前言 Jmeter使我们日常做性能测试最常用的工具之一啦!但是我们在和其他同学协同工作的时候,偶尔也会遇到一些问题,例如我想要给别人发送一个Jmeter工具包,但这个文件包往往会很大,比较浪费流量和空间,…

Python_爬虫3_Requests库网络爬虫实战(5个实例)

目录 实例1:京东商品页面的爬取 实例2:亚马逊商品页面的爬取 实例3:百度360搜索关键词提交 实例4:网络图片的爬取和存储 实例5:IP地址归地的自动查询 实例1:京东商品页面的爬取 import requests url …

StructuredStreaming (一)

一、sparkStreaming的不足 1.基于微批,延迟高不能做到真正的实时 2.DStream基于RDD,不直接支持SQL 3.流批处理的API应用层不统一,(流用的DStream-底层是RDD,批用的DF/DS/RDD) 4.不支持EventTime事件时间(一般流处理都会有两个时间:事件发生的事件&am…

计算机网络HTTP——针对实习面试

目录 计算机网络HTTP什么是HTTP?HTTP和HTTPS有什么区别?分别说明HTTP/1.0、HTTP/2.0、HTTP/3.0请说明访问网页的全过程请说明HTTP常见的状态码Cookie和Session有什么区别?HTTP请求方式有哪些?请解释GET和POST的区别?HT…

转轮数组(C语言实现)

题目介绍 方法一我们可以先把数字1 2 3 4逆转一下&#xff0c;第二步我们可以逆转一下5 6 7&#xff0c; 最后整体逆置一下就会变成上面的数字。 void reverse(int* nums, int begin, int end) {while (begin < end){int tmp nums[begin];nums[begin] nums[end];nums[en…

Ubuntu 的 ROS 操作系统 turtlebot3 gazebo仿真

引言 TurtleBot3 Gazebo仿真环境是一个非常强大的工具&#xff0c;能够帮助开发者在虚拟环境中测试和验证机器人算法。 Gazebo是一个开源的3D机器人仿真平台&#xff0c;它能支持物理引擎&#xff0c;允许机器人在虚拟环境中模拟和测试。结合ROS&#xff0c;它能提供一个完整的…

uniapp vuex的使用

实现组件全局&#xff08;数据&#xff09;管理的一种机制&#xff0c;可以方便的实现组件之间共享数据&#xff0c;不同于上述三种传递值的方式。 可以把vuex当成一个store仓库&#xff0c;可以集中管理共享的数据&#xff0c;并且存储在vuex中的数据都是响应式的&#xff0c…

uniapp适配暗黑模式配置plus.nativeUI.setUIStyle适配DarkMode配置

uniapp适配暗黑模式配置 目录 uniapp适配暗黑模式配置setUIStyleDarkMode 适配app-plus manifest.json配置theme.json配置pages.json配置页面切换代码实现同步手机暗黑配置额外适配 参考官方文档&#xff1a;https://uniapp.dcloud.net.cn/tutorial/darkmode.html 主要用到api…

element ui table进行相同数据合并单元格

示例如图 //要合并的项&#xff08;自定义&#xff09; const columnArr ["dq","sj","xj","zj","zjj","zjfzr","nhxm","nhsjh","nhsfzh","","",""…