当前位置: 首页 > news >正文

TCP三次握手,四次挥手

三次握手

  • 第一次握手:客户端向服务器发送一个 SYN 包,其中 SYN 标志位被设置为 1,表示客户端请求建立连接,并随机生成一个初始序列号 seq=x 。此时客户端进入 SYN_SENT 状态,等待服务器的确认1.
  • 第二次握手:服务器收到客户端的 SYN 包后,必须确认客户端的 SYN,于是向客户端发送一个 SYN+ACK 包,SYN 和 ACK 标志位都被设置为 1 。服务器也会随机生成一个自己的初始序列号 seq=y ,同时将确认号 ack 设置为 x+1,表示已经收到了客户端的序列号为 x 的 SYN 包。此时服务器进入 SYN_RECV 状态1.
  • 第三次握手:客户端收到服务器的 SYN+ACK 包后,会向服务器发送一个 ACK 包,ACK 标志位为 1,确认号 ack=y+1,表示已经收到了服务器的序列号为 y 的 SYN 包,而序列号 seq 则为 x+1 。发送完这个 ACK 包后,客户端和服务器都进入 ESTABLISHED 状态,此时 TCP 连接就成功建立了1.
四次挥手

  • 第一次挥手:当客户端或服务器中的一方完成数据传输任务后,会发送一个 FIN 包给对方,表示自己不再发送数据了,希望关闭连接。例如客户端发送 FIN 包,此时客户端进入 FIN_WAIT_1 状态1.
  • 第二次挥手:对方收到 FIN 包后,会发送一个 ACK 包给发送 FIN 包的一方,确认号为收到的 FIN 包的序列号加 1,表示已经收到了对方的关闭请求。比如服务器收到客户端的 FIN 包后,向客户端发送 ACK 包,服务器进入 CLOSE_WAIT 状态,而客户端收到 ACK 包后进入 FIN_WAIT_2 状态1.
  • 第三次挥手:在发送完 ACK 包后,如果接收 FIN 包的一方也没有数据要发送了,它会发送一个 FIN 包给对方,表示自己也准备关闭连接。例如服务器在确认客户端的 FIN 包后,若自己也无数据可发,就会向客户端发送 FIN 包,此时服务器进入 LAST_ACK 状态1.
  • 第四次挥手:客户端收到服务器的 FIN 包后,会再次发送一个 ACK 包给服务器,确认号为收到的 FIN 包的序列号加 1。客户端发送完 ACK 包后进入 TIME_WAIT 状态,等待一段时间后才会进入 CLOSED 状态,而服务器收到 ACK 包后直接进入 CLOSED 状态,至此 TCP 连接彻底关闭1

作用
  1. 三次握手的作用
    • 建立连接的可靠性保障:通过三次握手,客户端和服务器之间能够相互确认对方具有收发数据的能力。第一次握手,客户端发起连接请求;第二次握手,服务器回应客户端,表明自己能够接收客户端请求并且也有发送数据的能力;第三次握手,客户端确认服务器的回应,双方都清楚对方已准备好进行数据传输,从而建立起可靠的连接基础,避免了无效连接的建立。
    • 序列号同步:在握手过程中,双方交换初始序列号。序列号在后续的数据传输中用于对数据进行排序、确认和重传等操作,保证数据的顺序性和完整性。这使得接收方能够按照正确的顺序重组数据,同时也为可靠的数据传输机制提供了重要的标识。
    • 防止旧连接的干扰:序列号的使用和三次握手的过程可以防止网络中延迟的旧数据包干扰新建立的连接。因为每一次新的连接都有新的序列号,接收方可以根据序列号来判断数据包是否属于当前连接,避免将过期的数据误认为是新连接中的有效数据。
  2. 四次挥手的作用
    • 有序关闭连接:四次挥手是一种比较谨慎的连接关闭方式。双方通过发送 FIN 和 ACK 包来逐步关闭连接,确保数据能够完整地传输完毕并且双方都同意关闭连接。第一次挥手是一方主动提出关闭数据发送通道;第二次挥手是另一方对这个请求的确认,表示已经收到关闭请求;第三次挥手是另一方在自己也完成数据发送后,提出关闭自己的数据发送通道;第四次挥手是最初提出关闭请求的一方确认对方的关闭请求,从而实现双向的数据发送通道的有序关闭。
    • 确保数据完整性:在挥手过程中,通过 ACK 包的确认机制,保证了在关闭连接之前,所有已经发送的数据都被正确接收。例如,在 CLOSE_WAIT 状态下,服务器可以继续发送未发送完的数据,直到全部发送完成后才发送 FIN 包关闭连接,这样可以避免数据丢失,确保数据的完整性。
    • 资源释放:通过有序的四次挥手,双方能够合理地释放连接占用的资源,如缓存区、端口号等。这对于网络资源的有效利用非常重要,避免资源的浪费和因资源占用导致的潜在问题,如端口耗尽等情况。

