【网络面试篇】TCP连接建立(笔记)

news2024/11/8 0:43:24

目录

一、三次握手

1. 过程描述

2. 为什么是三次握手?不是两次、四次?

(1)三次握手才可以阻止重复历史连接的初始化

(2)三次握手才可以同步双方的初始序列号

(3)三次握手才可以避免资源浪费

3. 如何唯一确定一个 TCP 连接?

4. TCP 头

(1)序列号

(2)确认应答号

(3)控制位

二、相关问题

1. 第一次握手丢失了,会发生什么?

2. 第二次握手丢失了,会发生什么?

3. 第三次握手丢失了,会发生什么?


一、三次握手

1. 过程描述

  • 一开始,客户端和服务端都处于 CLOSE 状态。先是 服务端主动 监听某个端口,处于 LISTEN 状态。

  • 客户端 会随机 初始化序号(client_isn),将此序号 置于 TCP 首部的「序号」字段中,同时把 SYN 标志位置为 1,表示 SYN 报文。接着把第一个 SYN 报文 发送给 服务端,表示向 服务端 发起连接,该报文 不包含应用层 数据,之后客户端处于 SYN-SENT 状态。

  • 服务端 收到 客户端的 SYN 报文 后,首先 服务端 也 随机初始化 自己的序号(server_isn),将此 序号 填入 TCP 首部的「序号」字段中,其次 把 TCP 首部的「确认应答号」字段 填入 client_isn+1,接着把 SYN 和 ACK 标志 位置为 1。最后 把该报文 发给客户端,该报文 也不包含 应用层数据,之后 服务端 处于 SYN-RCVD 状态。

  • 客户端 收到服务端 报文 后,还要 向服务端回 应最后一个 应答报文,首先该 应答 报文 TCP 首部 ACK 标志 位置 1,其次「确认应答号」字段 填入 server_isn +1,最后 把报文 发送给 服务端,这次 报文 可以携带客户 到服务端的 数据,之后 客户端 处于 ESTABLISHED 状态。
  • 服务端 收到 客户端的应答 报文后,也进入 ESTABLISHED 状态。

2. 为什么是三次握手?不是两次、四次?

(1)三次握手才可以阻止重复历史连接的初始化(主要原因)

        现在 考虑一个 场景,客户端先 发送了 SYN (seq=90)报文,然后 客户端 宕机了,而且 这个 SYN 报文 还被网络阻塞 了,服务端 并没有 收到,接着 客户端重启 后,又重新 向 服务端 建立连接,发送了 SYN (seq=100)报文(这里不是重传 SYN,重传的 SYN 的序列号是一样的)。


        客户端 连续 发送多次 SYN(都是同一个四元组)建立 连接的 报文,在网络拥堵 情况下:

  • 一个「SYN 报文」比「最新的 SYN」报文早到达了 服务端,那么 此时服务端 就会 回一个 SYN+ACK 报文给 客户端,此报文中的 确认号是 91(90+1)。
  • 客户端 收到后,发现 自己 期望收到的 确认号 应该是 100+1,而不是 90+1,于是就会回 RST 报文。
  • 服务端 收到 RST 报文后,就会 释放连接。
  • 后续 最新的 SYN 抵达了 服务端后,客户端 与 服务端 就可以正常的 完成三次握手了。

        在两次握手的情况下,服务端在收到 SYN 报文后,就进入 ESTABLISHED 状态,意味着这时 可以给 对方发送数据,但是 客户端 此时还 没有进入 ESTABLISHED 状态,假设 这次是 历史连接,客户端 判断到此次 连接为 历史连接,那么就会 回 RST 报文来 断开连接,而 服务端 在第一次握手 的时候 就进入ESTABLISHED 状态,所以 它可以 发送数据的,但是 它并不知道 这个是历史连接,它只有 在收到 RST 报文后,才会 断开连接。

        可以看到,如果 采用 两次握手建立 TCP 连接的 场景下,服务端 在向客户端 发送数据 前,并 没有阻止掉 历史连接,导致 服务端 建立了一个 历史连接,又白白 发送了 数据,妥妥地 浪费了 服务端的 资源。

        因此,要 解决这种 现象,最好 就是在 服务端 发送数据前,也就是 建立 连接之前,要阻止掉 历史连接,这样 就 不会造成 资源浪费,而 要 实现这个功能,就需要 三次握手。

        所以,TCP 使用三次握手 建立连接的 最主要 原因是防止「历史连接」初始化了连接。

