Four-Way Wavehand用来终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。
在socket编程中,这一过程由Client或Server任意一方执行close触发。
由于TCP连接是全双工的,因此每个方向上都必须单独进行关闭。上图描述如下:
我曾在《TCP三次握手原理详解》介绍过:当Client与Server双方通过三次握手建立连接后,双方均处于ESTABLISHED状态,此状态下双方可以进行正常的数据传送。
第一次挥手
Client发送一个FIN=1 (FIN:释放连接)及 一个序号seq = u,用来关闭 Client 到 Server 的数据传送,代表 Client 一侧不再有数据发送给 Server 了,但是还能接收数据。随即 Client 进入 FIN_WAIT_1 状态。
第二次挥手
Server 收到 FIN 后,知道 Client 一侧不再有数据发送过来,请求断开连接。Server 发送一个ACK给 Client ,确认序号 ack 为接收序号 +1, 并发送序号 seq = v.随即进入 CLOSE_WAIT状态。
第三次挥手
Server 发送一个 FIN,用来关闭 Server 到 Client 的数据传送, Server 进入 LAST_ACK 状态。从图中也可以看出,在二、三次挥手期间,Server 仍然可以给Client传输数据(先前 Client 申请断开连接的时候可能 Server 的数据还没有发送完,可在这时将剩余没有发送完的数据发送完毕)。
第四次挥手
Client 收到FIN后,Client 进入 TIME_WAIT 状态,接着发送一个ACK 给Server,确认序号ack为收到序号w 再+1,Server收到后进入CLOSED状态。
完成四次挥手,连接断开。以上主动方是Client,被动方是Server。如果主动方是Server,被动方是Client的话同理,角色交换一下即可。
上述过程用情景对话的形式来理解就是:
A:说完了吗?我要挂了。
B:还没,BlaBlaBla....
B:说完了。
A:挂了,拜拜。
为什么需要四次挥手?
是为了确保数据能够完整的传输。
当被动方收到主动方的FIN报文通知时,它仅仅表示主动方没有数据再发送给被动方了。
但未必被动方所有的数据都完整的发送给了主动方,所以被动方不会马上关闭SOCKET,它可能还需要再发送一些数据给主动方。
之后再发送FIN报文给主动方,告诉主动方被动方同意关闭连接,所以这里的ACK报文和FIN报文多数情况下是分开发送的。
小弟才疏学浅,这些只是在学习过程中所记录的笔记,难免有些错漏。如果哪里有问题,请在文后留言,大家一起学习进步,谢谢!