TCP 建链(三次握手)和断链(四次握手)

TCP 建链(三次握手)和断链(四次挥手)

  • 背景
  • 简介
  • 建链(三次握手)
  • 断链(四次挥手)
  • 序号及标志位
  • 延伸问题
    • 为什么建立连接需要握手三次,两次行不行?
    • 三次握手可以携带数据吗?
    • 为什么释放连接是四次,比建立连接多一次?
    • 为什么 `TIME_WAIT` 状态需要经过 `2MSL` 才能返回到 `CLOSED` 状态?

背景

随着年龄的增长,很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来,技术出身的人总是很难放下一些执念,遂将这些知识整理成文,以纪念曾经努力学习奋斗的日子。本文内容并非完全原创,大多是参考其他文章资料整理所得,感谢每位技术人的开源精神。

简介

本文介绍 TCP 的建链和断链过程,即通常所说的三次握手和四次挥手的过程。

建链(三次握手)

TCP 建链需要客户端与服务器之间交互 3 个数据包,主要作用就是为了确认双方的接收和发送能力是否正常,初始序列号、交换窗口大小以及 MSS 等信息。
TCP建链 - 三次握手

  • 第一次握手
    客户端发送请求连接数据包到服务器,标志位 SYN 置为 1,随机生成一个初始序号 seq ,即 SYN=1 seq=x,客户端从 CLOSED 状态进入 SYN_SENT 状态,等待服务器回复。

  • 第二次握手
    服务器收到请求数据包后根据标志位 SYN=1 知道客户端在请求建立连接,服务器将标志位 SYNACK 都置为 1,确认序号 ack=x+1,随机生成一个初始序号 seq=y,并将该数据包 SYN=1, ACK=1, seq=y, ack=x+1 回复给客户端确认连接请求,服务器从 LISTEN 状态进入 SYN_RCVD 状态。

  • 第三次握手
    客户端收到确认后检查确认序号 ack 是否为 x+1ACK 是否为 1,如果正确则将标志位 ACK 置为1,确认序号 ack=y+1,并将该数据包 ACK=1, seq=x+1, ack=y+1 发送给服务器,发送完成后客户端进入 ESTABLISHED 状态,服务器接收到后检查确认序号 ack 是否为 y+1,如果正确则连接建立成功,服务器进入 ESTABLISHED 状态。随后客户端与服务器间可以开始传输数据。

断链(四次挥手)

TCP断链 - 四次挥手

  • 第一次挥手
    客户端发起 FINFIN=1, ACK=1, seq=u, ack=v,客户端从 ESTABLISHED 状态进入 FIN_WAIT_1 状态。TCP 协议规定,即使 FIN 包不携带数据,也要消耗一个序号。此 FIN 包中 ACK=1ack=v 基于断链前正常通信的数据包。

  • 第二次挥手
    服务器收到 FIN 包,发出 ACK 确认包,并带上自己的序号 seq=vACK=1 seq=v ack=u+1),服务器进入从 ESTABLISHED 状态进入 CLOSE_WAIT 状态。此时客户端已经没有数据需要发送给服务器了,但服务器如果仍有数据发送给客户端的话,客户端依然需要接收。客户端接收到服务器发送的 ACK 后进入 FIN_WAIT_2 状态。

  • 第三次挥手
    服务器数据发送完成后向客户端发送 FINFIN=1, ACK=1, seq=w, ack=u+1,半连接状态下服务器可能又发送了一些数据,假设发送 seqw,服务器进入 LAST_ACK 状态。

  • 第四次挥手
    客户端接收到服务器的 FIN 包后发出确认包 ACK=1, seq=u+1, ack=w+1,客户端进入 TIME_WAIT 状态,此时 TCP 连接还没有释放,必须经过 2*MSL 后才进入 CLOSED 状态,而服务器接收到客户端的 ACK 后就进入了 CLOSED 状态,服务器结束 TCP 连接的时间要比客户端早一些。

序号及标志位

TCP 建链(三次握手)和断链(四次挥手)中涉及到几个关键概念字段:

  • 标志位:共有 6 个,分别是:
    • ACK:确认序号有效。
    • FIN:释放一个连接。
    • PSH:接收方应该尽快将这个报文交给应用层。
    • RST:重置连接。
    • SYN:发起一个新连接。
    • URG:紧急指针(urgent pointer)有效。
  • seq:Seq 序号,占 32 位,用来标识从 TCP 源端向目的端发送的字节流,发起方发送数据时对此进行标记。
  • ack:Ack 序号,占 32 位,只有 ACK 标志位等于 1 时此序号字段才有效,确认方 ack 等于发起方 seq + 1注意:ACKack 是两个不同的概念,不要混淆了。

延伸问题

