TCP三次握手原理,以及为什么不能改成两次握手

2023-10-27

网上 关于 TCP三次握手 的文章有很多,但很多一些部分讲的含糊其辞,所以才重新造了这个轮子,一方面对那些含糊其辞的部分做了解释,另一方面也方便了以后的学习。

这里写图片描述

1、上图的名词解释

  • SYN:同步序号。它表示建立连接。TCP规定SYN=1时不能携带数据,但要消耗一个序号, 因此随机选取一个序列号为seq=x 数据包(该数据包里就是一个标记seq,并没有任何有效的数据)。
  • ACK :确认序号。它表示响应(都能响应了 那肯定上一步就连接成功了啊,所以说ACK=1代表确认连接成功啦)。

因此SYN和ACK同时为1,表示建立连接之后的响应;而只是单个的SYN=1,表示的只是建立连接

  • seq: (sequence number) 序列号。它是发送端数据包的初始序号。seq=x 表示发送端数据包的初始序号为x(seq = 0 就代表这是第0号帧)。
  • ack:(acknowledge number) 确认号。它是对这次收到数据包的确认,以及对下次收到数据包的期待。ack=x+1表示 我方 到 x为止的所有数据都已正确收到,且我方告知 对方:我期待你下次给我发送包的初始序号(seq)是x+1

为了方便记忆,可以这么理解:SYN/ACK是TCP协议层面的标记,而seq/ack是数据层面的标记。


2、TCP三次握手 过程

( 1 )首先Client向Server发送连接:SYN = 1, seq=x;

  • 因为建立连接,所以SYN=1又因为TCP规定SYN=1时不能携带数据,但要消耗一个序号, 所以Client随机选取一个初始序号seq=x。(因为并没有响应动作,所以这里没ACK什么事,我们就认为ACK=0吧)
  • 发送后Client进入syn_sent状态,表示客户端等待服务器的回复。

(2)Server收到请求后 再向Client发送确认:SYN=1, ACK=1, seq=y, ack=x+1;

  • 因为Server建立连接后做出了响应,所以SYN=1, ACK=1因为TCP规定SYN=1时不能携带数据,但要消耗一个序号, 所以Server随机选取一个初始序号seq=y又因为Server到 x为止的所有数据都已正确收到了,且Server告诉Client:我期待你下次给我发送包的初始序号(seq)是x+1,所以ack=x+1
  • 发送后服务器进入syn_rcvd,表示服务器已经收到Client的连接请求,等待Client的确认。

(3)Client收到确认后还需再次发送确认,同时携带要发送给Server的数据:ACK=1, seq=x+1, ack= y+1;连接建立

  • 因为有 响应 动作,所以ACK=1(因为要携带发送的数据,所以这儿没SYN什么事)。因为(2)中Server 已经告诉了这次它想收到包的初始序列号是x+1,所以初始序号为seq=x+1又因为Client到 y为止的所有数据都已正确收到了,准备接收序列号为y+1的包,所以ack=y+1
  • Server收到后,这个TCP连接就进入Established状态,就可以发起http请求了。

形象些:

  • 第一次握手,由浏览器发起,告诉服务器我要发送请求了
  • 第二次握手,由服务器发起,告诉浏览器我准备接受了,你赶紧发送吧
  • 第三次握手,由浏览器发送,告诉服务器,我马上就发了,准备接受吧

为什么需要三次握手,两次不行吗?

其实这是由TCP的自身特点可靠传输决定的。客户端和服务端要进行可靠传输,那么就需要确认双方接收和发送能力,不然容易出现丢包的现象

  • 第一次握手: 可以确认客服端的发送能力
  • 第二次握手: 可以确认服务端的接收能力 和 发送能力
  • 第三次握手: 可以确认客户端的接收能力。

3、为什么不能改成两次握手?

试想如果是用两次握手,则会出现下面这种情况:

