TCP—释放连接
四次挥手
状态解读
FIN-WAIT-1:表示想主动关闭连接
- 向对方发送FIN报文,此时进入FIN-WAIT-1状态
CLOSE-WAIT:表示在等待关闭
- 当对方发送FIN给自己,自己会回应ACK报文给对方,此时则进入CLOSE-WAIT状态
- 在这个状态下,需要考虑自己是否还有数据要发送给对方,如果没有,发送FIN报文给对方
FIN-WAIT-2:只要对方发送ACK确认后,主动就会处于FIN-WAIT-2状态,然后等待对方发送FIN报文
CLOSING:一种比较罕见的例外状态
- 表示你发送FIN报文后,并没有收到ACK的报文,反而却也收到了对方的FIN报文
- 如果双方几乎在同时准备关闭连接的话,那么就发现双方同时发送FIN报文情况,也即是出现CLOSING状态
LAST-ACK:被动关闭一方在发送FIN报文后,最后等待对方的ACK报文
- 当收到ACK报文后,即可进入CLOSED
TIME-WAIT:表示收到了对方的FIN报文,并发送出ACK报文,等2MSL后即可CLOSED状态
FIN:finish完成,关闭连接
为什么释放连接的时候,要进行4次挥手?
TCP是全双工模式
第一次挥手:当主机1发出FIN报文段时
-
表示主机1告诉主机2,主机1已经没有数据要发送了,但是,此时主机1可以接受主机2的数据
第二次挥手:主机2返回ACK报文段时
- 表示主机2已经知道主机1没有数据发送了,但主机2还是可以发送数据1
第三次挥手:当主机2也发送了FIN报文段时
- 表示主机2告诉主机1,主机2已经没有数据要发送了
第四次挥手:
表示主机1已经知道主机2没有数据发送了,随后1正式断开整个TCP连接
细节
-
TCP/IP协议栈设计上,允许任何一方先发起断开请求。
-
client发送ACK后,需要有个TIME-WAIT阶段,等待一段时间后,再真正关闭连接
一般等待2倍的MSL(Maximum segment lifetime 最大分段生存期)
每个具体的TCP都必须选择一个确定的MSL值,REC_1122建议是2分钟
why?
如果client马上发送ACK确认码可能会出现这种情况。
- client没有任何响应,服务器就会干等,甚至多次重发FIN,浪费资源
- client有个新的应用程序刚好分配同一个端口号,新的应用程序收到FIN后马上开始执行断开连接的操作,本来它是想跟server建立连接的
保活、心跳包
在实际开发当中,服务器并不会保持长连接,可能当客服端15S内没有发送数据,服务器就关闭了。那么如果我就是要保持长连接,咋办?这就是长连接
于是客服端为了活下去,就每个几秒发一个数据包过去,这就是心跳包,一跳一跳的
这个功能实在应用层实现的,通过这样才能,加一个定时器类似的东西去判断。
真实问题
实际过程中的四次挥手
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oFaJUpXA-1637539723644)(D:\Desktop\计算机网络\第十一一天:TCP—释放连接.assets\image-20211014191250335.png)]
这里是三次挥手
它放弃的是那一条数据呢?
是第二次挥手
有时候在使用抓包工具的时候,有可能只会看到"3次"挥手
这其实是将第2、3次挥手合并了
当server接收到client的FIN时, 如果server后面也没有 数据要发送给client了,这时,server就可以将第2、3次挥手合并,同时告诉client两件事
- 已经知道client没有数据要发
- server已经没有数据要发了