当客户端和服务端通过三次握手建立了 tcp 连接以后,当数据传送完毕,断开连接就需要进行tcp的四次挥手。
断开一个tcp连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在socket编程中,这一过程由客户端或服务端任一方执行close来触发。
由于tcp连接是全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个fin来终止这一方向的连接,收到一个fin只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个tcp连接上仍然能够发送数据,直到这一方向也发送了fin。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭。
中断连接端可以是客户端,也可以是服务器端。
第一次挥手: 主机1(可以使客户端,也可以是服务器端),设置sequence number,向主机2发送一个fin报文段;此时,主机1进入fin_wait_1状态;这表示主机1没有数据要发送给主机2了;
第二次挥手: 主机2收到了主机1发送的fin报文段,向主机1回一个ack报文段,acknowledgment number为sequence number加1;主机1进入fin_wait_2状态;主机2告诉主机1,我“同意”你的关闭请求;
第三次挥手: 主机2向主机1发送fin报文段,请求关闭连接,同时主机2进入last_ack状态;
第四次挥手: 主机1收到主机2发送的fin报文段,向主机2发送ack报文段,然后主机1进入time_wait状态;主机2收到主机1的ack报文段以后,就关闭连接;此时,主机1等待2msl后依然没有收到回复,则证明server端已正常关闭,那好,主机1也可以关闭连接了。
最后再看一下完整的过程:
如果有大量的连接,每次在连接,关闭都要经历三次握手,四次挥手,这显然会造成性能低下。因此。http 有一种叫做 长连接(keepalive connections) 的机制。它可以在传输数据后仍保持连接,当客户端需要再次获取数据时,直接使用刚刚空闲下来的连接而无需再次握手。
为什么tcp连接的时候是三次握手,关闭的时候tcp为什么要四次挥手