如客户端发出连接请求,但因连接请求报文丢失而未收到确认,于是客户端再重传一次连接请求。后来收到了确认,建立了连接。数据传输完毕后,就释放了连接,客户端共发出了两个连接请求报文段,其中第一个丢失,第二个到达了服务端,但是第一个丢失的报文段只是在某些网络结点长时间滞留了,延误到连接释放以后的某个时间才到达服务端,此时服务端误认为客户端又发出一次新的连接请求,于是就向客户端发出确认报文段,同意建立连接,不采用三次握手,只要服务端发出确认,就建立新的连接了,此时客户端忽略服务端发来的确认,也不发送数据,则服务端一致等待客户端发送数据,浪费资源。


4、三次握手过程中可以携带数据吗?

其实第三次握手的时候,是可以携带数据的。但是,第一次、第二次握手不可以携带数据

为什么这样呢?大家可以想一个问题,假如第一次握手可以携带数据的话,如果有人要恶意攻击服务器,那他每次都在第一次握手中的 SYN 报文中放入大量的数据。因为攻击者根本就不理服务器的接收、发送能力是否正常,然后疯狂着重复发 SYN 报文的话,这会让服务器花费很多时间、内存空间来接收这些报文。

也就是说,第一次握手不可以放数据,其中一个简单的原因就是会让服务器更加容易受到攻击了。而对于第三次的话,此时客户端已经处于 ESTAB-LISHED 状态。对于客户端来说,他已经建立起连接了,并且也已经知道服务器的接收、发送能力是正常的了,所以能携带数据也没啥毛病。



文章Git地址:TCP三次握手


以上便是全部,如有解释不对的地方望及时指出~
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

TCP三次握手原理,以及为什么不能改成两次握手 的相关文章

  • 【满分】【华为OD机试真题2023 JS】预定酒店

    华为OD机试真题 2023年度机试题库全覆盖 刷题指南点这里 预定酒店 知识点排序 时间限制 1s 空间限制 256MB 限定语言 不限 题目描述 放暑假了 小明决定到某旅游景点游玩 他在网上搜索到了各种价位的酒店 长度为n的数组A 他的心
  • 区块链的证明机制(Proof Of Work POW)学习心得(参考luotuo视频学习)

    在区块链学习中 参考luotuo的哔哩哔哩视频 区块链增加模块时是要经过计算的 只有计算到 开头n位为0 符合这个链条的规则时 才会将这个新的区块加入到区块链当中 这个计算hash的方法应该被加以判断 也就是增加一个方法来计算符合区块链难度

