三、TCP连接的释放(四次挥手、四报文挥手)
- 1)客户端发出连接释放报文段,终止控制位FIN=1,初始***seq=u,它等于前面已传送的数据的最后一个字节的序号加1。客户端进入FIN-WAIT-1状态。FIN报文段会消耗一个序号。
- 2)服务端收到请求,发出确认报文段,确认位ACK=1,确认号ack=u+1,初始***seq=v,它等于前面已传送的数据的最后一个字节的序号加1。服务端进入CLOSE-WAIT状态。客户端收到服务端的确认后,进入FIN-WAIT-2状态。TCP进入半关闭状态,客户端不会再发送数据;服务端还有数据没有传输完,得继续发送数据,客户端必须接收数据,所以下面的seq=w。
- 3)服务端发出连接释放报文段,终止控制位FIN=1,初始***seq=w,确认位ACK=1,确认号ack=u+1。服务端进入LAST-ACK状态。
- 4)客户端收到服务端的连接释放报文段后,发出确认。确认位ACK=1,初始***seq=u+1,确认号ack=w+1。客户端进入TIME-WAIT状态。服务端收到客户端的确认后,进入CLOSED状态,客户端等待2MSL(最长报文段寿命)后,进入CLOSED状态。
为什么要等待2MSL?
第一,为了保证客户端发送的最后一个确认报文段到达服务端。
第二,防止下一个新的连接,出现本次旧的连接请求。
建立连接中,客户端出现问题怎么办?
TCP有一个保活计时器,服务端每收到一次客户端的数据,就重新设置保活计时器,时间通常是2小时,超过这个时间没有收到客户端的请求,服务端就发送一个探测报文,每个75秒发送一次,发送10次无响应后,服务端认为客户端出了故障,连接关闭。