TCP连接释放

四报文挥手释放TCP连接
挥手需要再TCP客户与服务器之间交换四个报文段
客户和服务器都可以发起释放TCP连接
第一次挥手
TCP 客户进程主动关闭 TCP 连接,发送 TCP 连接释放报文段并进入终止等待 1 状态.
- TCP连接释放报文段首部中的终止标志位 FIN 和确认标志位ACK的值都被设置为 1。
- 表明这是一个TCP连接释放报文段,同时也对之前收到的TCP报文段进行确认。
- 序号seq字段的值设置为u,它等于TCP客户进程之前已经传送过的数据的最后一个字节的序号加1。
- TCP规定终止标志位FIN等于1的TCP报文段即使不携带数据,也要消耗掉一个序号。
- 确认号ack字段的值设置为v,它等于TCP客户进程之前已收到的数据的最后一个字节的序号加1
IMPORTANT
第二次挥手
TCP服务器收到该连接释放报文段后,发送TCP普通确认报文段并进入关闭等待状态
- 确认标志位 ACK 的值被设置为 1,表明这是一个 TCP 普通确认报文段。
- 序号 seq 字段的值设置为 v,它等于 TCP 服务器进程之前已传送过的数据的最后一个字节的序号加 1。 这也与之前收到的 TCP 连接释放报文段中的确认号 v 匹配。
- 确认号 ack 字段的值设置为 u+1,这是对 TCP 连接释放报文段的确认
- TCP 服务进程应通知高层应用进程,TCP 客户进程要断开与自己的 TCP 连接(这时,从客户进程到 TCP 服务进程这个方向的连接就释放了)

- TCP客户进程已经没有数据要发送了。但TCP服务器进程如果还有数据要发送,TCP客户进程仍要接收,也就是从TCP服务器进程到TCP客户进程这个方向的连接并未关闭。
- 半关闭状态可能会持续一段时间
TCP 客户端收到该 TCP 普通确认报文段后,进入终止等待 2 状态,等待 TCP 服务器进程发出的 TCP 连接释放报文段。
第三次挥手

TCP 服务器进程被动关闭 TCP 连接,发送 TCP 连接释放报文段并进入最后确认状态。
- TCP 连接释放报文段首部中的终止标志位 FIN 和确认标志位 ACK 的值都被设置为 1。 表明这是一个 TCP 连接释放报文段,同时也对之前收到的 TCP 报文段进行确认。
- 序号 seq 字段的值假定被设置为 w,这是因为在半关闭状态下 TCP 服务器进程可能又发送了一些数据。
- 确认号 ack 字段的值被设置为 u+1,这是对之前收到的 TCP 连接释放报文段的重复确认。
第四次挥手
TCP 客户收到该连接释放报文段后,发送 TCP 普通确认报文段并进入时间等待状态

- 确认标志位 ACK 的值设置为 1,表明这是一个 TCP 普通确认报文段。
- 序号 seq 字段的值设置为 u+1,这是因为 TCP 客户进程之前发送的 TCP 连接释放报文段虽然不携带数据,但要消耗掉一个序号。
- 确认号 ack 字段的值设置为 w+1,这是对所收到的 TCP 连接释放报文段的确认。
客户和服务器关闭
TCP 服务器收到该 TCP 普通确认报文段后,就进入关闭状态,撤销相应的传输控制块 TCB
TCP 客户进程还要等待 2MSL 时间才能进入关闭状态
MSL-最长报文段寿命
MSL 是最长报文段寿命(Maximum Segment Lifetime)的英文缩写词, [RFC793] 建议为 2 分钟。也就是说,TCP 客户进程进入时间等待(TIME-WAIT)状态后,还要经过 4 分钟才能进入关闭(CLOSED)状态。
TCP客户关闭为什么需要等待
若该报文段丢失后(第四个报文),必然会使服务器对之前的报文段重传, 当重传时,若 client 处于关闭,将会造成 server 返回重传,一直处于无法关闭;

防止client主机故障
Q:当 clent 故障时,TCP 服务器将不在收到客户端发来的数据,服务器应如何察觉到该状况?
A:服务器使用保活计时器,每收到 client 的数据就重新设置并启动保活计时器(2 小时),若定期内没有收到,则向 clent 每隔 75s 发送以此探测报文,连发 10 个,若无响应,即关闭该连接;