(2)三次握手才可以同步双方的初始序列号

        TCP 协议的 通信双方,都 必须 维护一个「序列号」,序列号 是可靠传输的 一个 关键因素,它的 作用:

  • 接收方可以去除重复的数据。
  • 接收方可以根据数据包的序列号按序接收。
  • 可以标识发送出去的数据包中,哪些是已经被对方收到的(通过 ACK 报文中的序列号知道)。

        可见,序列号在 TCP 连接中 占据着 非常 重要的 作用,所以 当客户端 发送携带「初始序列号」的 SYN 报文的 时候,需要 服务端 回一个 ACK 应答报文,表示 客户端的 SYN 报文 已被 服务端 成功接收,那当 服务端 发送「初始序列号」给 客户端的 时候,依然 也要得到 客户端 的 应答回应,这样 一来一回,才能 确保双方的 初始序列号 能被 可靠的 同步。

        四次握手 其实也 能够 可靠的 同步双方的 初始化序号,但 由于 第二步 和 第三步 可以 优化成一步,所以 就成了「三次握手」。

        而 两次握手只 保证了一方的 初始序列号 能被对方 成功接收,没办法保证 双方的 初始序列号都能 被 确认接收。

(3)三次握手才可以避免资源浪费

        如果只有「两次握手」,当 客户端 发生的 SYN 报文在 网络中 阻塞,客户端 没有 接收到 ACK 报文,就会 重新发送 SYN,由于 没有第三次握手,服务端 不清楚 客户端 是否收到了 自己回复的 ACK 报文,所以 服务端 每收到一个 SYN 就 只能先 主动建立 一个连接,这会 造成什么 情况呢?

        如果 客户端 发送的 SYN 报文在 网络中 阻塞了,重复 发送 多次 SYN 报文,那么 服务端在 收到请求后 就会 建立 多个冗余 的 无效链接,造成 不必要的 资源浪费。

        即 两次握手会 造成消息 滞留情况下,服务端 重复接受 无用的 连接请求 SYN 报文,而 造成重复 分配资源。

3. 如何唯一确定一个 TCP 连接?

        TCP 四元组 可以 唯一的 确定一个 连接,四元组 包括如下:

        源地址 和 目的地址 的 字段(32位)是在 IP 头部中,作用是 通过 IP 协议 发送报文给 对方主机。

        源端口 和 目的端口的字段(16位)是在 TCP 头部 中,作用是 告诉 TCP 协议 应该 把报文发给 哪个进程。

4. TCP 头

(1)序列号

        在 建立连接 时 由计算机 生成的 随机数作为 其初始值,通过 SYN 包 传给接收 端主机,每发送一次 数据,就「累加」一次该「数据字节数」的大小。用来 解决网络包 乱序问题。

(2)确认应答号

        指下一次「期望」收到的 数据的 序列号,发送端 收到这个 确认应答 以后 可以认为 在 这个序号 以前的数据 都已经被 正常接收。用来 解决丢包的 问题。

(3)控制位

  • ACK:该位为 1 时,「确认应答」的字段变为有效,TCP 规定除了最初 建立连接时 的 SYN 包之外 该位必须 设置为 1。
  • RST:该位为 1 时,表示 TCP 连接中 出现异常 必须 强制 断开连接。
  • SYN:该位为 1 时,表示 希望 建立连接,并在其「序列号」的字段 进行序列号 初始值的 设定。
  • FIN:该位为 1 时,表示 今后 不会再有数据 发送,希望 断开连接。当 通信结束 希望 断开连接时,通信 双方的 主机之间就 可以相互 交换 FIN 位为 1 的 TCP 段。

