什么是“三次挥手”和“四次握手”

article/2025/9/23 0:41:01

文章目录

  • 一、为什么要进行三次握手
  • 二、握手为什么要三次
  • 三、挥手为什么需要三次
  • 四、挥手为什么三次不行
  • 总结



前言

首先,我们先说什么是”三次握手“和”四次挥手“

 

1.我们先来简单介绍一下”三次握手“

(1).先来介绍一下里面这些看起来比较高级的字母:

SYN--同步序列号请求

seq--全称”Sequence number“--序列号

ACK--确认

ESTABLISHED--链接正常建立之后进入数据传输阶段

SYN SENT--发送完第一个SYN报文,等待收到确认

SYN RCVD--收到第一次的传输请求,还未进行确认

(2).三次握手的步骤:

  • 第一次:客户端发送初始序号x和syn=1请求标志

  • 第二次:服务器发送请求标志syn,发送确认标志ACK,发送自己的序号seq=y,发送客户端的确认序号ack=x+1

  • 第三次:客户端发送ACK确认号,发送自己的序号seq=x+1,发送对方的确认号ack=y+1

2.接着我们来介绍一下什么是"四次挥手”?

 

(1). 同上,我们先介绍这些字母:

FIN--请求断开连接

seq--全称”Sequence number“--序列号

ACK--确认

FIN WAIT 1--主动发送第一个FIN报文之后进入该状态

CLOSE WAIT--收到对方的关闭请求并进行确认进入该状态

FIN WAIT 2--已经收到第一个FIN的确认信号,等待对方发送关闭请求

LAST ACK--等待最后一次确认关闭的报文

TIME WAIT--收到对方的关闭请求并进行确认进入该状态

(2)四次挥手的操作方法:

  1. 客户端发送一个FIN段,并包含一个希望接收者看到的自己当前的序列号K. 同时还包含一个ACK表示确认对方最近一次发过来的数据。
  2. 服务端将K值加1作为ACK序号值,表明收到了上一个包。这时上层的应用程序会被告知另一端发起了关闭操作,通常这将引起应用程序发起自己的关闭操作。
  3. 服务端发起自己的FIN段,ACK=K+1, Seq=L
  4. 客户端确认。ACK=L+1


一、为什么要进行三次握手?

1.三次握手的作用:能够让双方都能明确自己和对方的收、发能力是正常的。

2.(1).第一次握手时:客户端发送网络包,服务端收到了。

这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。

(2).第二次握手时:服务端发包,客户端收到了。

这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。
客户端的视角来看,我接到了服务端发送过来的响应数据包,说明服务端接收到了我在第一次握手时发送的网络包,并且成功发送了响应数据包,这就说明,服务端的接收、发送能力正常。

而另一方面,我收到了服务端的响应数据包,说明我第一次发送的网络包成功到达服务端,这样,我自己的发送和接收能力也是正常的。

(3).第三次握手时:客户端发包,服务端收到了。

这样服务端就能得出结论:客户端的接收、发送能力,服务端的发送、接收能力是正常的。
第一、二次握手后,服务端并不知道客户端的接收能力以及自己的发送能力是否正常。而在第三次握手时,服务端收到了客户端对第二次握手作的回应。从服务端的角度,我在第二次握手时的响应数据发送出去了,客户端接收到了。所以,我的发送能力是正常的。而客户端的接收能力也是正常的。



二、握手为什么需要三次?


1.由上文内容可以看出想要握手是必须三次过程的。

原因如下:

(1).两次达不到让双方都得出自己、对方的接收、发送能力都正常的结论。

(2).每次收到网络包的一方至少是可以得到的信息是:对方的发送、我方的接收是正常的。而每一步都是有关联的,下一次的“响应”是由于第一次的“请求”触发,因此每次握手其实是可以得到额外的结论的。而这种结论都是从自己发出的信息得到关于他人的信息。应该可以说成间接信息。

(3).我们从第三次握手可以不难看出,当第三次握手时,服务端收到数据包,表明看服务端只能得到客户端的发送能力、服务端的接收能力是正常的,但是结合第二次,说明服务端在第二次发送的响应包,客户端接收到了,并且作出了响应,从而得到额外的结论:客户端的接收、服务端的发送是正常的。


三、挥手为什么需要四次?

1.TCP连接是双向传输的对等的模式,就是说双方都可以同时向对方发送或接收数据。

2.每当关闭一次连接时,会发送指令告诉对方自己的状态,我要关闭连接了。这时对方会回一个ACK,此时一个方向的连接关闭。但是另一个方向仍然可以继续传输数据,等到发送完了所有的数据后,会发送一个FIN段来关闭此方向上的连接。接收方发送ACK确认关闭连接。

注意:接收到FIN报文的一方只能回复一个ACK, 它是无法马上返回对方一个FIN报文段的,因为结束数据传输的“指令”是上层应用层给出的,我只是一个“搬运工”,我无法了解“上层的意志”


