博主个人社区:开发与算法学习社区 博主个人主页:Killing Vibe的博客 欢迎大家加入,一起交流学习~~
在正常情况下,TCP要经过三次握手建立连接,四次挥手断开连接,但断开连接的时候,由于双方的关闭时机不同,双方也相应的会有不同的状态。
这里有张图很好的总结了TCP整个生命周期(情况一):
服务端状态转化:
客户端状态转化:
当然上面的图只是其中一种情况,对应了博主之前讲4次挥手的情况一(总共有三种情况)。
下面博主给大家带来另外两种变形的情况:(是不是究极折磨🤔):
分别是情况二 和 情况 三 :(先记住)
解析:
好,有了上述三种情况,就可以理解下面的TCP状态汇总图了(不理解也无所谓,记住挥手阶段有三种情况就行):
首先,大家握手的状态变化都是一样的,区别就在挥手阶段:
分了三种情况(这里说服务器和客户端是为了好理解):
情况一:四次挥手,服务器是被动关闭的一方,客户端主动关闭; 情况二:三次挥手,服务器和客户端都是主动关闭的一方; 情况三:四次挥手,服务器和客户端都是主动关闭的一方。
注意:(看了下面我说的,应该有助于理解)
CLOSE_WAIT 状态 :
留心观察一下三种情况,是不是发现这个状态只发生在情况一里面,也就是只发生在被动方身上,出现在只有一方提出了挥手(FIN)。
TIME_WAIT状态:
留心观察一下,这个状态三种情况都有,但是只发生在主动方身上,出现在基本挥手已经结束的情况。
好了,到这里,相信读者们对这个状态转化有了初步了解,现在博主有四个问题,帮助大家更好理解这些状态:
问题一:
服务器上出现大量CLOSE_WAIT状态的TCP连接,请问这种现象是否合理?
答:
不确定。单纯这个现象无法明确断言是否正常的。
因为,如果我们的程序设计时,会出现比较长时间的单方面关闭的情况时,出现大量的CLOSE_WAIT是合理现象。
但如果我们没有这种设计,则不合理,可能的原因是我们这一侧忘记调用socket.close()
问题二:
服务器上发现了大量的TIME_WAIT的TCP连接,是否合理?
答:
理论上讲合理,就是代码正常的关闭了连接,只是主动关闭的TCP连接比较多罢了。
但是实践上来说是不合理的。因为维护连接是有成本的(最主要的硬件成本就是内存)。
客户端上背负的连接比较少(几百条),服务器上背负的连接很多(几十万-几百万)。所以,如果让服务器背负这个TIME_WAIT连接的成本,相对压力较大,所以一般建议让客户端来背这个成本。
所以一般做网络编程设计时,不建议服务器去主动关闭连接(某些特殊情况下该主动关闭还是得主动的)
问题三:
既然挥手的工作已经完成了,为什么要有个TIME_WAIT状态而不是直接进入CLOSED状态?
答:
1. 我们不能保证最后一个ACK 接收方一定能收到,如果接收方没收到就不能closed,就会重发FIN,如果发送方没有这个TIME_WAIT状态,收到FIN就不能ACK了,那接收方就关闭不了了。
2.TCP靠五元组来区分连接,五元组就是一条连接的主键信息,连接如果没有经过TIME_WAIT释放,则五元组就会立即又被分配出去了。如果此时收到了一些之前网络传输比较慢的一些数据,就不能判断是谁发过来的了,有可能是上一个进程发送的。
问题四:
为什么是TIME_WAIT的时间是2MSL?
MSL是个理论值,实际中很多OS取的是经验值,一般取一分钟。所以默认情况下TIME_WAIT的持续时间是2分钟。这个值可以修改。
以上就是TCP状态转移的三种情况,觉得有帮助的朋友可以点赞收藏一波,有什么疑问可以私信博主。