TCP 三次握手过程是怎样的?

TCP 是面向连接的协议,所以使用 TCP 前必须先建立连接,而建立连接是通过三次握手来进行的。三次握手的过程如下图:

close,close,Listen,syn_sent,sys_rcvd,established,established

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

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

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

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

  • 服务端收到客户端的应答报文后,也进入 ESTABLISHED 状态。

从上面的过程可以发现第三次握手是可以携带数据的,前两次握手是不可以携带数据的,这也是面试常问的题。

一旦完成三次握手,双方都处于 ESTABLISHED 状态,此时连接就已建立完成,客户端和服务端就可以相互发送数据了。

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

相信大家比较常回答的是:“因为三次握手才能保证双方具有接收和发送的能力。”

这回答是没问题,但这回答是片面的,并没有说出主要的原因。

在前面我们知道了什么是 TCP 连接

  • 用于保证可靠性和流量控制维护的某些状态信息,这些信息的组合,包括 Socket、序列号和窗口大小称为连接。

所以,重要的是为什么三次握手才可以初始化 Socket、序列号和窗口大小并建立 TCP 连接。

接下来,以三个方面分析三次握手的原因:

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

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

  • 三次握手才可以避免资源浪费

小结

TCP 建立连接时,通过三次握手能防止历史连接的建立,能减少双方不必要的资源开销,能帮助双方同步初始化序列号。序列号能够保证数据包不重复、不丢弃和按序传输。

不使用「两次握手」和「四次握手」的原因:

  • 「两次握手」:无法防止历史连接的建立,会造成双方资源的浪费,也无法可靠的同步双方序列号;

  • 「四次握手」:三次握手就已经理论上最少可靠连接建立,所以不需要使用更多的通信次数。

TCP 四次挥手过程是怎样的?

天下没有不散的宴席,对于 TCP 连接也是这样, TCP 断开连接是通过四次挥手方式。

双方都可以主动断开连接,断开连接后主机中的「资源」将被释放,四次挥手的过程如下图:

客户端主动关闭连接 —— TCP 四次挥手

  • 客户端打算关闭连接,此时会发送一个 TCP 首部 FIN 标志位被置为 1 的报文,也即 FIN 报文,之后客户端进入 FIN_WAIT_1 状态。

  • 服务端收到该报文后,就向客户端发送 ACK 应答报文,接着服务端进入 CLOSE_WAIT 状态。

  • 客户端收到服务端的 ACK 应答报文后,之后进入 FIN_WAIT_2 状态。

  • 等待服务端处理完数据后,也向客户端发送 FIN 报文,之后服务端进入 LAST_ACK 状态。

  • 客户端收到服务端的 FIN 报文后,回一个 ACK 应答报文,之后进入 TIME_WAIT 状态

  • 服务端收到了 ACK 应答报文后,就进入了 CLOSE 状态,至此服务端已经完成连接的关闭。

  • 客户端在经过 2MSL 一段时间后,自动进入 CLOSE 状态,至此客户端也完成连接的关闭。