四、挥手为什么三次不行?

在这里,可能比较不容易懂,那么先举个”渣男“分手的例子吧。我相信这样可能更直观一些。

1.小渣和小美热恋了几年后,他们之间的感觉越来越微妙,慢慢的小美发现小扎对自己的关心越来越少了。终于小渣抵不住异地恋的痛苦,移情别恋了,看上了新来的学妹,小渣决定分手了,给小美寄了封分手信。

 分手就算了,居然还有脸要回送我的东西!渣男!小美,收到信后,气得跳脚,立马回了封信,让他滚蛋。

 第二天,小美就去邮局,把渣男送给她的东西都打包寄还了给他。小美还不忘在信中提醒,收到东西之后给我回封信,不要到时候耍赖说没收到,我再也不想看见你了!渣男!

 小渣收到小美寄的包裹之后,立马回了封信,说东西收到了,我们以后也别联系了

一段恋情就这么结束了。。

2.情侣之间分分合合,当然计算机之间的连接也经常需要断开连接,断开的方式竟然和情侣之间很相似。

1.客户端发送一个FIN包,表示要断开连接,并设置seq序列号为m到服务器端,客户端进入FIN_WAIT_1状态。

(小渣写分手信给小美,进入等待回信的状态)

2.服务器端收到客户端的FIN包后,就知道客户端想要断开连接了,于是返回一个ACK包,设置seq为m+1,服务器端进入CLOSE_WAIT状态。服务器端对客户端说,我知道你想要断开连接了,不过先等等,我这还有些数据没发完,你等我发完再关闭。

客户端收到服务器端的确认后,进入FIN_WAIT_2状态,客户端现在只接收服务器端的数据,不再发送数据。

(小美回信给小渣,同意分手,但是东西要整理下再寄给小渣,小渣进入等待包裹状态)

3.服务器端发送完所有数据之后,发送一个FIN报文,设置seq序列号为n,进入LAST_ACK状态,表示我的数据都已经发送完了,你可以断开连接了。

(小美给小渣寄回包裹,表示我们已经两清了,你收到之后给我回个信,就可以滚蛋了)

4.客户端收到服务器端的FIN包后,返回一个ACK包,设置seq序列号为n+1,客户端就进入了TIME-WAIT(时间等待)状态。服务器只要收到了客户端发出的确认,立即进入CLOSED状态,关闭的连接。

(小渣回信给小美说,你的包裹我收到了,我们以后不用再联系了)

6.注意此时TCP连接还没有释放,必须经过2MSL(最长报文段寿命)的时间后,才进入CLOSED状态。


          讲道理,四个报文都发送完毕,我们应该可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的。如果客户端发送出最后的ACK回复,服务器没有收到,服务器将不断重复发送FIN报文。所以客户端不能立即关闭,它必须确认服务器端接收到了该ACK。



总结

         “三次握手,四次挥手”看似简单,但是深究进去,还是可以延伸出很多知识点的。比如半连接队列、全连接队列等等。以前关于TCP建立连接、关闭连接的过程很容易就会忘记,可能是因为只是死记硬背了几个过程,没有深入研究背后的原理。


http://chatgpt.dhexx.cn/article/XUAQNd0c.shtml

相关文章

简述TCP四次挥手

四次挥手主要用到了两个标志位(ACK&FIN): ACK 示意参考:TCP三次握手FIN: 终止数据传输标志位---->当FIN为1的时候代表此数据为终止断开连接的请求 四次挥手流程: 由于TCP连接是双向传输的对等的模式即双工 wiki百科定义: 全双工(full-duplex)的…

简述四次挥手

什么是四次挥手 由于TCP连接是全双工的,断开一个TCP连接,需要客户端与服务器发送四个包来确认连接的断开 简述四次挥手的过程: 因为TCP是全双工的,因此,每个方向都要单独关闭 当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着 一方向不会再…

三次握手四次挥手

三次握手四次挥手是tcp协议中的,在说三次握手四次挥手先说一下tcp协议和udp协议。 (1)我们常用的网络通信如浏览网页、软件聊天、看的爱奇艺上的视频都是通过tcp、udp这两种协议来进行数据传输的; (2)tcp…

TCP三次握手与四次挥手(详解)

TCP三次握手 一:引出 客户端与服务器之间数据的发送和返回的过程当中需要创建一个叫TCP connection的东西;由于TCP不存在连接的概念,只存在请求和响应,请求和响应都是数据包,它们之间都是经过由TCP创建的一个从客户端…

TCP连接的四次挥手全过程

TCP通过四次挥手来释放连接 四次挥手的过程如下: 第一次挥手: 客户端向服务器发送一个 FIN 数据包(FIN 1,seq u)主动断开连接,报文中会指定一个序列号。告诉服务器:我要跟你断开连接了&am…

http三次握手四次挥手详解

