# 三次握手的过程?以及为什么是三次而不是四次和两次
# 简要回答
- TCP的三次握手:(首先服务器要进入 LISTEN 状态,等待客户端的连接。)
- 第一次握手:
客户端随机生成初始序列号(如x),发送SYN = 1的连接请求报文段,并进入 SYN-SENT 状态,等待服务器确认。 - 第二次握手:
服务器在收到来自客户端发来的SYN报文后,随机生成自己的序列号(如y),并发送SYN = 1, ACK = 1的确认报文段,确认号为x + 1,之后服务器进入 SYN-RCVD 状态。 - 第三次握手:
客户端收到服务器发来的确认报文段后,再向服务器发送ACK = 1的确认报文段,确认号为y + 1;客户端发送完该报文段后,进入 ESTABLISHED 状态。当服务器接收到该报文段后,也进入 ESTABLISHED 状态,此时TCP连接建立成功。
- 第一次握手:
- 为什么是三次握手而不是两次或四次?
- 第三次握手的必要性:
防止已经失效的重复连接请求(例如网络延迟的冗余SYN报文)导致服务器误开无效连接。 - 为什么不能是两次握手:
两次握手无法防止历史SYN报文干扰,可能导致服务器资源浪费。 - 为什么不是四次握手:
三次握手已经能确保双方收发能力可靠,四次握手会增加额外延迟且无必要。
- 第三次握手的必要性:
# 详细回答
- TCP的三次握手:(首先服务器要进入 LISTEN 状态,等待客户端的连接。)
- 第一次握手(SYN):
Δ 客户端向服务器发送一个连接请求报文段,其中同步位SYN = 1,初始序号seq通常随机设置,记为x。
Δ 该请求报文不携带任何数据,即报文段的数据部分为空,但是仍然需要消耗掉一个序号(下次发送的报文的seq从x + 1开始)。
ΔSYN报文发送后,客户端进入 SYN-SENT 状态。 - 第二次握手(SYN-ACK):
Δ 服务器收到客户端发来的连接请求后,如果同意建立连接,则向客户端发送一个确认报文段,其中同步位SYN = 1,确认位ACK = 1。因为TCP提供全双工通信,服务器也可以向客户端发送数据,所以服务器也需要为自己随机设置一个初始序号seq,不妨记为y,而确认号ack =x + 1(表示来自客户端的编号在x之前的所有字节都已正确接收,现在服务器希望得到编号为x + 1的字节)。
Δ 和第一次握手的请求报文段类似,第二次握手的确认报文段不携带任何数据,即报文段的数据部分为空,但是仍然需要消耗掉一个序号。(下次发送的报文的seq从y + 1开始)
ΔSYN-ACK报文发送后,服务器进入 SYN-RCVD 状态。 - 第三次握手(ACK):
Δ 客户端收到服务器发来的确认报文段后,需要再向服务器发送确认报文段,其中确认位ACK = 1,序号seq =x + 1,确认号ack =y + 1(因为第二次握手时服务器的确认报文段占用了一个序号)。
Δ 第三次握手的确认报文段可以携带数据,也可以不携带数据。如果不携带数据,则不消耗序号(即TCP连接建立后,客户端发送的下一个请求报文的序号seq仍然为x + 1)。
Δ 客户端发送完ACK报文后,进入 ESTABLISHED 状态;当服务器接收到该报文段后,也进入 ESTABLISHED 状态;此时TCP连接建立成功,双方可以进行数据传输。
- 第一次握手(SYN):
- 为什么是三次握手而不是两次或四次?
- 第三次握手的必要性:
第三次握手可以防止已经失效的连接请求报文段突然又到达了TCP服务器端,而造成的服务器资源浪费。考虑这样一个场景:假如客户端发送的已经失效的SYN(因网络延迟)请求报文到达服务器,服务器会回复SYN-ACK确认报文。若只有两次握手,客户端会忽略此响应,但服务器认为连接已经成功建立,就会持续等待客户端发来数据,导致“半开连接”,浪费大量服务器资源。如果进行了第三次握手,服务器在发送确认报文段后还需要客户端进行确认,如果客户端未在时间限制内确认,服务器可以认为连接未建立成功,就不会继续占用资源。 - 为什么不能是两次握手:
① 两次握手时,服务器无法区分当前连接是否是延迟的旧请求。客户端可能已放弃连接,但服务器仍在等待数据,造成资源浪费。
② RFC 793(TCP协议标准文档)明确要求三次握手:只有三次交互能保证双方初始序列号(ISN)同步。 - 为什么不是四次握手:
三次握手已经能确保双方收发能力可靠,四次握手会增加额外延迟且无必要。
- 第三次握手的必要性:
# 知识图解
- TCP三次握手的示意图如下:

- TCP四次挥手的示意图如下:

# 知识拓展
- 为什么是三次握手(详细版本):
第三次握手可以防止已经失效的连接请求报文段(例如由于网络拥塞而超时的SYN报文)突然又到达了TCP服务器端,而造成的服务器资源浪费。假设 TCP 仅需两次握手即可建立连接,考虑如下场景——
① 客户端发送SYN报文,但由于网络拥塞,该报文滞留在了某个节点,导致服务器未能正确接收。
② 客户端在指定时间内没有收到来自服务器的SYN-ACK报文,触发超时重传机制,客户端因此重新发送了一个SYN报文给服务器。
③ 服务器成功收到了重传的SYN报文,并且此后的第二次握手正常进行,TCP连接成功建立;客户端和服务器通信结束后,TCP连接被释放。
④ 但是,此前由于网络拥塞而滞留的SYN报文在延误了一段时间后,达到了服务器端并被服务器正确接收。
⑤ 服务器认为客户端要建立新的连接,于是向客户端发送SYN-ACK报文。由于当前情景假设了TCP仅需两次握手即可建立连接,所以此时在服务器看来,TCP连接已经成功建立,服务器接下来会持续等待客户端发来数据。
⑥ 客户端收到服务器发来的SYN-ACK报文后,由于自己并没有主动发出连接请求,所以直接丢弃该确认报文。而服务器那边会一直等待客户端发送数据,这就造成大量服务器资源浪费。
如果进行了第三次握手,服务器在发送SYN-ACK报文后还需要客户端进行确认,如果客户端没有在限定时间内确认,服务器可以认为连接建立失败,就不会再继续占用资源了。 - 保活计时器:
因为TCP提供了全双工通信,所以在TCP连接建立后,客户端和服务器都可以随时向对方发送数据。为了避免服务器无效等待客户端(比如客户端故障),服务器每次收到来自客户端的数据后,都会重置保活计时器并计时。假如保活计时器计时期间,服务器始终未收到来自客户端的数据,那么当保活计时器即使周期结束之后,服务器就会每隔一定时间(75s)向客户端发送一次探测报文段。若连续发送 10个 探测报文段后,服务器还没有收到客户端的响应,则服务器端认为该客户端已经失去联系,就会关闭相关的TCP连接。
评论
验证登录状态...