你可以看到,每个方向都需要一个 FIN 和一个 ACK,因此通常被称为四次挥手

这里一点需要注意是:主动关闭连接的,才有 TIME_WAIT 状态。

为什么挥手需要四次?

再来回顾下四次挥手双方发 FIN 包的过程,就能理解为什么需要四次了。

  • 关闭连接时,客户端向服务端发送 FIN 时,仅仅表示客户端不再发送数据了但是还能接收数据。

  • 服务端收到客户端的 FIN 报文时,先回一个 ACK 应答报文,而服务端可能还有数据需要处理和发送,等服务端不再发送数据时,才发送 FIN 报文给客户端来表示同意现在关闭连接。

从上面过程可知,服务端通常需要等待完成数据的发送和处理,所以服务端的 ACKFIN 一般都会分开发送,因此是需要四次挥手。

但是在特定情况下,四次挥手是可以变成三次挥手的,具体情况可以看这篇:TCP 四次挥手,可以变成三次吗?(opens new window)

参考:

小林coding

相关文章:

TCP三次握手,四次挥手

三次握手 第一次握手:客户端向服务器发送一个 SYN 包,其中 SYN 标志位被设置为 1,表示客户端请求建立连接,并随机生成一个初始序列号 seqx 。此时客户端进入 SYN_SENT 状态,等待服务器的确认1.第二次握手:服…...

Mono里建立调试C#脚本运行环境

前面已经介绍了怎么样来执行一个嵌入式的脚本框架, 这个框架是mono编写的一个简单的例子。 如果不清楚,可以参考前文: https://blog.csdn.net/caimouse/article/details/144632391?spm=1001.2014.3001.5501 本文主要来介绍一下,我们的C#脚本是长得怎么样的,它大体如下…...

Linux dnf 包管理工具使用教程

简介 dnf 是基于 Red Hat Linux 发行版的下一代包管理工具,它代替 yum 提供更好的性能、更好的依赖处理和更好的模块化架构。 基础语法 dnf [options] [command] [package] 常用命令用法 更新元数据缓存 sudo dnf check-update# 检查已安装的包是否有可用的更…...

Java 创建线程的方式有哪几种

在 Java 中,创建线程的方式有四种,分别是:继承 Thread 类、实现 Runnable 接口、使用 Callable 和 Future、使用线程池。以下是详细的解释和通俗的举例: 1. 继承 Thread 类 通过继承 Thread 类并重写 run() 方法来创建线程。 步…...

计算机的错误计算(一百八十七)

摘要 用大模型计算 sin(123.456789). 其自变量为弧度。结果保留16位有效数字。第一个大模型是数学大模型。先是只分析,不计算;后经提醒,才给出结果,但是是错误结果。第二个大模型,直接给出了Python代码与结果&#xf…...

12. 最大括号深度

题目描述 现有一字符串仅由"(",")", "{","}", "[", "]"六种括号组成。若字符串满足以下条件之一, 则为无效字符串:任一类型的左右括号数量不相等 存在未按正确顺序(先左后右)闭合的括号输出…...

进程与线程以及如何查看

长期补充,建议关注收藏! 定义 特性进程线程定义程序执行的基本单位执行中的最小单位资源拥有独立的内存空间和资源共享进程的资源开销创建和销毁的开销较大创建和销毁的开销较小执行单位进程中可以有多个线程线程是执行单元,必须依赖于进程并…...

BlueLM:以2.6万亿token铸就7B参数超大规模语言模型

一、介绍 BlueLM 是由 vivo AI 全球研究院自主研发的大规模预训练语言模型,本次发布包含 7B 基础 (base) 模型和 7B 对话 (chat) 模型,同时我们开源了支持 32K 的长文本基础 (base) 模型和对话 (chat) 模型。 更大量的优质数据 :高质量语料…...

