TCP两次挥手,你见过吗?那四次握手呢?

本文详细探讨了TCP的挥手过程,包括四次挥手的正常情况,以及特殊情况下的三次和两次挥手。重点分析了FIN是否必须通过close()或shutdown()发出,FIN-WAIT-2状态过多的原因,以及自连接的情况。文中还讨论了TCP同时打开的连接建立,以及在不同场景下如何处理数据传输和连接关闭。
摘要由CSDN通过智能技术生成

我们都知道,TCP是个面向连接的、可靠的、基于字节流的传输层通信协议。

那这里面提到的"面向连接",意味着需要 建立连接,使用连接,释放连接。

建立连接是指我们熟知的TCP三次握手。

而使用连接,则是通过一发送、一确认的形式,进行数据传输。

还有就是释放连接,也就是我们常见的TCP四次挥手。

TCP四次挥手大家应该比较了解了,但大家见过三次挥手吗?还有两次挥手呢?

都见过?那四次握手呢?

今天这个话题,不想只是猎奇,也不想搞冷知识。

我们从四次挥手开始说起,搞点实用的知识点。

TCP四次挥手

简单回顾下TCP四次挥手。

正常情况下。只要数据传输完了,不管是客户端还是服务端,都可以主动发起四次挥手,释放连接。

就跟上图画的一样,假设,这次四次挥手是由客户端主动发起的,那它就是主动方。服务器是被动接收客户端的挥手请求的,叫被动方。

客户端和服务器,一开始,都是处于ESTABLISHED状态。

第一次挥手:一般情况下,主动方执行close()或 shutdown()方法,会发个FIN报文出来,表示"我不再发送数据了"。

第二次挥手:在收到主动方的FIN报文后,被动方立马回应一个ACK,意思是"我收到你的FIN了,也知道你不再发数据了"。

上面提到的是主动方不再发送数据了。但如果这时候,被动方还有数据要发,那就继续发。注意,虽然第二次和第三次挥手之间,被动方是能发数据到主动方的,但主动方能不能正常收就不一定了,这个待会说。

第三次挥手:在被动方在感知到第二次挥手之后,会做了一系列的收尾工作,最后也调用一个 close(), 这时候就会发出第三次挥手的 FIN-ACK。

第四次挥手:主动方回一个ACK,意思是收到了。

其中第一次挥手和第三次挥手,都是我们在应用程序中主动触发的(比如调用close()方法),也就是我们平时写代码需要关注的地方。

第二和第四次挥手,都是内核协议栈自动帮我们完成的,我们写代码的时候碰不到这地方,因此也不需要太关心。

另外不管是主动还是被动,每方发出了一个 FIN 和一个ACK 。也收到了一个 FIN 和一个ACK 。这一点大家关注下,待会还会提到。

FIN一定要程序执行close()或shutdown()才能发出吗?

不一定。一般情况下,通过对socket执行 close() 或 shutdown() 方法会发出FIN。但实际上,只要应用程序退出,不管是主动退出,还是被动退出(因为一些莫名其妙的原因被kill了), 都会发出 FIN。

FIN 是指"我不再发送数据",因此shutdown() 关闭读不会给对方发FIN, 关闭写才会发FIN。

如果机器上FIN-WAIT-2状态特别多,是为什么

根据上面的四次挥手图,可以看出,FIN-WAIT-2是主动方那边的状态。

处于这个状态的程序,一直在等第三次挥手的FIN。而第三次挥手需要由被动方在代码里执行close() 发出。

因此当机器上FIN-WAIT-2状态特别多,那一般来说,另外一台机器上会有大量的 CLOSE_WAIT。需要检查有大量的 CLOSE_WAIT的那台机器,为什么迟迟不愿调用close()关闭连接。

所以,如果机器上FIN-WAIT-2状态特别多,一般是因为对端一直不执行close()方法发出第三次挥手。

​主动方在close之后收到的数据,会怎么处理

之前写的一篇文章《代码执行send成功后,数据就发出去了吗?》中,从源码的角度提到了,一般情况下,程序主动执行close()的时候;

  • 如果当前连接对应的socket的接收缓冲区有数据,会发RST。

  • 如果发送缓冲区有数据,那会等待发送完,再发第一次挥手的FIN。

大家知道,TCP是全双工通信,意思是发送数据的同时,还可以接收数据。

Close()的含义是,此时要同时关闭发送和接收消息的功能。

也就是说,虽然理论上,第二次和第三次挥手之间,被动方是可以传数据给主动方的。

但如果 主动方的四次挥手是通过 close() 触发的,那主动方是不会去收这个消息的。而且还会回一个 RST。直接结束掉这次连接。

​【文章福利】另外小编还整理了一些C++后端开发面试题,教学视频,后端学习路线图免费分享,需要的可以自行添加:学习交流群点击加入~ 群文件共享

小编强力推荐C++后端开发免费学习地址:C/C++Linux服务器开发高级架构师/C++后台开发架构师​icon-default.png?t=M5H6https://ke.qq.co

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值