二、相关问题

1. 第一次握手丢失了,会发生什么?

        当 客户端想 和 服务端 建立 TCP 连接的时候,首先 第一个 发的 就是 SYN 报文,然后 进入到 SYN_SENT 状态。在这之后,如果 客户端 迟迟 收不到服务端的 SYN-ACK 报文(第二次握手),就会触发「超时重传」机制,重传 SYN 报文,而且 重传的 SYN 报文的 序列号 都是一样的。

        在 Linux 里,客户端的 SYN 报文 最大重传次数 由 tcp_syn_retries 内核参数 控制,这个参数是 可以 自定义的,默认值一般是 5。

        通常,每次 超时的 时间 是上一次的 2 倍。当 第五次 超时重传 后,会 继续等待 32 秒,如果服务端 仍然 没有回应 ACK,客户端就 不再发送 SYN 包,然后断开 TCP 连接。

        举个例子,假设 tcp_syn_retries 参数值为3,那么当客户端的 SYN 报文一直在 网络中 丢失时,会发生 下图的过程:


        当客户端 超时 重传 3 次 SYN 报文后,由于 tcp_syn_retries 为 3,已达 到 最大重 传次数,于是 再 等待一段时间(时间为 上一次 超时时间的 2 倍),如果 还是 没能 收到服务端的 第二次握手(SYN-ACK 报文),那么 客户端就会 断开连接。

2. 第二次握手丢失了,会发生什么?

        当 服务端 收到 客户端的 第一次握手 后,就会回 SYN-ACK 报文 给 客户端,这个 就是 第二次 握手,此时 服务端会 进入 SYN_RCVD 状态。

第二次握手的 SYN-ACK 报文有 两个目的:

  • 第二次握手里的 ACK,是对第一次握手的确认报文。
  • 第二次握手里的 SYN,是服务端发起建立 TCP 连接的报文。

        因为 第二次握手 报文里 是 包含对 客户端的 第一次握手 的 ACK 确认报文,所以,如果 客户端 迟迟 没有 收到第二次握手,那么 客户端就 觉得 可能自己的 SYN 报文(第一次握手)丢失了,于是 客户端就会 触发 超时重传机制,重传 SYN 报文。

        然后,因为 第二次握手 中 包含 服务端的 SYN 报文,所以当 客户端收到 后,需要 给 服务端发送 ACK 确认报文(第三次握手),服务端 才会 认为该 SYN 报文被 客户端收到了。那么,如果第二次握手 丢失了,服务端就 收不到第三次握手,于是 服务端 这边会 触发超时重传机制,重传SYN-ACK 报文。

        在 Linux 下,SYN-ACK 报文 的最大 重传次数 由 tcp_synack_retries 内核参数决定,默认值是 5。

        因此,当 第二次握手 丢失了,客户端 和 服务端 都会 重传:

  • 客户端会重传 SYN 报文,也就是 第一次握手,最大 重传 次数 由 tcp_syn_retries 内核参数决定。
  • 服务端会 重传 SYN-ACK 报文,也就是 第二次握手,最大重传 次数 由 tcp_synack_retries 内核 参数 决定。

        举个例子,假设 tcp_syn_retries 参数值为1,tcp_synack_retries 参数值为 2,那么当第二次握手 一直 丢失时,发生的 过程如下图:


  • 当客户端超时重传1次 SYN报文后,由于 tcp_syn_retries 为1,已达到最大重传次数,于是再等待一段时间(时间为上一次超时时间的2倍),如果还是没能收到服务端的第二次握手(SYN-ACK 报文),那么客户端就会断开连接。
  • 当服务端超时重传 2次 SYN-ACK 报文后,由于 tcp_synack_retries 2,已达到最大重传次数,于是再等待一段时间(时间为上一次超时时间的2倍),如果还是没能收到客户端的第三次握手(ACK报文),那么服务端就会断开连接。

