TCP的状态转换发生在三次握手和四次挥手的过程中,这次主要谈一谈转换中的几个状态
1.状态转换缘由
TCP发生状态转换大概会有以下几种情况
- 接收到了某个控制位的报文段(SYN,ACK,FIN)
- 有些转换要求发送一些控制字段的报文段
- 由于程序的动作或者计时器超时
2.具体转换
当初始化时,会从CLOSED状态启动,然后根据执行的是主动打开操作还是被动打开操作来转换到SYN_SENT或LISTEN状态,具体的转换过程如下图所示:
在上图中,
- 数据传输就发生在ESTABLISHED状态
- 客户端在经过TIME_WAIT状态(2MSL计时器完成后),也会进入CLOSED状态
3.FIN_WAIT_2状态
当我们主动关闭时并发送FIN时,处于FIN_WAIT_1状态,发送FIN后,随即进入FIN_WAIT_2状态.
当另一端已经发送确认消息ACK,此时执行主动关闭的客户端会一直等待被动关闭的另一端(服务器端)发送FIN连接.
如果处于半关闭状态的话,就会等待数据传输完后,再发送FIN.
只有当接收到FIN后,才会进入到TIME_WAIT的状态,也就是说,两端可以一直处于FIN_WAIT_2和CLOSE_WAIT状态,直到应用程序结束并宣布它关闭
我们可以防止进入这个无线循环状态
如果负责主动关闭的应用程序,执行的是一个完全关闭操作,即不会出现半关闭状态(还期望让它接收数据),那么可以通过设置一个计时器,当计时器已超时,并且连接是空闲的,那么这一端就会进入一个CLOSED状态
4.TIME_WAIT状态
在状态转换中,主动关闭的一方,最后会经历一个TIME_WAIT状态,在该状态下,TCP会等待两倍于最大段存区的时间(MSL),有时也是被称为加倍等待.
MSL状态代表任何报文段在被丢弃前,在网络中所被允许存在的最长时间,这个数值可以为30秒,1分钟或2分钟,绝大部分情况下,这一数值是可以修改的.
我们现在先认为已经设定过MSL,
那么在我们TCP执行主动关闭,发送了最后的一个ACK后,主动关闭的这一端必须要处于TIME_WAIT状态并延续2MSL,
这是因为被动关闭的TCP总是会重传最后的FIN,直到它接收到最终的ACK,所以就需要主动关闭端保持这个状态,防止主动关闭端发送最终的ACK出现丢失的情况.
同时也是保证迟来的TCP报文段有足够的时间被识别并丢弃,防止建立新连接后接收了上一个连接的旧数据
当TCP处于2MSL等待状态时,通信双方将该连接(四元组)定义为不可使用,只有:
- 2MSL结束时
- 一条新连接使用的初始序列号超过了连接前的实例所使用的最高序列号时
- 允许使用时间戳选项来区分之前连接实例的报文段以避免混淆时
满足以上三点中一点,这条连接才能再次使用.
事实上,一些实现与API可以绕开这一约束方法,以后有机会再进行学习
对交互式应用程序而言,客户端常常是执行主动关闭操作的一方,因此会进入TIME_WAIT状态,但是因为客户端通常使用的是操作系统分配的临时端口号(它们也不会关心被分配的端口号究竟是什么),所以我们一般不会出现关闭一个客户端后,马上重启时无法重启的情况.
但是一个客户端也可以快速产生大量连接,因此在端口供应紧张时,也会延迟一会儿,等待其他连接的终止.
对于服务器来讲,我们使用的端口往往是一些知名的端口,所以我们如果终止了一个已经建立连接的服务器进程,那么当我们短时间内重启时,由于它不能为程序分配一个对应的端口,就会报出"地址已占用"的错误.
5.静默时间
TIME_WAIT状态防止新连接接收到旧数据这一功能只有在处于TIME_WAIT状态的主机在2MSL内未关闭才有用
当处于TIME_WAIT状态的主机崩溃后,重启时,需要等待一个相当于MSL的时间才能建立新的连接,这段时间就是静默时间
静默时间的原因在于,在TIME_WAIT状态的主机崩溃掉前,产生的延时报文段,会被认为属于我们重启之后创建的连接,然后给新连接发送旧数据.
6.同时打开和同时关闭
两个应用程序同时执行主动打开操作,虽然发生概率比较小,但也存在,如:
主机1:使用端口7777与主机2端口8888执行主动打开
主机2:使用端口8888与主机1端口7777执行主动打开
SYN包同时打开了对端,这个时候,就是同时打开的情况,如下图
当发生这种情况时,我们首先要明确一点,TCP协议针对这种情况,专门设计,只会建立一条连接,在同时收到SYN包后,直接进入ESTABLISHED状态,我们可以建立了4个报文段,看到比三次握手多了一次,此时双方都扮演着服务器和客户端的角色.
同时关闭与同时打开差不多,如下图
观察同时关闭的过程,我们会发现,多了一个CLOSE_WAIT状态被CLOSING状态所替代,互相发送ACK后,同时进入TIME_WAIT状态
了解上面这些后,看这幅图基本就会一目了然,没什么大问题了
初学TCP,如有错误,欢迎大家帮我指出.