TCP的关闭连接比TCP连接的建立稍微复杂一些,下面我把个人的学习和理解写下来分享。
(参考《计算机网络》,第6版,谢希仁著)。
1、TCP关闭连接的步骤
假设现有客户端A和服务端B,客户端A向服务端B发出关闭连接请求。
步骤一:客户端A主动向服务端B发送请求关闭连接报文段,FIN=1,seq=u,并进入FIN-WAIT-1状态,
步骤二:服务端B接受到客户端A的请求之后返回一个确认报文段,ACK=1,ack=u+1,seq=v进入到CLOSE-WAIT状态,并通知应用程序在传送完剩余数据之后关闭连接,
步骤三:客户端A接受到服务端B的确认报文段之后就进入FIN-WAIT-2状态,
步骤四:当服务端B的剩余数据传送完毕之后服务端B被动关闭连接,即向客户端A发送关闭连接报文段,FIN=1,ACK=1,seq=w(因为之间可能传送了一些数据消耗了一些序列号),ack=u+1,并进入到LAST-ACK状态,
步骤五:当客户端A接收到B的关闭连接报文段之后便返回一个确认报文段,ACK=1,ack=w+1,seq=u+1,并进入到TIME-WAIT状态(持续2MSL时间),
步骤六:当服务端B接收到A的确认报文段之后便进入到CLOSED状态,表示B到A这个方向的连接已关闭,
步骤七:客户端A在经历2MSL时间之后,没有接收到服务端B的超时重传的话便进入CLOSED状态,如果收到B的超时重传的报文,就重新发送确认报文段,并重新计算2MSL时间,直到2MSL时间过了。这时候TCP连接便完全关闭 了。
图解如下
2、TCP四次挥手的详细信息
下面通过抓包软件wireshark来查看TCP关闭连接时的步骤和报文段的详细信息
先交代背景
客户端IP:14.215.177.38
服务端IP:192.168.1.3
从wireshark中看TCP断开连接时的信息如下
NO.10829 客户端A向服务端B发送的请求关闭连接的报文段,此时TCP报文首部详细信息如下图
从上图可以看出 FIN=1,seq=4655,但是这里有个疑问,为什么ACK=1?后来通过去查看之前的其他包发现是对之前已经接收到的数据包的字节流进行确认
NO.10830是服务端B收到客户端的请求关闭连接的报文段之后返回的确认报文段,此时TCP报文首部详细信息如下图
从上图可以看出,ACK=1,seq=30939,ack=4656(前一个报文段的seq+1)
NO.10831是服务端B在传送玩剩下的数据之后被动关闭连接发出的报文段,此时TCP报文首部详细信息如下图
从上图可以看出FIN=1,ACK=1,seq=30939,ack=4656(跟前一个报文段一样)
NO.10832是客户端A在接收到服务端B的关闭连接报文段后返回的确认报文段,此时TCP的报文首部详细信息如下图
从上图可以看出ACK=1,seq=4656,ack=30940
3、第四次挥手后客户端A等待2MSL原因
1.确保服务端B能够收到客户端A的确认报文段
2.防止“已失效的连接请求报文段”出现下一个连接中