首先就是这张很经典的图,我们围绕这个图开讲
咱分条来说各个转换之间的动作
首先从CLOSED开始
如果是CLOSED-》LISTEN 代表这是服务端 监听某个端口 准备接受其他人的connect了
如果是CLOSED-》SYN_SENT 代表这是一个客户端发送了connect 发送了SYN=1,进行了TCP的第一次握手 然后等待对方的第二次握手发送SYN=1和ACK=1
当收到了SYN=1和ACK=1后(第二次握手),并且自己发送了ACK=1(第三次握手) 这时候在客户端这边,就已经建立了TCP连接,所以就是SYN_SENT -》ESTABLISHED 代表正式建立了连接
这时候回到服务端接收端这边 服务端接受到第一次握手SYN=1后,自己发送第二次握手SYN=1 ACK=1,就已经进入了SYN_RCVD状态,等待着第三次握手的到来
等到第三次握手的到来,于是收到了ACK=1,于是服务端这边的连接也建立成功,SYN_RCVD-》ESTABLISHED
当然 在SYN_RCVD等待第三次握手的时候,也有可能收到的不是第三次握手,而是一个RST(reset)标志,这就代表要重置这个连接,所以当收到RST的时候,SYN_RCVD-》LISTEN 退化了
然后接下来就是TCP的关闭状态了,这时候就涉及到了TCP的4次挥手,当然在状态上有主动关闭和被动关闭的区别
先说说主动关闭 一般是客户端发起(虽然并没有什么客户端服务端区别,但就这样叫了)
首先先是向服务端发送一个FIN=1,代表客户端到服务端这单向路莫得数据要传了,于是这里就从ESTABLISHED-》FIN_WAIT_1 状态 第一次等待,等待服务端下一个数据包传过来的ACK
然后呢,当服务端传过来一个ACK,这个ACK的值为上一次发送FIN的时候,传过去的SEQ+1,这时候,就是FIN_WAIT_1-》FIN_WAIT_2 ,开始等待服务端的FIN了
当收到了服务端最后一个FIN,代表了服务端到客户端这单线也莫得数据要传送了,然后自己发送一个ACK,表示自己收到了对面的FIN,于是终于FIN_WAIT_2进入到了TIME_WAIT阶段
为什么要有TIME_WAIT阶段而且要持续2MSL(MSL为报文最大生命周期,WINDOWS一般为2分钟)呢?因为有可能对方服务器端莫得收到最后的ACK,所以这段时间是用来重传等待的
等过了这段时间,就真正断开回到了CLOSED了
然后可以说下服务端那边的被动关闭了,服务端当他接受到了FIN后,肯定还可能会有数据没传完,所以数据夹带一个ACK(此时ACK=发送过来的FIN报文中的SEQ+1)传过去告诉客户端知道了 ,再塞点数据。然后发送了ACK就从ESTABLISHED进入了CLOSE_WAIT阶段
然后最后 服务端也没数据了 然后就发送了FIN报文,告诉对方自己莫得数据了,然后等待对面的ACK回应,这时候就从CLOSE_WAIT进入了LAST_ACK阶段
最后的最后,当接受到了客户端最后一个ACK,彻底解放,回到CLOSED的怀抱中
这时候说两个同时的例子
一个是同时打开
TCP第一次握手都发送的是SYN=1嘛
有时候会碰到客户端发送了SYN=1,第一次挥手,然后进入到了SYN_SENT状态
这时候 原本应该接受对方的第二次握手 本应该收到的是SYN=1并且ACK=1
但是这时候只收到了一个SYN=1的话,就代表是双方同时发送了SYN第一次握手。此时虽然双方发出去的时候都为SYN_SENT,但是在收到了对方的SYN=1后,就变成了SYN_RCVD了
那有啥好讲的,双方都只能回复一个第二次握手回去咯,所以双方都发送了SYN=1,ACK=1,此时这个发送的ACK就是帮助对方从SYN_RCVD进入到ESTABLISHED状态了
然后就是同时关闭
和上面一样,原本主动发送FIN的一方,变成FIN_WAIT准备收获对面的第二次挥手ACK了
但是 这时候突然也直接受到了对面的FIN=1,
那能怎么办,直接相视一笑,都对对面发送一个ACK的确认,然后进入CLOSING的状态
等待对方的ACK一到,直接就进入TIME_WAIT状态了 等2MSL后就CLOSED了
这就是我自己对TCP11种状态间的转换的理解
原文地址:https://www.cnblogs.com/EatMedicine/p/10612386.html