3. 第三次握手丢失了,会发生什么?

        客户端 收到 服务端的 SYN-ACK 报文后,就会 给服务端 回一个 ACK 报文,也就是 第三次握手,此时 客户端 状态 进入到 ESTABLISH 状态。

        因为 这个 第三次握手 的 ACK 是对 第二次握手 的 SYN 的 确认报文,所以 当 第三次握手 丢失了,如果 服务端 那一方迟迟 收不到这个 确认报文,就会 触发超时重传机制,重传 SYN-ACK 报文,直到 收到 第三次握手,或者 达到 最大重传次数。

        注意,ACK 报文 是不会 有重传的,当 ACK 丢失了,就由对方 重传对应的 报文。

        举个例子,假设 tcp_synack_retries 参数值为 2,那么当 第三次握手 一直丢失 时,发生的 过程如下图:


        当 服务端 超时重传 2 次 SYN-ACK 报文后,由于 tcp_synack_retries 为 2,已达到最大重传次数,于是 再等待一段时间(时间为 上一次 超时时间 的 2 倍),如果 还是没能 收到客户端的 第三次握手(ACK 报文),那么 服务端 就会 断开连接。

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

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

相关文章

04.DDD与CQRS

学习视频来源:DDD独家秘籍视频合集 https://space.bilibili.com/24690212/channel/collectiondetail?sid1940048&ctype0 文章目录 定义职责分离DDD与CQRS的关系领域模型和查询模型特点命令场景的领域模型查询场景的查询模型 架构方案领域事件方案1&#xff1a…

树莓派全网最全安装测试(包括系统,显示器,灯,舵机灯测试)

1.下载ubuntu https://cdimage.ubuntu.com/releases/20.04.5/release/ 2.格式化和烧录镜像源 3.修改自己的wifl sd卡直接放回树莓派 4.IP地址 https://www.bilibili.com/video/BV1YD421H7zF/?buvidXU5DB1750D0CD69E8D83AEE359EB6582A7396&is_story_h5false&midMJB9z…

LabVIEW涡扇发动机加力泵测试

LabVIEW软件开发的涡扇发动机加力泵测试平台采用高度集成的硬件设备,实现了对涡扇发动机加力泵的全面测试和分析,从而确保其性能满足严格的航空标准。 项目背景 涡扇发动机是现代飞机的重要动力来源之一,其加力泵的性能直接影响飞机的整体动…

车载中控系统的UI自动化测试实践

本文主要介绍了如何在车载中控系统中实施UI自动化测试的过程,从测试环境的准备到测试用例的设计,再到具体实现方法及注意事项等方面进行了详细的阐述。 引言 随着汽车行业的快速发展,车载中控系统已成为提升驾驶体验的重要组成部分。为了保…

echarts属性之dataZoom

dataZoom-slider 滑动条型数据区域缩放组件(dataZoomInside) 滑动条型数据区域缩放组件提供了数据缩略图显示,缩放,刷选,拖拽,点击快速定位等数据筛选的功能。下图显示了该组件可交互部分 所有属性 data…

牛客小白月赛103(打表、二进制、几何、思维)

文章目录 牛客小白月赛103(打表、二进制、几何、思维)A. 小冰的正多边形B. 冰冰的电子邮箱C. 冰冰的异或(打表、二进制)D. 冰冰的分界线(几何、浮点数处理)E. 冰冰的 GCD(调和级数、思维) 据说F是假题&…

「C/C++」C++17 之 std::variant 安全的联合体(变体)

#1024程序员节|征文# ✨博客主页何曾参静谧的博客📌文章专栏「C/C」C/C程序设计📚全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计…

Web3的去中心化社交网络:区块链技术如何改变互动方式

随着互联网技术的不断进步,社交网络正在经历一场深刻的变革。Web3,作为新一代互联网技术的代表,正通过区块链和去中心化理念改变着我们与他人互动的方式。传统的社交网络通常由大型公司控制,用户数据的集中化管理和隐私问题备受关…

代码随想录(十二)——图论

并查集 并查集主要有三个功能。 寻找根节点,函数:find(int u),也就是判断这个节点的祖先节点是哪个将两个节点接入到同一个集合,函数:join(int u, int v),将两个节点连在同一个根节点上判断两个节点是否在…

