赞
踩
之前已经介绍了TCP协议的三路握手和四次挥手。如下图所示,TCP通信过程包括三个步骤:建立TCP连接通道(三次握手)、数据传输、断开TCP连接通道(四次挥手)。
这里进一步探究TCP三路握手和四次挥手过程中的状态变迁以及数据传输过程。先看TCP状态状态转换图。
插句话,该文介绍的性能分析工具(sar -n TCP,ETCP 1)命令可以对主动打开和被动打开的数目进行统计,在一定程度上可以反应服务器的繁忙程度。
下图给出客户端与服务器的三次握手过程:
下图给出三次握手对应的状态转移图:
参考《TCP/IP详解》卷一第18章18.8节。这种情况发生在两端几乎同时发送SYN并且这两个SYN在网络中交错的情形。这种情况可能发生,但是非常罕见。
例如,主机A的应用程序使用本地端口7777,并与主机B的端口8888执行主动打开。主机B的应用程序使用本地端口8888,并与主机A的端口7777执行主动打开。
下图给出同时打开过程:
下图给出同时打开的状态转移图:
说明:从目前个人经验来看,这种场景没有遇到过,但这是完整理解TCP状态转移必须的一部分。但《TCP/IP详解》卷一第18章18.8节中支出,许多伯克利版的TCP实现都不能正确地支持打开。
考虑场景:客户端尚未接收到服务器ACK+SYN,异常退出(崩溃退出)。这时,当客户端接收到服务器的ACK+SYN时,客户端回复RST(reset)。此时服务器处于SYN_RCVD状态,当接收到客户端RST时,则从SYN_RCVD转移到LISTEN状态。
具体过程:
下图给出建立连接失败的状态转移图:
考虑场景1:服务器的进程异常退出,客户端不知道。那么客户端发送SYN后,服务器端响应RST,则客户端建立连接失败。
考虑场景2:服务器机器关闭,导致服务器IP不可达。那么客户端发送SYN后,超时重发,超过重试次数,最终TIMEOUT,则客户端建立连接失败。
具体过程:
下图给出建立连接失败的状态转移图:
下图给出客户端与服务器的四次挥手过程:
下图给出四次挥手的状态转移图:
参考《TCP/IP详解》卷一第18章18.9节。我们在前面讨论了一方(通常但不总是客户方)发送第一个FIN执行主动关闭。双方都执行主动关闭也是可能的,TCP协议也允许这样的同时关闭(simultaneous close)。
下图给出同时关闭过程:
下图给出同时关闭的状态转移图:
考虑场景:被动关闭端收到FIN包后,直接发送FIN+ACK,则主动关闭方则从FIN_WAIT_1跳过FIN_WAIT_2,直接进入TIME_WAIT。
给出具体流程:
下图给出同时关闭的状态转移图:
TIME_WAIT状态存在的原因有两点:
1.可靠的终止TCP连接
2.保证让迟来的TCP报文段有足够的时间被识别并丢弃
第一点很好解释:如果网络不可靠,那么就无法保证最后客户端发送的ACK报文服务器端一定能够收到,因此处于LAST_ACK状态的服务器可能会因为超时而未收到ACK报文,而重新向客户端发送FIN报文。因此客户端需要停留在TIME_WAIT状态一段时间以处理重复收到的报文段。如果没有这个TIME_WAIT状态,客户端处于CLOSED状态,那么客户端将响应RST(reset),服务器端收到后会将该RST分节解释成一个错误,也就不能实现最后的全双工关闭了(主动方单方的关闭)。所以用TIME_WAIT状态来保证TCP连接的可靠终止。
第二个原因:比如在客户端收到ACK后如果立即关闭,虽然这个端口已经关闭,但如果有一个新的连接被建立起来,使用的IP地址和端口和这个先前到达了CLOSED状态的完全相同,假定原先的连接中还有数据报残存在网络之中,这样新的连接建立以后传输的数据极有可能就是原先的连接的数据报,为了防止这一点,TCP不允许从处于TIME_WAIT状态的socket 建立一个连接,处于TIME_WAIT状态的 socket 在等待了两倍的MSL时间之后,将会转变为CLOSED状态。这里TIME_WAIT状态持续的时间是2MSL(MSL是任何IP数据报能够在因特网中存活的最长时间),足以让这两个方向上的数据包被丢弃(最长是2MSL)。通过实施这个规则,我们就能保证每成功建立一个TCP连接时,来自该连接先前化身的老的重复分组都已经在网络中消逝了。
综上来看:TIME_WAIT存在的两个理由就是
---------------------
本文参考:
1.https://www.cnblogs.com/figo-cui/p/5137993.html
2.https://blog.csdn.net/wenqian1991/article/details/40110703
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。