为什么建立连接需要握手三次,两次行不行?

  • 原因一:TCP连接建立前需要确认客户端和服务器双方的收发包能力。
    • 第一次握手可以让服务器知道客户端的发送能力是正常的。
    • 第二次握手可以让客户端知道服务器的接收和发送能力都是正常的。
    • 第三次握手可以让服务器指导客户端的接收能力是正常的。
  • 原因二:确保序列号可靠同步。
    第二次握手服务器向客户端发送了自己的初始序列号,如果第二次握手报文丢失则客户端就无法知道服务器的初始序列号,所以需要第三次握手让服务器知道客户端已确认服务器的初始序列号。
  • 原因三:阻止重复历史连接的初始化。
    客户端由于某种原因发送了两个不同序号的 SYN 包,因为复杂的网络环境中旧的数据包有可能先到达服务器,如果是两次握手则服务器收到旧的 SYN 包就会立刻建立连接,从而造成网络异常。如果是三次握手,服务器需要回复 SYN+ACK 包,客户端会对比应答的序号,如果发现是旧的报文就会给服务器发 RST 包,直至正确的 SYN 包到达服务器后才正常建立连接。
  • 原因四:安全问题。
    TCP 新建连接时内核会为连接分配一系列内存资源,如果采用两次握手可能会放大DDOS 攻击。

三次握手可以携带数据吗?

第一次握手和第二次握手不可以携带数据,第三次握手可以携带数据。假如第一次握手携带数据,如果碰到恶意攻击,那么每次在第一次握手的 SYN 报文中都会加入大量数据,会造成服务器花费大量存储空间来缓存这些数据。

为什么释放连接是四次,比建立连接多一次?

建立连接时服务器的 SYNACK 是合并发送的,而因 TCP 是全双工通信,释放连接过程中在客户端发送 FIN 包后,服务器可能还有数据需要发送,不能立即关闭连接,所以不能同时发送 FIN 包和 ACK 包,只能先确认 ACK,然后等服务器无数据发送时再发送 FIN 包。

为什么 TIME_WAIT 状态需要经过 2MSL 才能返回到 CLOSED 状态?

MSL 是指报文在网络中的最大生存时间。

  • 原因一:在客户端回复服务器 FIN 包的确认包 ACK 后,这个 ACK 包可能是不可达的,如果服务器收不到 ACK 的话需要重新发送 FIN 包。所以客户端发送 ACK 后需要留出 2MSL 时间(ACK 到达服务器的时间 + 服务器重发 FIN 包时间),如果客户端等到 2MSL 后没有收到服务器重传的 FIN 包,说明可以确认服务器已经收到了客户端发送的 ACK 包。
  • 原因二:客户端发送完最后一个 ACK 包后,再经过 2MSL 时间就可以使当前连接持续的时间内所产生的所有报文都从网络中小时,使下一个新的连接中不会出现这种旧的连接请求报文。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Vue】Vue生命周期

Vue生命周期:就是一个Vue实例从创建(new一个Vue实例) 到 销毁(关闭网页) 的整个过程。 生命周期四个阶段:① 创建 ② 挂载 ③ 更新 ④ 销毁 创建阶段:创建响应式数据 通过data给当前的Vue实例提…

【设计模式】结构型-适配器模式

前言 在软件开发中,经常会遇到需要将一个类的接口转换成另一个类的接口的情况。这可能是因为新旧系统之间的接口不兼容,或者是因为需要使用的第三方库的接口与当前系统的接口不匹配。为了解决这类问题,设计模式中的适配器模式应运而生。 一…

Leetcode3164. 优质数对的总数 II

Every day a Leetcode 题目来源:3164. 优质数对的总数 II 解法1:统计因子 遍历 nums1,统计所有元素的因子个数,记录到哈希表 cnt 中。 遍历 nums2,那么有 cnt[nums2[i]*k] 个数可以被 nums2[i]*k 整除,…

容器化部署Pig微服务快速开发框架

系统说明 基于 Spring Cloud 、Spring Boot、 OAuth2 的 RBAC 企业快速开发平台, 同时支持微服务架构和单体架构 提供对 Spring Authorization Server 生产级实践,支持多种安全授权模式 提供对常见容器化方案支持 Kubernetes、Rancher2 、Kubesphere、E…

南昌代理记账公司的收费标准及咨询服务

随着现代商业的快速发展,对于财务管理的需求也在不断增加,作为一家专业的会计代理公司,我们的目标是为各类企业提供全面、高效的财务管理服务,任何服务都应以公平合理的价格为基础,我们一直坚持这一原则。 关于常州代…

NDIS网络接口

在windows发行版本中,真的存在一个 ndis.sys 的驱动文件,和我们认知的不太一样,它真的是一个DLL,NDIS 库打包在 Ndis.sys(一个内核模式导出库)中,作为一组函数,强调宏以获得最佳性能…

0基础学习区块链技术——链之间数据同步样例