HarmonyOS 5.0应用开发——文件读写

【高心星出品】 文章目录 文件读写文件操作创建目录删除目录或者文件扫描目录中文件 文本读写写入文本读取文本内容 文件读写文件写入边读边写 文件读写 Core File Kit(文件基础服务)为开发者提供一套访问和管理应用文件和用户文件的能力。帮助用户更高…

44-RK3588s调试 camera-engine-rkaiq(rkaiq_3A_server)

在RK3588s平台上调试imx415 camera sensor 过程中,已经识别到了camera sensor ID,并且可以拿到raw图和isp处理后的图像,但是isp处理后的图像偏绿,来看查看后台服务发现rkaiq_3A_server没有运行,然后单独运行rkaiq_3A_s…

Linux 宝塔安装(各操作系统命令合集)

由于CentOS官方已全面停止维护CentOS Linux项目,公告指出 CentOS 7和8在2024年6月30日停止技术服务支持,详情见CentOS官方公告。导致CentOS系统源已全面失效,比如安装宝塔等等会出现网络不可达等报错,需要切换源。系统源问题&…

Android 获取OAID

获取OAID 老规矩,直接上: implementation com.huawei.hms:opendevice:6.11.0.300 // 要获取华为vaid 和aaid,还需添加opendevice 依赖implementation(name: oaid_sdk_2.5.0, ext: aar) import android.content.Context; import android.util.…

基于微信小程序的公务员考试信息查询系统+LW示例参考

系列文章目录 1.基于SSM的洗衣房管理系统原生微信小程序LW参考示例 2.基于SpringBoot的宠物摄影网站管理系统LW参考示例 3.基于SpringBootVue的企业人事管理系统LW参考示例 4.基于SSM的高校实验室管理系统LW参考示例 5.基于SpringBoot的二手数码回收系统原生微信小程序LW参考示…

【Android】Kotlin教程(4)

文章目录 1.field2.计算属性3.主构造函数4.次构造函数5.默认参数6.初始化块7.初始化顺序7.延迟初始化lateinit8.惰性初始化 1.field field 关键字通常与属性的自定义 getter 和 setter 一起使用。当你需要为一个属性提供自定义的行为时,可以使用 field 来访问或设置…

可以在线制作的PS网页版来了!

在当今数字化的创意时代,设计领域不断发展与变革,设计师们对于工具的需求也日益多样化和高效化。随着互联网技术的飞速进步,一种全新的设计工具模式应运而生——在线制作的 PS 网页版。它以其独特的优势和便捷性,逐渐成为众多设计…

高德地图如何添加自己店铺的位置信息?

众所周知,创业开店时,地理位置的选择至关重要。一个优越的地理位置不仅能显著提升店铺的可见度,还能有效吸引更多潜在顾客的光顾。而且,为了将店铺的客流量最大化,商家还需在地图平台上准确标注自己的位置信息&#xf…

【黄豆颗粒数据集】黄豆识别 机器视觉 深度学习(含数据集)

一、背景意义 随着全球农业生产的现代化,黄豆(大豆)作为一种重要的经济作物,广泛用于食品、饲料和工业原料的生产。准确识别和分类黄豆颗粒对于农业生产的管理、质量控制和市场分析具有重要意义。然而,传统的人工分类方…

JavaEE-多线程上

文章目录 线程概述进程/线程多线程的作用JVM关于线程资源的规范关于Java程序的运行原理 并发与并行并发(concurrency)并行(parallellism)并发编程与并行编程 线程的调度策略分时调度模型抢占式调度模型 创建线程线程类分析入门实现线程的第一种方式实现线程的第二种方式 线程的…

论文阅读:三星-TinyClick

《Single-Turn Agent for Empowering GUI Automation》 赋能GUI自动化的单轮代理 摘要 我们介绍了一个用于图形用户界面(GUI)交互任务的单轮代理,使用了视觉语言模型Florence-2-Base。该代理的主要任务是识别与用户指令相对应的UI元素的屏幕…