Webpack学习笔记(4)

1.缓存 可以通过命中缓存降低网络流量,是网站加站速度更快。 然而在部署新版本时,不更改资源的文件名,浏览器可能认为你没有更新,所以会使用缓存版本。 由于缓存存在,获取新的代码成为问题。 接下来将配置webpack使…...

28、论文阅读:基于像素分布重映射和多先验Retinex变分模型的水下图像增强

A Pixel Distribution Remapping and Multi-Prior Retinex Variational Model for Underwater Image Enhancement 摘要介绍相关工作基于模型的水下图像增强方法:无模型水下图像增强方法:基于深度学习的水下图像增强方法: 论文方法概述像素分布…...

5.interview-self-introduction

1.保证电话面试来的时候,可以接听,保持电话通常 interviews will be arranged recently.please keep your phone line open and make sure you can answer th call when the phone interview comes. speak loudly and slow down your speaking voice &a…...

高性能MySQL-查询性能优化

查询性能优化 1、为什么查询这么慢2、慢查询基础:优化数据访问2.1 是否向数据库请求了不需要的数据2.2 MySQL是否存在扫描额外的记录 3、重构查询方式3.1 一个复杂查询还是多个简单查询3.2 切分查询3.3 分解联接查询 4、查询执行的基础4.1 MySQL的客户端/服务器通信…...

如何有效修复ffmpeg.dll错误:一站式解决方案指南

当您遇到提示“ffmpeg.dll文件丢失”的错误时,这可能导致相关的应用程序无法启动或运行异常。本文将详细介绍如何有效地解决ffmpeg.dll文件丢失的问题,确保您的应用程序能够恢复正常运行。 ffmpeg.dll是什么?有哪些功能? ffmpeg.…...

8086汇编(16位汇编)学习笔记00.DEBUG命令使用解析及范例大全