随机推荐

  • CSDN博客如何设置的更美观和贴好看的代码

    之前学习写博客时想要写出整洁的博文 贴好看的代码 所以百度了好多位小可爱的方法 奈何我太笨可能对我帮助不是很大 依然是一头雾水 我是想要找到那种黑色背景代码高亮的方式 后来自己慢慢琢磨出来了 所以把我的方法分享一下 1 在博客设置首页有博客
  • hive on spark 3.1.2集成spark3.0.0

    需要修改spark env sh 加上 export SPARK DIST CLASSPATH hadoop classpath 否则报错 2 14 51 56 117 INFO yarn ApplicationMaster Final a
  • 盘点2022年有影响力的五种顶级NFT头像

    盘点2022年15 个顶级NFT头像 NFT头像在去年风靡一时 作为一种简单的即插即用方法 任何人都可以将特征 身体 头部 背景等 加载到应用程序中以快速混合搭配 NFT 创建 因此它已成为制作头像比以往任何时候都容易 考虑到今年 NFT热
  • 美团外卖与饿了么竞品分析

    截至2020年3月 我国网上外卖用户规模达3 98亿 占网民整体的44 手机网上外卖用户规模达3 97亿 占手机网民整体的44 2 图片来源 前瞻网 2017 2019年 我国互联网餐饮外卖交易规模逐渐扩大 2019全年超7274亿元 互联
  • Web自动化测试面试

    一 Web 自动化测试 1 Selenium 中 hidden 或者是 display none 的元素是否可以定位到 不能 可以写 JavaScript 将标签中的 hidden 先改为 0 再定位元素 2 Selenium 中如何保证操
  • 安卓APP_ 布局(4) —— TableLayout表格布局

    摘自 安卓APP 布局 4 TableLayout表格布局 作者 丶PURSUING 发布时间 2021 04 11 22 55 50 网址 https blog csdn net weixin 44742824 article detai
  • 集合竞价

    include
  • Linux 创建目录和文件

    mkdir 创建目录 在linux中 mkdir是创建目录的意思 是 make directories 的缩写 该命令用于创建新的目录 语法为 mkdir mp 目录名 设置参数 m 用于手动配置创建目录的权限 设置参数 p 用于递归创建所
  • 苹果Vision Pro手势+眼球融合交互的奥秘

    毫无疑问 Vision Pro在眼球追踪 手势的融合交互体验上 给AR VR头戴设备带来了新突破 在用户体验上的提升非常明显 那么 为什么Vision Pro上这一功能会被如此值得关注呢 为了弄清楚 我们先来看看主流VR设备是如何做的 主流
  • Fatal Python error: init_fs_encoding: failed to get the Python codec of the filesystem encoding

    Fatal Python error init fs encoding failed to get the Python codec of the filesystem encoding Python runtime state core
  • 循迹小车代码应该怎么写?

    循迹小车的代码通常包括以下几个部分 引入库和定义变量 首先需要引入所需的库 并定义各个引脚对应的变量 以便后面的代码可以直接使用 初始化设置 对循迹小车进行初始化设置 如设置电机转向 速度等参数 读取循迹传感器数值 通过循迹传感器读取黑线和
  • 用jQuery编写简单的动画效果

    jQuery是一种基于JavaScript库的快速 小型而且特别丰富的JavaScript库 它极大地简化了HTML文档遍历和操作 事件处理 动画效果和AJAX交互等功能 jQuery中的各种动画函数可以让我们轻松地为网页添加各种各样的动画
  • Leetcode 刷题笔记:字符串篇

    结束了忙碌的期末 终于有了一个月的冬假 赶紧利用这段时间集中精力把Leetcode刷起来 1 Leetcode344 反转字符串 题解 难度 这道题目算是比较基础也是很简单的一道题目了 用双指针的方法可以轻松解决 时间复杂度O N 空间复杂
  • ES集成IK分词器

    一 下载IK分词器 注意版本与ES版本保持一致 下载地址 https github com medcl elasticsearch analysis ik releases 二 下载之后解压到ES的plugin目录 注意新建一个ik目录 解
  • 运行jar包时指定jdk的版本

    set JAVA HOME C Program Files Java jdk1 8 0 153 set CLASSPATH JAVA HOME lib dt jar JAVA HOMe lib tools jar set Path JAVA
  • CryptoPP版本验证

    在使用第三方程序库时 可能会遇到程序库的版本不匹配的问题 下面介绍在使用CryptoPP时 如何验证其版本 代码如下 include
  • 字符串转换成整数

    题目描述 输入一个由数字组成的字符串 把它转换成整数并输出 例如 输入字符串 123 输出整数123 给定函数原型int StrToInt const char str 实现字符串转换成整数的功能 不能使用库函数atoi 分析与解法 本题考
  • 问题:WPS文字提示应用程序已存在该快捷键,请另设快捷键

    1 问题描述 WPS文字 对某一字体样式自定义快捷键 结果提示已存在 如何如何查看已设定快捷键 只针对软件内部冲突 不考虑外部软件影响 我遇到过以下两种情况 1 与自己之前定义的冲突 2 与模板文件冲突 这个不太确定 对于模板冲突 自定义样
  • sqlite的下载安装和配置使用(非常详细)

    sqlite下载链接 Sqlite下载官网 1 这个压缩包中有头文件sqlite3 h以及源码 主要是用到头文件 2 看电脑配置的操作系统或者看所需项目是64位还是32位下载对应的压缩包 3 解压得到这两个文件 sqlite3 def文件用
  • TCP三次握手原理,以及为什么不能改成两次握手

    网上 关于 TCP三次握手 的文章有很多 但很多一些部分讲的含糊其辞 所以才重新造了这个轮子 一方面对那些含糊其辞的部分做了解释 另一方面也方便了以后的学习 1 上图的名词解释 SYN 同步序号 它表示建立连接 TCP规定SYN 1时不能携