【注意】中断链接端能够是Client端,也能够是Server端。服务器
图3—Client端主动发起关闭链接请求网络
1. 假设Client端主动发起中断链接请求,也就是发送FIN报文。tcp
2. Server端接到FIN报文后,意思是说"我Client端没有数据要发给你了",可是若是你还有数据没有发送完成,则没必要急着关闭Socket,能够继续发送数据。因此你先发送ACK,"告诉Client端,你的请求我收到了,可是我还没准备好,请继续你等个人消息"。这个时候Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文。此时Server端进入ClOSE_WAIT状态。3d
3当Server端肯定数据已发送完成,则向Client端发送FIN报文,"告诉Client端,好了,我这边数据发完了,准备好关闭链接了"。blog
4.Client端收到FIN报文后,"就知道能够关闭链接了,可是他仍是不相信网络,怕Server端不知道要关闭,因此Client端发送ACK后进入TIME_WAIT状态,若是Server端没有收到ACK则能够重传。“,Server端收到ACK后,"就知道能够断开链接了"。Client端等待了2MSL后依然没有收到回复,则证实Server端已正常关闭,那好,我Client端也能够关闭链接了。Ok,TCP链接就这样关闭了!awk
【问题1】为何TIME_WAIT状态须要通过2MSL(最大报文段生存时间)才能返回到CLOSE状态?请求
答:虽然按道理,四个报文都发送完毕,咱们能够直接进入CLOSE状态了,可是咱们必须假象网络是不可靠的,有可能最后一个ACK丢失。因此TIME_WAIT状态就是用来重发可能丢失的ACK报文。im
为何是2MSL,主要是为了考虑到若是最后一个ACK丢失,服务端会从新发FIN,客户端等待2MSL,才能接收到服务端从新发送的FIN报文。d3
在服务器的平常维护过程当中,会常常用到下面的命令:通信
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
它会显示例以下面的信息:
TIME_WAIT 814
CLOSE_WAIT 1
FIN_WAIT1 1
ESTABLISHED 634
SYN_RECV 2
LAST_ACK 1
经常使用的三个状态是:ESTABLISHED 表示正在通讯,TIME_WAIT 表示主动关闭,CLOSE_WAIT 表示被动关闭。