传输层 TCP连接管理 释放连接四次握手

A计算机传输完了数据,传完之后要发出释放连接的数据包,这个TCP的FIN标记位为1,序号为u,B收到之后就通知应用程序A发完了,A不给B发了,B收到之后给它发送确认,确认号是u+1,序号是v,确认标记位为1。

在发送了关闭连接的请求之后,A状态就变为了FIN-WAIT-1,B发送确认之后变为CLOSE-WAIT,变成了关闭并且等待。现在A不能向B发送数据的,但是B可以向A发送数据,B发送释放连接的请求,这个时候FIN标记位为1,确认号还是u+1,然后序号是w,A收到并且确认号是w+1。然后B就close了,关闭连接了。

关闭连接之后还得等一段时间

,time-wait,这个时间时间是几分钟,为啥还要等,是因为万一这个包在路上丢了怎么办?如果丢了,还需要再发一遍释放连接的请求,所以这边还需要等一段时间。如果发送释放连接的请求,如果没有time-wait等待了,那么A就搭理B了。

释放连接需要4个数据包。

-----------------------------------------------------------------------------------------------------------------------------

第一次挥手:A 的应用进程先向其 TCP 发出连接释放报文段,并停止再发送数据,主动关闭 TCP 连接。A 把连接释放报文段首部的终止控制位 FIN 置 1,其序号 seq = u(等于前面已传送过的数据的最后一个字节的序号加 1),这时 A 进入 FIN-WAIT-1(终止等待1)状态,等待 B 的确认。请注意:TCP 规定,FIN 报文段即使不携带数据,也将消耗掉一个序号。

第二次挥手:B 收到连接释放报文段后立即发出确认,确认号是 ack = u + 1,而这个报文段自己的序号是 v(等于 B 前面已经传送过的数据的最后一个字节的序号加1),然后 B 就进入 CLOSE-WAIT(关闭等待)状态。TCP 服务端进程这时应通知高层应用进程,因而从 A 到 B 这个方向的连接就释放了,这时的 TCP 连接处于半关闭(half-close)状态,即 A 已经没有数据要发送了,但 B 若发送数据,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(前面发送的 FIN 报文段要消耗一个序号)。然后进入 TIME-WAIT(时间等待) 状态。请注意,现在 TCP 连接还没有释放掉。必须经过时间等待计时器设置的时间 2MSL(MSL:最长报文段寿命)后,A 才能进入到 CLOSED 状态,然后撤销传输控制块,结束这次 TCP 连接当然如果 B 一收到 A 的确认就进入 CLOSED 状态,然后撤销传输控制块。所以在释放连接时,B 结束 TCP 连接的时间要早于 A。



CLOSE-WAIT和TIME-WAIT存在的意义?


- Close-wait存在的意义: 就是服务端还有数据要发送,这个时间内就是服务端发送完最后的数据

- Time-wait存在的意义:
    - 第一,这里同样是要考虑丢包的问题,如果第四次挥手的报文丢失,服务端没收到确认ack报文就会重发第三次挥手的报文,这样报文一去一回最长时间就是2MSL,所以需要等这么长时间来确认服务端确实已经收到了
    - 第二,防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。

关于 time_wait:

1.TCP 连接建立后,「主动关闭连接」的一端,收到对方的 FIN 请求后,发送 ACK 响应,会处于 time_wait 状态

2.time_wait 状态,存在的必要性:

a、可靠的实现 TCP 全双工连接的终止:四次挥手关闭 TCP 连接过程中,最后的 ACK 是由「主动关闭连接」的一端发出的,如果这个 ACK 丢失,则对方会重发 FIN 请求,因此,在「主动关闭连接」的一段,需要维护一个 time_wait 状态,处理对方重发的 FIN 请求。(time_wait这方发送的ack可能丢失,所以得处理重发的FIN)

b、处理延迟到达的报文:由于路由器可能抖动,TCP 报文会延迟到达,为了避免「延迟到达的 TCP 报文」被误认为是「新 TCP 连接」的数据,则,需要在允许新创建 TCP 连接之前,保持一个不可用的状态,等待所有延迟报文的消失,一般设置为 2 倍的 MSL(报文的最大生存时间),解决「延迟达到的 TCP 报文」问题。

关闭连接:防止数据丢失;与应用层交互


• FIN:结束

• ACK:确认

关闭连接是有两个目的,第一,必须防止数据丢失,第二我们与应用层是有交互的。

首先client和server都是处于establish的状态,由我们的client首先发起关闭连接,它是主动关闭连接的一方,首先它会发送报文,报文当中flag标志位中的FIN标志位1,发送完FIN以后,它就进入到FIN-WAIT-1状态,可以通过netstat端口的状态进入了FIN-WIAT-1,服务器接收到FIN以后,在操作系统的内核层会自动的回一个ACK,此时server端netstat就可以看到CLOSE-WAIT的状态,而server端发送来的ACK在client接受之后自动会从FIN-WAIT-1进入到FIN-WAIT-2状态,要注意到无论是FIN还是ACK都依然符合前面所说的重发确认等流程。

当server端进入到CLOSE-WAIT状态之后,如果server上面的app,它没有去处理这样一个事件,这样连接的状态永远都在CLOSE-WAIT状态。

当有些web应用出现bug的时候,那么就可以使用netstat就可以观察到CLOSE-WIAT状态。

当APP通过read函数接收到0的时候,他就知道应该去关闭这个连接了,当它调用了close的socket之后,我们的server就会发一个FIN包给到client,当server发完FIN包之后,server状态就会进入到LAST-ACK,而这个FIN包到达主动关闭连接的client端之后,这个时候在client端就会进入TIME-WAIT阶段,这在服务器经常可以看到的一个状态,这是服务器主动在关闭连接。

当主动关闭连接的client收到FIN之后就会回一个ACK,会ACK,server收到ACK之后就会进入close状态,而client发送完ACK之后,它要等两个MSL的时间,也就是TCP报文段在整个网络当中那个存活的最长时间,TIME-WAIT经过两个MSL的时间也会进入close的状态。

在456这个报文当中由172.11发起了关闭连接,在FIN控制位标记为1,说明是在关闭连接,此时172.11在关闭连接就会进入FIN-WAIT1状态,

 再来看看457这个报文,也就是65.15,也就是浏览器端,收到对方发来的FIN,那么回一个ACK,此时65.15就会进入CLOSE-WAIT状态,等待浏览器去调用close socket方法,ACK到达172.11之后就会进入FIN-WAIT-2状态。

当浏览器执行了close socket之后,就由close-wait变为last-ack状态。

当fin到达172.11之后,他就会从fin-wait2变为time-wait状态,它同时发送最后一个ack,65.15收到ack之后就会从last-ack置为close的状态。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值