我们可以在https://blockchaindemo.io/体验这个过程。 创建区块 默认第一个链叫Satoshi(中本聪)。链上第一个区块叫“创世区块”——Genesis Block。后面我们会看到创建的第二条链第一个区块也是如此。 新增链 新创建的链叫Debby。默认上面有一个创世区块。 然后我们让这…

可视化数据科学平台在信贷领域应用系列一:数据探索

引言 信贷风险数据建模是金融机构在数据量日益庞杂的时代进行信贷业务风控的关键技术。它能够帮助机构更好地控制风险、减少违约损失,并提高业务效率。通过不断优化建模方法和利用建模工具,金融机构的风险控制能力得到了显著提升。 在本文中,…

python数据分析——逻辑回归

参考资料:活用pandas库 逻辑回归 当响应变量为二值响应变量时,经常使用逻辑回归对数据建模。 # 导入pandas库 import pandas as pd # 导入数据集 acspd.read_csv(r"...\data\acs_ny.csv") # 展示数据列 print(acs.columns) # 展示数据集 pri…

MongoDB CRUD操作:可重试写入

MongoDB CRUD操作:可重试写入 文章目录 MongoDB CRUD操作:可重试写入使用的先决条件部署的限制支持的存储引擎3.6 MongoDB 驱动程序MongoDB 版本写确认 可重试写入和多文档事务启用可重试写入MongoDB驱动mongosh 可重试的写操作行为持续的网络错误故障切…

Python版《消消乐》,附源码

曾经风靡一时的消消乐,至今坐在地铁上都可以看到很多人依然在玩,想当年我也是大军中的一员,那家伙,吃饭都在玩,进入到高级的那种胜利感还是很爽的,连续消,无限消,哈哈,现…

开源数据库同步工具DBSyncer-数据库的连接

开源数据库同步工具DBSyncer使用的是什么数据库呢? 查看连接信息,如下: 如上图可知,DBSyncer支持两种方式的数据库连接方式, #storage #数据存储类型:disk(默认)/mysql(推荐生产环境使用) #disk-磁盘:/data/config(驱…

基于Java的敬老院管理系统设计和实现(论文 + 源码)

【免费】基于Java的敬老院管理系统设计和实现.zip资源-CSDN文库https://download.csdn.net/download/JW_559/89399326 基于Java的敬老院管理系统设计和实现 摘 要 新世纪以来,互联网与计算机技术的快速发展,我国也迈进网络化、集成化的信息大数据时代。对于大众而言,单机应用早…

Git版本控制:核心概念、操作与实践

Git是一种分布式版本控制系统,被广泛应用于软件开发过程中。本文将介绍Git的核心概念、常用操作以及最佳实践,帮助读者掌握Git的基本技巧,提高团队协作效率。 一、引言 在软件开发过程中,版本控制是至关重要的。它能帮助我们跟踪…

推导Hessian of XPBD

记 M后面新增的部分为H H − ∂ 2 C ∂ x 2 λ H - \frac{\partial^2 C}{\partial x^2} \lambda H−∂x2∂2C​λ 那么如何求C的二阶导数呢 使用 https://www.matrixcalculus.org/

java自学阶段二:JavaWeb开发--day80(项目实战2之苍穹外卖)

《项目案例—黑马苍穹外卖》 目录: 学习目标项目介绍前端环境搭建(前期直接导入老师的项目,后期自己敲)后端环境搭建(导入初始项目,新建仓库使用git管理项目,新建数据库,修改登录功能&#xff…

如何以定投策略投资场外个股期权?

场外个股期权为投资者提供了一种灵活且富有潜力的投资工具。与传统的投资方式不同,场外个股期权以其低门槛、高灵活性和潜在的较高回报吸引了众多投资者。对于希望长期稳健增值的投资者来说,利用定投策略来投资场外个股期权是一个值得考虑的选项。 文章…

mathematica中三维画图中标记函数的最大值点

示例代码&#xff1a; Clear["*"]; f[x_, y_] : -(x - 1)^2 - (y 1)^2;(*找到最大值点*) maxPoint Maximize[{f[x, y], -10 < x < 10 && -10 < y < 10 && x^2 y^2 < 10}, {x, y}](*绘制3D图形并标记最大值点*) Y1 Plot3D[f[x, y…

gravis,一个无敌的 Python 库!

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;今天为大家分享一个无敌的 Python 库 - gravis。 Github地址&#xff1a;https://github.com/robert-haas/gravis 在数据科学和机器学习领域&#xff0c;数据的可视化是一个非常重要的环节。通过可视化&#xff…

每日一题33:数据统计之广告效果

一、每日一题 返回结果示例如下&#xff1a; 示例 1&#xff1a; 输入&#xff1a; Ads 表: ------------------------- | ad_id | user_id | action | ------------------------- | 1 | 1 | Clicked | | 2 | 2 | Clicked | | 3 | 3 | Viewed…