TCP 三次握手意义及为什么是三次握手

news2024/11/24 23:18:31

  ✨✨✨励志成为超级技术宅  ✨✨✨

        TCP的三次握手在笔试和面试中经常考察,非常重要,那么大家有没有思考过为什么是三次握手,俩次握手行不行呢?四次握手行不行呢?如果大家有疑问或者不是很理解,那么这篇博客有图有讲解,一定能帮助大家思考,希望大家能看看了( つ•̀ω•́)つ。


一.知识铺垫

        首先tcp协议的格式如下:

        这里我们先了解32位序号和32位确认序号。假设我们是客户端,32位序号就像学生id唯一标识标识一段传输的TCP报文, 32位确认序号就是收到服务端TCP报文时,将服务端的32位序号+1作为我们客户端的32确认序号发送给服务器。也就是我们端的32位确认序号等于对端的32位序号+1。

        为什么会有确认序号产生呢?这是为了确保消息能被收到。举个例子,在生活中,辅导员为了确保重要的消息被同学知道, 会在班群通知,XXX重要消息,收到请回复只要有同学对这条消息回复,就代表消息收到了这时老师和同学就类似于服务器和客户端,服务器和客户端确保的通信被收到的机制其实也就是收到请回复。我们将收到消息的32位序号+1作为32位确认序号放入消息中,就是我们对这条32位序号消息的回复。

        通过32位序号和32位确认序号结合,我们就能在发送消息的同时进行回复。 32位序号表示发送的消息序号,32确认序号就表示对哪条消息的收到确认回复。当发送需求和回复确认需求同时都存在时,俩个序号就会添加上对应的值,这就是捎带应答(可以理解为因为要发送消息就顺便应答一下的意思TCP三次握手的第二次握手就是捎带应答,因为在同一时间内具有发送需求(建立连接)和确认需求(对第一次握手应答)。

二.回顾三次握手流程

        SYN和ACK是TCP六位标志位中的俩位,当标志位置1表示有效。我们先来讲解含义。

TCP的六位标志位
上图的六位标志位

        SYN是“Synchronize”(同步)的缩写,用来请求建立连接。ACK是“Acknowledgment”(确认)的缩写,ACK报文的主要作用是确认接收方已经成功接收了发送方发送的数据段 。

       在三次握手中,当客户端以及服务端发送含有SYN标志位请求时就表示要建立连接,发送ACK报文就表示对另一方连接请求的确认。另外,双方发送的含有SYN的消息的32位序号是随机的,对于每一次的ack请求都是不同的。

        那么我们来概括一下三次请求的简要流程:

1.第一次握手(SYN):

  • 客户端(Client):发送一个带有SYN(同步序列编号)标志位的TCP报文段给服务器,请求建立连接。此时,客户端进入SYN_SEND状态。
  • 报文内容:SYN=1,初始序列号seq=x(客户端随机的初始序列号)。

2.第二次握手 (SYN+ACK)

  • 服务器(Server):收到客户端的SYN报文段后,确认SYN报文段有效,并回复一个带有SYN和ACK(确认)标志位的TCP报文段给客户端,表示同意建立连接。此时,服务器进入SYN_RCVD状态。
  • 报文内容:SYN=1,ACK=1,确认号ack=x+1(表示收到了客户端的序列号x),初始序列号seq=y(服务器随机的初始序列号)。

3.第三次握手(ACK)

  • 客户端(Client):收到服务器的SYN+ACK报文段后,确认该报文段有效,并向服务器发送一个带有ACK标志位的TCP报文段,表示已经收到了服务器的SYN报文段。此时,客户端和服务器都进入ESTABLISHED(已建立连接)状态,可以开始传输数据。
  • 报文内容:ACK=1,确认号ack=y+1(表示收到了服务器的序列号y)。

         了解上面的知识我们也就能探索为什么是三次握手了。 

三.为什么不是俩次握手

1.确保双方的通信能力

        首先我们要怎么才能确定一端到对端的通信能力呢?答案是请求被回复。请求被回复就说明对方成功接收到了消息,没有回复可能是对方没有收到或者对方发送消息的通路有问题

        当客户端发送建立连接的请求SYN,之后如果客户端收到了服务器回复了SYN和ACK的消息。此时作为客户端我们就能确定客户端到服务器的连接是畅通的,因为我们收到了回复,而回复就代表我们的消息被对端成功接收,客户端到服务器通信是畅通的。

        而作为服务端,当我们对客户端的连接请求,回复SYN和ACK消息,如果要确保服务器到客户端通信畅通,也必须需要收到回复,这就是第三次握手的意义,客户端发送ACK消息对服务端的的连接请求回复确认消息ACK,当此时服务器收到消息了,就代表服务器到客户端通信是正常的,即三次握手确认后了双方的通信能力

        始终要记住只有我们的消息被回复才能保证我们的消息被收到。

        总体来说只要俩边的SYN请求都能接收到ACK回复,就表明俩边的SYN请求都已经被对端收到,双方通信就是正常的。

        

        那么为什么不能是俩次握手,俩次握手双方不是也已经进行互相通信了吗?此时为什么还不能确保双方的通信能力。

        答案是此时虽然进行了互相通信,但是只有客户端的连接请求被确认,而服务器的请求还没有进行回应,俩次握手后,客户端如果收到回应,是能确保自己到服务端的通路和服务端到自己的通路是正常的,但是此时作为服务器,我们并不能确认我们的SYN和ACK消息被收到,只有收到回应才能确保我们的消息被正确送到对方,才能确保服务器到客户端的通路是畅通的。

        因此完成俩次握手客户端能确认自己到服务器的通信正常,服务器无法确保自己到客户端通信正常。

        我们在从另外一个角度看,对于俩次握手,如果第二次握手失败,即服务器发送的SYN报文因为网络等原因没有送达,服务器就会认为连接建立,进行监听并发送数据,而客户端因为服务器报文丢失,根本不会建立连接发送消息,此时服务器就会监听和对不存在的连接发消息,浪费资源。

        而对于三次握手,第二次握手失败,服务器也不会建立连接,不会浪费资源,甚至因为网络变化第三次握手失败,此时客户端已经建立连接,但是服务器依旧不会建立连接,这时服务器的三次任何一次握手失败的代价都不用服务器承担,第三次失败也是客户端承担代价。能减少服务器负担。

2.防止历史报文的干扰

       历史报文的干扰的情况是指因为网络延迟等问题服务器第一次发送的SYN报文被阻塞在网络中,此时服务器会再次发送第二次SYN报文,第二次报文成功发送,如果此时第一次的SYN报文之后又发送到服务器又会怎样?

        我们就来讲讲三次握手是怎么防止历史报文的干扰,首先每次SYN报文的32序列号是随机的,我们假设第一次阻塞的SYN报文32位初始序列号是100(随便写几位),第二次成功送达的序列号是200,此时服务器回应ACK和SYN报文,此时32位确认序号是201,此时如果阻塞报文在第二次成功送达的报文之后到来,服务器不能区分新旧(因为初始序列号是随机的,且此时连接为建立),同样会进行回应,确认序列号101。这时客户端会收到俩份ACK和SYN的报文,一份确认序列化101,一份201,服务器是能记住自己最新的初始序列号200的,因此201符和预期,客户端会对201的报文进行一份回应,101不符合客户端直接丢弃。此时客户端和服务器各自只建立了一份连接,服务器虽然多建立一个syn_rcvd状态但是并不会太浪费资源。

        我们再来看看俩次连接为什么不能防止历史连接干扰

        首先假设只有俩次握手,在服务器对客户端的SYN报文进行回复后,那么服务器就会认为连接建立了(因为俩次握手的就要建立连接)。因此服务器收到俩次SYN请求会分别添加2个连接, 此时客户端由于上面同样的原因,会丢弃一份SYN和ACK报文,只会添加一个连接。

        因此俩次握手不能防止历史连接干扰而三次握手可以。此外还有一种情况如果三次握手成功后,历史连接再次到来的情况,我询问了老师,因为五元组相同(源ip,目的ip,源端口,目的端口,协议类型),此时服务器会检查建立与对于客户端建立的连接,发现连接正常,对于历史连接就会直接丢弃,不过此时并不能很好体现为什么要三次握手了而不是俩次握手了。

四.为什么不是四次握手

        通过上面的讲解我们能明白三次握手已经能很好完成建立连接的功能,对于为什么不是四次握手我们就能很好理解。

        主要是为了避免资源浪费和协议设计的简洁性

       在TCP连接建立的过程中,如果采用四次握手,将会增加通信的开销和延迟,降低连接建立的效率。 TCP协议的设计注重简洁性和高效性。三次握手的过程既能够确保连接的可靠性,又能够避免不必要的复杂性和开销。如果增加到四次握手,将会使协议变得更加复杂和冗余。

        综上所述,TCP采用三次握手而不是四次握手,是在保证连接可靠性和通信效率之间的一种平衡选择。这种机制不仅简单可靠,而且能够有效地避免连接建立过程中的问题。

五.三次握手的意义

        我们最后再来完全总结一次三次握手的意义(毕竟经常考):

1.确保双方的通信能力

2.防止历史报文的干扰

3.交换彼此的窗口大小(即接收缓冲区剩余空间)和初始化序列号(也可说是交换滑动窗口的头指针位置)

        对于第三点如果不了解或者想要更好理解TCP协议的全部内容的话,可以看本人关于TCP协议的另外一篇博客 TCP 协议详解_tcp协议-CSDN博客。里面详细讲解了TCP的各种知识点,相信可以帮助你更好理解TCP全貌。

        感觉有帮助的请点个赞,这真的很重要。٩(๑òωó๑)۶

                         

         

        

        

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

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

相关文章

vmware在全屏模式下快速切换回win桌面的方法

window上开发没有ubuntu下的方便,经常在window主机和ubuntu虚拟机直接切换太麻烦,每次得ctrlalt从虚拟机释放鼠标才可以切换,经过折腾发现以下几种方法可行 方法1 虚拟机监听切换按键并通知主机进行切换桌面 虚拟主机放在单独的一个桌面上并…

[Docker#8] 容器配置 | Mysql | Redis | C++ | 资源控制 | 命令对比

目录 一:Mysql 容器化安装 二:Redis 容器化安装 Redis 简介 Redis 容器创建 三:C容器制作 四:容器资源更新 常见问题 一:Mysql 容器化安装 进入 mysql 的镜像网站,查找 mysql 的镜像 mysql docker…

泷羽sec学习打卡-Linux基础

声明 学习视频来自B站UP主 泷羽sec,如涉及侵权马上删除文章 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负 关于Linux的那些事儿-Base 一、Linux-Base什么时openssl?有哪些加密参数?常用lin…

SpringBoot后端解决跨域问题

1.全局方式 新建一个conifg配置类,内容如下: Configuration public class CorsConfig implements WebMvcConfigurer {Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**")//是否发送Cookie.allowCrede…

odoo17 owl 前端 顶部导航栏右侧添加自定义按钮

odoo17 前端 顶部导航栏右侧添加自定义按钮 先看图 很多时候都想要在这添加个自定义按钮或图标, 无穷下手添加 这里将展示如何在顶部header添加自定义 添加自定义模块 demo 目录结构如下 └─demo│ __init__.py│ __manifest__.py│├─static│ └─src│ ├─s…

Power bi中的lookupvalue函数

lookupvalue函数是一个非常实用的函数,它可用于在两个表之间查找相应的值。kagkupMalue函数可以将一个表中的列值作为参数传递给另一个表中的列,并返回在第二个表中与该值匹配的另一个列的值。在实践中,lookupvalue函数通常用于两个表之间的关…

golang分布式缓存项目 Day5 分布式节点

该项目原作者:https://geektutu.com/post/geecache-day1.html。本文旨在记录本人做该项目时的一些疑惑解答以及部分的测试样例以便于本人复习 1 流程回顾注: 我们在GeeCache 第二天 中描述了 geecache 的流程。在这之前已经实现了流程 ⑴ 和 ⑶&#xf…

[产品管理-76]:延续是创新与颠覆式创新的比较

目录 一、概述 1、定义与特征 2、市场影响与竞争策略 3、实施难度与风险 4、案例分析 二、示例 1. 延续性创新示例 2. 创新示例 3. 颠覆式创新示例 一、概述 延续性创新与颠覆式创新是技术创新领域的两种重要策略,它们在多个方面存在显著差异。 以下是对…

【 AI写作鹅-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 1. 暴力破解密码,造成用户信息泄露 2. 短信盗刷的安全问题,影响业务及导致用户投诉 3. 带来经济损失,尤其是后付费客户,风险巨大,造…

AI:重塑电商行业的创新引擎,开启电商数字化转型新征程

🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,…

语义分割数据增强,图像和标签同步对应详细增强教程(附代码)

💪 专业从事且热爱图像处理,图像处理专栏更新如下👇: 📝《图像去噪》 📝《超分辨率重建》 📝《语义分割》 📝《风格迁移》 📝《目标检测》 📝《图像增强》 &a…

pgsql和mysql的自增主键差异

1. 当有历史数据存在时, mysql的自增主键是默认从最大值自增。 pgsql的自增主键取初始值开始逐个尝试,所以存在可能与历史数据的主键重复的情况。 pgsql解决上述问题的方式:重设自增值。 SELECT SETVAL(t_db_filed_id_seq, (SELECT MAX(&q…

Spring Cloud Contract快速入门Demo

1.什么是Spring Cloud Contract ? Spring Cloud Contract 是 Spring 提供的一套工具,用于帮助开发者通过契约(Contract)驱动的方式进行微服务的测试和集成。它主要解决微服务之间通信时,如何确保服务提供者和消费者之…

OceanBase JDBC (Java数据库连接)的概念、分类与兼容性

本章将介绍 OceanBase JDBC的 概念与分类,已帮助使用 JDBC 的用户及技术人员更好的 了解JDBC,以及 OceanBase JDBC在与 MySQL 及 Oracle 兼容性方面的相关能力。 一、JDBC 基础 1.1 JDBC 的概念 JDBC 一般指 Java 数据库连接。Java 数据库连接&#xf…

自定义springCloudLoadbalancer简述

概述 目前后端用的基本都是springCloud体系; 平时在dev环境开发时,会把自己的本地服务也注册上去,但是这样的话,在客户端调用时请求可能会打到自己本地,对客户端测试不太友好. 思路大致就是前端在请求头传入指定ip&a…

Go/Golang语言各种数据类型内存字节占用大小和最小值最大值

具体请前往:Go/golang语言基本数据类型字节大小和取值范围(最小值~最大值)

力扣104 : 二叉树最大深度

补:二叉树的最大深度 描述: 给定一个二叉树 root ,返回其最大深度。二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 何解? 树一般常用递归:递到叶子节点开始倒着处理

Android GPU纹理数据拷贝

在 Android 开发中读取纹理数据有以下几种方法: glReadPixelsImageReaderPBO(Pixel BufferObject) HardwareBuffer 1. glReadPixels glReadPixels 是 OpenGL ES 的 API,通常用于从帧缓冲区中读取像素数据,OpenGL ES…

畅捷通T+ RecoverPassword.aspx

用友 畅捷通T RecoverPassword.aspx 存在未授权管理员密码修改漏洞,攻击者可以通过漏洞修改管理员账号密码登录后台 #漏洞影响版本 12.0,12.1.12.2.12.3 13.0 15.0 16.0 18.0 补丁号291都影响 19.0 补丁号167之前也有影响 对于老版本畅捷通已经…

最全最简单理解迭代器

1. 迭代器的基础概念(iterator) 1.1 本质 迭代器能够用来遍历容器的对象,与能够遍历数组的指针类似,是广义指针。 1.2 作用: 能够让迭代器与算法不干扰的相互发展,最后又能无间隙的粘合起来。重载了*,++,==,!=,=运算符。用以操作复杂的数据结构。容器提供迭代…