8086汇编(16位汇编)学习笔记00.DEBUG命令使用解析及范例大全-C/C基础-断点社区-专业的老牌游戏安全技术交流社区 - BpSend.net[md]启动 Debug,它是可用于测试和调试 MS-DOS 可执行文件的程序。  Debug [[drive:][path] filename [parameters]]  参数  [drive:…...

查看mysql的冷数据配置比例

查看mysql的冷数据配置比例 -- 真正的LRU链表,会被拆分为两个部分,一部分是热数据,一部分是冷数据,这个冷热数据的比例是由innodb_old_blocks_pct参数控制的,它默认是37,也就是说冷数据占比37%。 show GLO…...

【Java基础面试题028】Java中的hashCode和equals方法,与==操作符有什么区别?

回答重点 hashcode、equals 和 都是Java中用于比较对象的三种方式,但是它们的用途和实现还是有挺大区别的。 hashcode用于散列存储结构中确定对象的存储位置。可用于快速比较两个对象是否不同,因为如果它们的哈希码不同,那么它们肯定不相等…...

在C#中测试比较目录的不同方法以查看它们有哪些共同的文件

C# 中的示例“比较目录以查看它们有哪些共同的文件”使用Directory.GetFiles获取两个目录中的文件。它对文件进行排序,并比较两个排序后的列表以查看哪些文件位于第一个目录中、第二个目录中或两个目录中。有关其工作原理的详细信息,请参阅该示例。 Kur…...

harbor离线安装 配置https 全程记录

1. 下载harbor最新版本 下载网址: 找最新的版本: https://github.com/goharbor/harbor/releases/download/v2.11.2/harbor-offline-installer-v2.11.2.tgz 这里我直接使用迅雷下载, 然后上传 1.1解压 sudo tar -xf harbor-offline-installer-v2.11.2.tgz -C /opt/ 2. 配置Harb…...

C++简明教程(文章要求学过一点C语言)(5)

在开始之前必须阅读这个文章 https://blog.csdn.net/weixin_45100742/article/details/135152562 这篇文章完全是对C语言的补课,如果C语言学的好,可跳过。 变量、数据类型与运算符 在 C 编程中,理解变量、数据类型和运算符是构建程序的基石…...

Halcon单相机+机器人=眼在手上#标定心得

首先,这个标定板肯定是放在我们要作业的工作台上的 目的 **1,得到标定物(工作台)与机器人底座之间的pose转换关系。2,得到相机与机器人末端tool的的转换关系。 两个不确定的定量 1,标定板与机器人底座b…...

【hackmyvm】Diophante 靶场

1. 基本信息^toc 这里写目录标题 1. 基本信息^toc2. 信息收集2.1. 端口扫描2.2. 目录扫描2.3. knock 3. WordPress利用3.1. wpscan扫描3.2. smtp上传后门 4. 提权4.1. 提权leonard用户4.2. LD劫持提权root 靶机链接 https://hackmyvm.eu/machines/machine.php?vmDiophante 作者…...

C++类的继承关系中什么时候要用到上行转换和下行转换

一、C类继承关系中的上行转换 1. 多态性实现 在C中,上行转换(将派生类转换为基类)是实现多态性的关键。例如,当有一个基类Animal,以及派生类Dog和Cat。如果有一个函数接受Animal类型的参数,我们可以将Dog或…...

Ubuntu 22.04永久保存路由

在 Ubuntu 22.04 上,可以按照以下方式配置让流量访问 172.19.201.207 走指定的路由。 1. 临时添加路由 临时路由规则只在当前系统会话中有效,重启后会丢失。 添加路由规则 运行以下命令: sudo ip route add 172.19.201.207 via 192.168.2…...

数据结构十大排序之(冒泡,快排,并归)

接上期: 数据结十大排序之(选排,希尔,插排,堆排)-CSDN博客 前言: 在计算机科学中,排序算法是最基础且最重要的算法之一。无论是大规模数据处理还是日常的小型程序开发,…...

OpenFeign源码

openfeign是通过FeignClientFactoryBean生成动态代理对象的方式实现http客户端无感调用,可以做到像定义接口一样写http客户端调用代码。 配置Feign接口后,我们通常会在SpringBoot项目启动类上标记EnableFeignClients,这个是生成动态代理对象的…...

sql server索引优化语句

第一步 建一个测试表 --create table TestUsers --( -- Id int primary key identity(1,1), -- Username varchar(30) not null, -- Password varchar(10) not null, -- CreateDateTime datetime not null --)第二步 插入100w数据 大概1分钟执行时间 ----插入数据…...

深度学习之超分辨率算法——SRGAN

更新版本 实现了生成对抗网络在超分辨率上的使用 更新了损失函数,增加先验函数 SRresnet实现 import torch import torchvision from torch import nnclass ConvBlock(nn.Module):def __init__(self, kernel_size3, stride1, n_inchannels64):super(ConvBlock…...

16.2、网络安全风险评估技术与攻击

目录 网络安全风险评估技术方法与工具 网络安全风险评估技术方法与工具 资产信息收集,可以通过调查表的形式把我们各类的资产信息进行一个统计和收集,掌握被评估对象的重要资产分布,进而分析这些资产关联的业务面临的安全威胁以及存在的安全…...

【项目管理】GDB调试

gdb(GNU Debugger) 是 Linux 和嵌入式开发中最常用的调试工具之一,可以用来调试 C/C 程序、排查崩溃、分析程序流程等。在嵌入式开发中,gdb 还可以通过远程调试(gdbserver)调试目标设备上的程序。 这篇文章…...

ChatGPT生成接口测试用例(一)

用ChatGPT做软件测试 接口测试在软件开发生命周期中扮演着至关重要的角色,有助于验证不同模块之间的交互是否正确。若协议消息被恶意修改,系统是否能够恰当处理,以确保系统的功能正常运行,不会出现宕机或者安全问题。 5.1 ChatGP…...