在网络通信的世界里,数据的准确传输至关重要。TCP 协议作为保障数据可靠传输的关键,其三次握手机制更是起着核心作用。
什么是 TCP 三次握手?
TCP,即传输控制协议(Transmission Control Protocol),它是一种面向连接的、可靠的、基于字节流的传输层通信协议。在进行数据传输之前,发送方和接收方需要先建立连接,而这个建立连接的过程,就是通过三次握手来完成的。简单来说,三次握手就像是两个朋友在正式交谈之前,先互相确认对方是否准备好、能否正常沟通一样。
三次握手的详细过程
为了更好地理解,我们假设客户端(Client)和服务器(Server)要建立连接。
第一次握手
客户端将标志位 SYN 置为 1,随机产生一个值 seq = J,并将该数据包发送给服务器,此时客户端进入 SYN_SEND 状态,开始等待服务器的确认。
第二次握手
服务器收到客户端发来的数据包后,通过标志位 SYN = 1 知道客户端请求建立连接。服务器将标志位 SYN 和 ACK 都置为 1,ack = J + 1(这里的 ack 是对客户端序号 J 的确认,J + 1 表示期望客户端下次发送数据的序号),然后服务器自己也随机产生一个值 seq = K,并将这个数据包发给客户端以确认连接请求,此时服务器进入 SYN_RECV 状态。
第三次握手
客户端收到服务器的确认数据包后,会检测 ack 是否为 J + 1,ACK 是否为 1。如果这些都正确,客户端就将标志位 ACK 置为 1,ack = K + 1(这是对服务器序号 K 的确认),并将该数据包发送给服务器。完成这第三次握手后,客户端与服务器就进入了 ESTABLISHED 状态,随后它们之间就可以开始愉快地传输数据了。
为什么需要三次握手?两次不行吗?
你可能会好奇,为什么建立连接非得要三次握手,两次难道不行吗?其实,两次握手确实存在一些问题。
假如只进行两次握手,客户端发送连接请求后,会等待服务器端的应答。但是可能会出现这样的情况:假如客户端的 SYN 数据包因为网络延迟等原因,迟迟没有到达服务器端,此时客户端超时后,会重新发送一次连接请求。假如重发的这次服务器端收到了,且应答客户端了,连接就建立了。然而,建立连接后,之前延迟的第一个 SYN 数据包也到达服务端了,这时服务端会认为这是一个新的连接请求,会再给客户端发送一个 ACK。但这个 ACK 会被客户端丢弃,因为客户端已经建立了连接。可是服务器端却已经为这个 “误以为” 的新连接分配了资源,而且服务器端会一直维持着这个资源,这样就造成了资源的浪费。
两次握手的问题关键在于服务器端无法判断 SYN 的有效性。而三次握手就不一样了,服务器端会等待客户端的第三次握手,如果第三次握手迟迟不来,服务器端就会释放之前为这个连接分配的相关资源,避免了资源的浪费。