连接释放(四报文握手)
Last updated
Last updated
数据传输结束后,通信的双方都可释放连接。现在 A 和 B 都处于 ESTABLISHED 状态。
A 的应用进程先向其 TCP 发出连接释放报文段,并停止再发送数据,主动关闭 TCP 连接。A 把连接释放报文段首部的终止控制位 FIN 置 1,其序号 seq=u,它等于前面已传送过的数据的最后一个字节的序号加 1。这时 A 进入 FIN-WAIT-1(终止等待 1)状态,等待 B 的确认。
B 收到连接释放报文段后即发出确认,确认号是 ack=u+1,而这个报文段自己的序号是 v,等于 B 前面已传送过的数据的最后一个字节的序号加 1。然后 B 就进入 CLOSE-WAIT(关闭等待)状态。
这时从 A 到 B 这个方向的连接就释放了,这时的 TCP 连接处于半关闭 (half-close)状态,即 A 已经没有数据要发送了,但 B 若发送数据,A 仍要接收。
A 收到来自 B 的确认后,就进入 FIN-WAIT-2(终止等待 2)状态,等待 B 发出的连接释放报文段。
若 B 已经没有要向 A 发送的数据,其应用进程就通知 TCP 释放连接。这时 B 发出的连接释放报文段必须使 FIN=1。现假定 B 的序号为 w(在半关闭状态中 B 可能又发送了一些数据)。B 还必须重复上次已发送过的确认号 ack=u+1。这时 B 就进入 LAST-ACK(最后确认)状态,等待 A 的确认。
A 在收到 B 的连接释放报文段后,必须对此发出确认。在确认报文段中把 ACK 置 1,确认号 ack=w+1,而自己的序号是 seq=u+1 。然后进入到 TIME-WAIT(时间等待)状态。
现在 TCP 连接还没有释放掉。必须经过时间等待计时器(TIME-WAIT timer)设置的时间 2 MSL后,A 才进入到 CLOSED 状态。
时间 MSL 叫做最长报文段寿命 (Maximum Segment Lifetime)。
B 只要收到了 A 发出的确认,就进入 CLOSED 状态。
保活计时器 (keepalive timer)
除时间等待计时器外,TCP 还设有一个保活计时器 (keepalive timer)。设想有这样的情况:客户已主动与服务器建立了 TCP 连接。但后来客户端的主机突然出故障。显然,服务器以后就不能再收到客户发来的数据。因此,应当有措施使服务器不要再白白等待下去。这就是使用保活计时器。
服务器每收到一次客户的数据,就重新设置保活计时器,时间的设置通常是两小时。若两小时没有收到客户的数据,服务器就发送一个探测报文段,以后则每隔 75 秒钟发送一次。若一连发送 10 个探测报文段后仍无客户的响应,服务器就认为客户端出了故障,接着就关闭这个连接。