TCP四次挥手原理及抓包情况 下载本文

一 TCP四次挥手原理及抓包情况

TCP的连接的拆除需要发送四个包,因此称为四次挥手(four-way handshake)。客户端或服务器均可主动发起挥手动作,在socket编程中,任何一方执行close()操作即可产生挥手操作,如图1所示。

图1 四次挥手原理图

第一次挥手:主动方发送一个FIN,用来关闭主动方到被动方的数据传送;

第二次挥手:被动方收到这个FIN,它发回一个ACK,确认序号为收到的序号加1,和SYN一样,一个FIN将占用一个序号;

第三次挥手:被动方关闭与主动方的连接,发送一个FIN给主动方;

第四次挥手:主动方发回ACK报文确认,并将确认序号设置为收到序号加1;被动方关闭连接

通俗说就是

主动方对被动方说:我不爱你了,咱们离婚吧!--------------->(FIN_WAIT_1状态,等待回应) 被动方回应:那离婚吧,把你的东西都拿走! --------------->(FIN_WAIT_2状态,在关闭连接前将最后一点数据传完) 被动方又说:咱们来个Kiss Goodbye吧! --------------->( LAST_ACK,关闭连接,并请求最后一次确认)

主动方回应:波儿~ --------------> (CLOSED,完毕)

图2 WIRESHARK抓包情况

二 思考题

2.1 、为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?

这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的建连请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。如图3所示:

图3 四次握手的关键点

2.2、为什么TIME_WAIT状态还需要等2MSL后才能返回到CLOSED状态?

这是因为虽然双方都同意关闭连接了,而且握手的4个报文也都协调和发送完毕,按理可以直接回到CLOSED状态(就好比从SYN_SEND状态到ESTABLISH状态那样);但是因为我们必须要假想网络是不可靠的,你无法保证你最后发送的ACK报文会一定被对方收到,因此对方处于LAST_ACK状态下的SOCKET可能会因为超时未收到ACK报文,而重发FIN报文,所以这个TIME_WAIT状态的作用就是用来重发可能丢失的ACK报文。