一、TCP通过“四报文挥手”来释放连接
    1、TCP客户机发送TCP连接释放报文。报文段的终止位FIN被设置为1,确认位ACK设置为1,表明这是一个TCP释放报文,同时对之前收到的报文进行确认,序号字段seq的值设置为u,等于客户端进程之前已传送过的数据的最后一个字节的序号加1,确认号ack设置为v,等于TCP客户进程之前已收到的数据的最后一个字节的序号加1,同时TCP客户机进入FIN-WAIT-1终止等待1状态
    2、TCP服务器收到TCP连接释放报文后,向TCP客户机发送普通确认报文。报文的确认位ACK设置为1,表明这是一个TCP普通确认报文,序号字段seq设置为v,等于TCP服务器进程之前已传送过的数据的最后一个字节的序号+1,与收到的释放报文的ack字段匹配,确认号ack设置为u+1,这是对TCP连接释放报文seq段的确认,同时TCP服务器进入CLOSE-WAIT关闭等待状态,并通知高层的应用进程,表示TCP客户机要断开与自己的连接,此时从TCP客户机到TCP服务器方向的连接就释放了,TCP连接处于半关闭状态,TCP客户机已经没有数据要发送了,但TCP服务器如果还有数据要发送,TCP客户机仍要接收。
    3、若TCP服务器应用进程已经没有数据要发送了,则通知TCP发送TCP连接释放报文关闭TCP连接。报文的终止位FIN设置为1,确认位ACK设置为1,序号字段seq设置为w,这是因为在半关闭状态下,TCP服务器又发送了一些数据,确认号ack设置为u+1,这是对之前收到的TCP连接释放报文段的重复确认。TCP服务器进入LAST-ACK最后确认状态。
    4、TCP客户机收到TCP服务器发来的TCP释放报文后,向TCP服务器发送TCP普通确认报文。报文的确认位ACK设置为1,表明这是一个普通确认报文,序号字段seq设置为u+1,表示要消耗掉一个序号,确认号字段ack设置为w+1,这是对之前收到的TCP服务器发来的TCP释放报文段的确认。TCP客户机进入TIME-WAIT时间等待状态。TCP服务器进程收到该报文后就进入连接关闭状态,而TCP客户机进程还要经过2MSL后才能进入关闭状态,MSL意思是最长报文段寿命,RFC793建议为2分钟,即TCP客户机还需要等待4分钟才能进入关闭状态。TCP允许不同的实现根据具体情况使用更小的MSL值。
    image.png
    5、若TCP客户机收到TCP服务器发送的TCP连接释放报文,再发送TCP普通确认报文后直接进入关闭状态,则一旦TCP普通确认报文在网络中丢失了,则TCP服务器将一直处于连接关闭的最后确认状态,并不断超时重传TCP连接释放报文,从而始终不能进入关闭状态。
    image.png

    二、TCP保活计时器
    1、TCP服务器进程每收到一次TCP客户进程的数据,就重新设置并启动保活计时器(2小时定时)
    2、若保活计时器定时周期内未收到TCP客户进程发来的数据,则当保活计时器到时候,TCP服务器进程就向TCP客户进程发送一个探测报文段,以后则每隔75秒发送一次。若一连10个探测报文段后仍然无TCP客户进程的响应,TCP服务器进程就认为TCP客户进程所在主机出现了故障,接着就关闭这个连接。