TCP的三次握手、四次挥手

TCP的三次握手、四次挥手
最新回答
你长了一张欠吻的嘴

2026-04-11 09:49:42

TCP的三次握手与四次挥手

TCP的三次握手

TCP的三次握手是在发送数据前通过三次交互建立起通信连接,目的是让源端和目的端确认双方的发送报文能力和接收报文能力是正常的。具体过程如下:

  • 第一次握手:Client端将SYN置为1,表示希望与Server端建立连接;序号seq初始化为J(随机生成),并将该数据包发送给Server端。Client进入SYN_SENT状态,等待Server确认。

  • 第二次握手:Server端收到报文后,检查SYN为1,知道Client端想建立连接。于是Server端也将SYN置为1,表示希望与Client端建立连接;同时,Server端将ACK置为1,表示收到了Client端的请求;Server端将seq初始化为K(随机生成),并将ack置为J+1(ack=seq+1,表示期望收到的下一个报文段的序号)。Server端发送这个报文后,进入SYN_RCVD状态。

  • 第三次握手:Client端收到Server端的报文后,检查ack是否为J+1,ACK是否为1。如果正确,Client端将标志位ACK置为1,ack=K+1,并将该数据包发送给Server端。Server端检查ack是否为K+1,ACK是否为1。如果正确,则双方连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后可以开始传输数据。

TCP的四次挥手

TCP的四次挥手是断开TCP连接的过程,即客户端和服务端总共要收发4个包才能确定断开连接。具体过程如下:

  • 第一次挥手:假设客户端主动发起断开请求,客户端向服务端发送报文,报文首部包括FIN=1,表示客户端想要断开连接;序列号seq=u。此时客户端进入FIN-WAIT-1状态,停止发送数据,并等待服务端的确认。

  • 第二次挥手:服务端收到客户端的报文后,发出确认报文。控制位ACK=1,确认号ack=u+1,序列号seq=v。然后服务端进入CLOSE-WAIT状态,告知上层应用进程连接即将关闭,让应用程序做好相应准备。此时客户端已经没有数据向服务端发送,但服务端向客户端发送数据,客户端依然能接收。

  • 第三次挥手:服务端数据发送完毕后,向客户端发送断开连接请求。报文首部控制位FIN=1,ACK=1,确认序号ack=u+1,序号seq=w。然后服务端进入LAST-ACK状态,等待客户端确认。

  • 第四次挥手:客户端收到服务端的断开连接报文后,必须发出确认报文。标志位ACK=1,确认号ack=w+1,序号seq=u+1。之后客户端进入TIME-WAIT状态,等待2*MSL(最长报文段寿命)的时间后才进入CLOSED状态关闭连接。而服务端只要收到了客户端的确认报文后,就会进入CLOSED状态关闭连接。

TIME_WAIT状态的原因:

  • 客户端发送给服务端的回执报文可能在传输途中丢失,服务端没有收到。此时服务端会再次向客户端发送FIN=1的断开请求报文。如果客户端没有等待2*MSL时间而直接进入了CLOSED状态,就会收不到服务端的断开连接请求报文,导致服务端无法进入CLOSED状态。
  • 等待一段时间是为了让本连接持续时间内所产生的所有报文都从网络中消失,避免下一个新的连接出现旧的连接请求报文。

为什么是四次挥手而不是三次或五次:

  • 如果是三次挥手,即将服务端向客户端发送报文的第二次挥手和第三次挥手合为一次,会造成服务端发送了回执后立刻又发送断开请求,导致服务端有数据没有全部发送至客户端。因此,必须将第二次挥手和第三次挥手分开。
  • 五次挥手则完全没必要,多此一举。第二次挥手和第三次挥手分别代表了服务端收到客户端断开请求后的确认,以及服务端数据发送完毕后的断开请求,这两个过程是分开的,不能合并,也不需要再增加额外的挥手过程。