1、 TCP的三次握手和四次挥手实质就是TCP通信的连接和断开。 三次握手:为了对每次发送的数据量进行跟踪与协商,确保数据段的发送和接收同步,根据所接收到的数据量而确认数据发送、接收完毕后何时撤消联系,并建立虚连接。 四次挥…

TCP四次挥手及原因

聚散终有时,TCP 断开连接是通过四次挥手方式。 双方都可以主动断开连接,断开连接后主机中的「资源」将被释放。 上图是客户端主动关闭连接 : 一次挥手 客户端打算关闭连接,此时会发送一个 TCP 首部 FIN 标志位被置为 1 的报文&…

TCP三次握手和四次挥手详解

文章目录 三次握手和四次挥手简述三次握手的目的三次握手流程详解半连接队列和全连接队列四次挥手的目的四次挥手详解为什么客户端需要TIME_WAIT状态为什么挥手比握手多一次为什么三次挥手不行TCP报文参数释义 三次握手和四次挥手简述 三次握手,即客户端与服务端进…

三次握手,四次挥手,为什么是三次握手四次挥手

三次握手 两次握手(情况1) 两次握手(情况2) OK,下面正经地来回答下这个问题,要搞清楚这个问题,首先得了解TCP究竟是如何保证可靠传输的。 PS:TCP协议中,主动发起请求的一…

TCP三次握手四次断开

转载地址:www.51niux.com IP协议是网络层的主要协议,为上层传输层提供无连接、无状态、不可靠的服务。优点是简单高效。无状态是指各个IP报文是独立传送的,不同步传输状态的信息,所以容易发生重复和乱序的情况。不可靠是指IP协议…

有关三次握手,四次挥手的超详细总结!!!

有关三次握手,四次挥手的超详细总结!!! 我们先来看一下三次握手和四次挥手的示意图: 图示为三次握手。 图示为四次挥手。 一、三次握手和四次挥手的过程: 三次握手: TCP建立连接的过程我们…

TCP四次挥手详解

在开始之前可以先了解一下 TCP三次握手 TCP四次挥手过程和状态变迁 为什么挥手需要四次? 为什么TIME_WAIT等待的时间是2MSL? 等待2MSL的意义 TIME_WAIT状态过多有什么危害? 如何解决TIME_WAIT状态过多? TCP四次挥手过程和…

C++ map遍历

C map遍历 #include <iostream> #include <map>using namespace std;int main() {map<int, int> _map;_map[0] 1;_map[1] 2;_map[10] 10;map<int, int>::iterator iter;iter _map.begin();while(iter ! _map.end()) {cout << iter->firs…

C++ map遍历(简单易记忆)

C中map遍历有两种方法&#xff1a; 第一种&#xff0c;使用迭代器&#xff0c;while循环 #include <iostream> #include <map> using namespace std; int main() {map<int,int> p;p[0] 1;p[1] 2;p[3] 4;map<int,int>::iterator it p.begin();whi…

Java中Map的4种遍历方式

原标题&#xff1a;Java中Map的4种遍历方式 第一种方式&#xff1a;这是平常用的最多也最可取的一种遍历方式。 for (Map.Entry entry : map.entrySet()) { System.out.println(“key” entry.getKey() “,value” entry.getValue()); 第二种方式&#xff1a;如果只需要…

HashMap的几种遍历方式及循环删除

目录 1. 前言2. HashMap 的遍历方式2.1. 迭代器 EntrySet2.2. 迭代器 KeySet2.3. ForEach EntrySet2.4. ForEach KeySet2.5. Lambda 表达式2.6. Streams API 3. 循环删除3.1. 迭代器 Iterator 方式3.2. ForEach 循环方式3.3. Lambda 表达式3.3.1. Lambda 删除的正确方式 3.4. S…

Map遍历四种方式及其效率

目录 1、Map介绍 2、Map数据结构及扩容 2.1、数组&#xff1a;寻址容易&#xff0c;插入和删除元素困难 2.2、链表&#xff1a;寻址困难&#xff0c;插入和删除元素容易 2.3、Map数组长度默认16&#xff0c;扩容负载因子为0.75 3、Map遍历4种方式及其效率 3.1、方式一&a…

前端map循环遍历使用

map定义 Array.map() ⽅法返回⼀个新数组&#xff0c;数组中的元素为原始数组元素调⽤函数处理后的值&#xff0c;同时不会改变原来的数组 var newArra[1,3,6,10,44]; var newArraysnewArra.map((index) > { return index*index }) console.log(newArra); //[1,3,6,10,44]…

map forEach for in 循环遍历

1.map遍历数组对象 var map [{ key : "百度", value : "李彦宏" },{key : "阿里巴巴", value : "马云" },]; for (var key in map) { console.log(map[key]); } 2.forEach遍历数组 forEach()方法需要一个函数作为参数&…

Map的循环遍历,修改,删除

预制数据 Map<String, String> map new HashMap<>();map.put("aaa","123");map.put("bbb","123");map.put("CCC","123"); 只循环key ---> map.keyset() for (String key : map.keySet()) {Syst…