官方解析
TCP 三次握手和四次挥手是 TCP 协议中建立和终止连接的过程。
三次握手的流程如下:
-
客户端向服务器发送 SYN 包,表示请求建立连接,此时客户端进入 SYN_SENT 状态。
-
服务器接收到 SYN 包后,回应一个 SYN-ACK 包,表示同意建立连接,此时服务器进入 SYN-RECEIVED 状态。
-
客户端接收到 SYN-ACK 包后,向服务器回应一个 ACK 包,表示确认建立连接,此时客户端进入 ESTABLISHED 状态。服务器收到 ACK 包后也进入 ESTABLISHED 状态。
四次挥手的流程如下:
-
客户端向服务器发送 FIN 包,表示希望关闭连接,此时客户端进入 FIN-WAIT-1 状态。
-
服务器接收到 FIN 包后,向客户端回应一个 ACK 包,表示已经收到了关闭请求,此时服务器进入 CLOSE-WAIT 状态,客户端收到 ACK 包后进入 FIN-WAIT-2 状态。
-
服务器关闭连接后,向客户端发送一个 FIN 包,表示可以关闭连接,此时服务器进入 LAST-ACK 状态。
-
客户端接收到服务器的 FIN 包后,向服务器回应一个 ACK 包,表示已经收到关闭请求,此时客户端进入 TIME-WAIT 状态,等待 2MSL(最大报文生存时间)后,关闭连接。服务器收到 ACK 包后也进入 CLOSED 状态。
三次握手是为了确保客户端和服务器都能够收到对方的请求和回应,防止因为网络原因导致请求或回应丢失而建立不了连接。四次挥手则是为了确保连接的正常关闭,防止因为网络原因导致连接无法关闭或者出现连接断开后还能够接收到数据的情况。
TCP(Transmission Control Protocol)是一种面向连接的协议,为了保证数据传输的可靠性,TCP 使用了三次握手和四次挥手的过程。
三次握手的过程如下:
-
第一次握手:客户端向服务器发送 SYN 报文,请求建立连接。
-
第二次握手:服务器收到客户端的 SYN 报文,向客户端发送 SYN+ACK 报文,表示可以建立连接。
-
第三次握手:客户端收到服务器的 SYN+ACK 报文,向服务器发送 ACK 报文,表示连接已经建立。
如图所示:
为什么需要三次握手?
三次握手的目的是为了确认双方的收发能力和同步初始序列号。
四次挥手的过程如下:
第一次挥手:客户端向服务器发送 FIN 报文,请求关闭连接。第二次挥手:服务器收到客户端的 FIN 报文,向客户端发送 ACK 报文,表示收到关闭请求。第三次挥手:服务器向客户端发送 FIN 报文,请求关闭连接。第四次挥手:客户端收到服务器的 FIN 报文,向服务器发送 ACK 报文,表示收到关闭请求。如图所示:
为什么需要四次挥手?
四次挥手的目的是为了保证数据的完整性和可靠性。在关闭连接之前,双方需要确保所有数据都已经传输完毕,因此需要通过四次挥手的过程进行确认和处理。
总结:三次握手的本质是确认通信双方收发数据的能力 ,四次挥手的目的是关闭一个连接。
TCP 三次握手
目的:
-
建立连接
-
使每一方确认对方的存在
-
允许双方进行参数的协商
-
进行资源的分配
流程
-
A 的 TCP 向 B 发送 连接请求报文段,其首部中的同步位 SYN = 1 ,并随机选择一个序号 seq = x ,表明传送数据时的第一个数据字节序号为 x。
-
B 的 TCP 收到连接请求报文段后,如果同意,则发送连接同意报文。
B 在连接同意报文段中应使 SYN = 1 ,使 ACK = 1 其确认号ack = x + 1 ,自己随机选择一个序号seq = y
3. A 收到此报文后向 B 给出确认,其 ACK = 1 ,确认号 ack = y + 1,seq = x + 1。
A 的TCP通知上层应用进程,连接已经建立B 的 TCP 收到主机A的确认后,也通知其上层应用进程:TCP连接已经建立
为什么需要三次握手?
不是两次的主要原因使为了防止多次连接导致连接混乱。 比如A主机的网络较差,连续发送了多个连接请求,B收到请求后发送连接同意报文,但是B不知道A是否收到了同意连接请求,就只能重复同意,这些过期的请求可能回导致网络的混乱 设计成三次握手,客户端在接收到服务端的同意连接报文之后,就不需要再重复发送请求连接报文,并且第三次握手客户端会发送报文给服务端,告诉服务端我已经知道你同意连接了,就不需要再同意我重复发的其他请求。所以三次握手的原因就是避免多次建立重复连接,三次握手少了不能保证建立TCP连接成功,多了会造成资源浪费。
TCP 四次挥手
目的:释放 TCP 连接
流程:
-
数据传输结束后,通信双方都可以释放连接 现在假设 A 向 B 已经发送完数据,A 就可以发出连接释放报文段,并停止在发送数据,主动关闭 TCP 连接
-
B 收到后。发出确认,意思我收到了,从 A 到 B 这个方向的连接就释放了(此时 A 就不能再发送数据给 B 了),TCP 连接处于半关闭状态。B 若发送数据,A 仍需要接收
-
当 B 发送完数据后,就可以释放连接。B 发出的连接释放报文
-
A 收到连接释放报文后,必须发出确认。
为什么需要四次挥手:
TCP 是全双工通信,可以双向传输数据。任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了 TCP 连接。
举个例子:A 和 B 打电话,通话即将结束后。
-
第一次挥手 :A 说“我没啥要说的了”
-
第二次挥手 :B 回答“我知道了”,但是 B 可能还会有要说的话,A 不能要求 B 跟着自己的节奏结束通话
-
第三次挥手 :于是 B 可能又巴拉巴拉说了一通,最后 B 说“我说完了”
-
第四次挥手 :A 回答“知道了”,这样通话才算结束。
TCP 三次握手:用于建立连接
-
客户端向服务器发送 SYN 包
客户端发送一个 SYN 数据包给服务器,请求建立连接,其中包含一个随机生成的序列号 seq = x -
服务器回复 SYN-ACK 确认
服务器收到 SYN 包后,如果可以建立连接,就会回复一个 SYN-ACK 数据包,其中会包含一个随机生成的序列号 seq = y 和一个确认序列号 ack = x + 1,表示收到客户端的请求,并准备好接收数据 -
客户端发送 ACK 确认
客户端收到服务器的 SYN-ACK 后,会发送一个 ACK 数据包给服务器,其中会包含一个确认序列号 ack = y + 1,并且自己的序列号 seq = x + 1,表示确认收到,并准备发送数据
为什么需要三次握手?
三次握手为了客户端和服务端都能够确认对方的身份,并确保数据的发送和接收都正常。
-
防止服务端开启一些无用的连接增加服务端的开销
-
防止重复连接造成的连接错误
TCP 四次挥手:用于释放连接
-
客户端向服务器发送 FIN
当客户端不需要数据传输的时候,会向服务器发送一个 FIN 数据包,请求关闭连接 -
服务器回复 ACK 确认
服务器收到 FIN 包之后回复 ACK 数据包,表示同意关闭连接,但可能还有数据要传输,并不会立即关闭 -
服务器发送 FIN
当服务器也没有数据要传输的时候,会向发送客户端发送一个 FIN 数据包,表示也准备好关闭连接 -
客户端发送 ACK 确认
客户端收到 FIN 包之后回复 ACK 数据包,表示收到关闭请求,此时客户端处于 TIME-WAIT 状态,等待 2MSL(最大报文存活时间)后,若没有收到数据则说明服务端已关闭,自己也可以关闭连接了
为什么需要四次挥手?
四次挥手为了确保数据都能传输完成并正常关闭连接。任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,再发出连接释放通知,对方确认后就完全关闭了 TCP 连接。