「TCP三握四挥」
来自 gpt 的摘要: 这篇文章解释了TCP协议中的三次握手和四次挥手,分别用于建立和断开可靠连接。三次握手确保客户端和服务端的收发能力正常,并通过同步序列号避免旧连接干扰。两次握手不足以防止历史连接的误触发,而四次握手则显得冗余。四次挥手则体现了TCP的全双工特性,允许双方独立决定何时结束数据传输,从而确保断开过程的完整性和安全性。
TCP 三次握手、四次挥手是什么?
三次握手
建立一个 TCP 连接需要“三次握手”,缺一不可:
一次握手:客户端发送带有 SYN(SEQ = x)标志的数据包 -> 服务端,然后客户端进入 SYN_SEND 状态,等待服务端的确认;
二次握手:服务端发送带有 SYN + ACK(SEQ = y,ACK = x + 1) 标志的数据包 –> 客户端,然后服务端进入 SYN_RECV 状态;
三次握手:客户端发送带有 ACK(ACK = y + 1) 标志的数据包 –> 服务端,然后客户端和服务端都进入ESTABLISHED 状态,完成 TCP 三次握手。
当建立了 3 次握手之后,客户端和服务端就可以传输数据了。
四次挥手
断开一个 TCP 连接则需要“四次挥手”,缺一不可:
第一次挥手:客户端发送一个 FIN(SEQ = x) 标志的数据包->服务端,用来关闭客户端到服务端的数据传送。然后客户端进入 FIN-WAIT-1 状态。
第二次挥手:服务端收到这个 FIN(SEQ = X) 标志的数据包,它发送一个 ACK (ACK = x + 1)标志的数据包->客户端。然后服务端进入 CLOSE-WAIT 状态,客户端进入 FIN-WAIT-2 状态。
第三次挥手:服务端发送一个 FIN(SEQ = y)标志的数据包->客户端,请求关闭连接,然后服务端进入 LAST-ACK 状态。
第四次挥手:客户端发送 ACK (ACK = y + 1)标志的数据包->服务端,然后客户端进入TIME-WAIT状态,服务端在收到 ACK(ACK = y + 1)标志的数据包后进入 CLOSE 状态。此时如果客户端等待 2MSL 后依然没有收到回复,就证明服务端已正常关闭,随后客户端也可以关闭连接了。
只要四次挥手没有结束,客户端和服务端就可以继续传输数据。
为什么要三次握手,可以设计成两次或四次吗?
为什么三次握手?
三次握手的目的是建立可靠的通信信道,说到通讯,简单来说就是数据的发送与接收,而三次握手最主要的目的就是双方确认自己与对方的发送与接收是正常的。
第一次握手:Client 什么都不能确认;Server 确认了对方发送正常,自己接收正常
第二次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:对方发送正常,自己接收正常
第三次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:自己发送、接收正常,对方发送、接收正常
三次握手就能确认双方收发功能都正常,缺一不可。
可以两次或四次吗?
TCP 建立连接时,通过三次握手能防止历史连接的建立,能减少双方不必要的资源开销,能帮助双方同步初始化序列号。序列号能够保证数据包不重复、不丢弃和按序传输。
不使用「两次握手」和「四次握手」的原因:
「两次握手」:无法防止历史连接的建立,会造成双方资源的浪费,也无法可靠的同步双方序列号;
「四次握手」:三次握手就已经理论上最少可靠连接建立,所以不需要使用更多的通信次数。
为什么要四次挥手?
为什么四次挥手?
TCP 是全双工通信,可以双向传输数据。任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了 TCP 连接。
举个例子:A 和 B 打电话,通话即将结束后。
第一次挥手:A 说“我没啥要说的了”
第二次挥手:B 回答“我知道了”,但是 B 可能还会有要说的话,A 不能要求 B 跟着自己的节奏结束通话
第三次挥手:于是 B 可能又巴拉巴拉说了一通,最后 B 说“我说完了”
第四次挥手:A 回答“知道了”,这样通话才算结束。
