TCP状态

SYN_RECV

服务端收到建立连接的SYN没有收到ACK包的时候处在SYN_RECV状态

CLOSE_WAIT

发起TCP连接关闭的一方称为client,被动关闭的一方称为server。被动关闭的server收到FIN后,但未发出ACK的TCP状态是CLOSE_WAIT。出现这种状况一般都是由于server端代码的问题,如果你的服务器上出现大量CLOSE_WAIT,应该要考虑检查代码。

TIME_WAIT

根据TCP协议定义的3次握手断开连接规定,发起socket主动关闭的一方 socket将进入TIME_WAIT状态。TIME_WAIT状态将持续2个MSL(Max Segment Lifetime),在Windows下默认为4分钟,即240秒。TIME_WAIT状态下的socket不能被回收使用. 具体现象是对于一个处理大量短连接的服务器,如果是由服务器主动关闭客户端的连接,将导致服务器端存在大量的处于TIME_WAIT状态的socket, 甚至比处于Established状态下的socket多的多,严重影响服务器的处理能力,甚至耗尽可用的socket,停止服务。

为什么需要TIME_WAIT?TIME_WAIT是TCP协议用以保证被重新分配的socket不会受到之前残留的延迟重发报文影响的机制,是必要的逻辑保证。

 

下面假设:主动关闭的一端为A,被动关闭的一端为B, 根据B是否收到最后的ACK包分为两种情况

  1. B发送FIN,进入LAST_ACK状态,A收到这个FIN包后发送ACK包,B收到这个ACK包,然后进入CLOSED状态
  2. B发送FIN,进入LAST_ACK状态,A收到这个FIN包后发送ACK包,由于某种原因,这个ACK包丢失了,B没有收到ACK包,然后B等待ACK包超时,又向A发送了一个FIN包
    a) 假如这个时候,A还是处于TIME_WAIT状态(也就是TIME_WAIT持续的时间在2MSL内)
    A收到这个FIN包后向B发送了一个ACK包,B收到这个ACK包进入CLOSED状态
    b) 假如这个时候,A已经从TIME_WAIT状态变成了CLOSED状态
    A收到这个FIN包后,认为这是一个错误的连接,向B发送一个RST包,当B收到这个RST包,进入CLOSED状态
    c) 假如这个时候,A挂了(假如这台机器炸掉了)【第四种情况,不在参考链接里】
    B没有收到A的回应,那么会继续发送FIN包,也就是触发了TCP的重传机制,如果A还是没有回应,B还会继续发送FIN包,直到重传超时(至于这个时间是多长需要仔细研究),B重置这个连接,进入CLOSED状态

TCP状态

参考:

TCP连接状态分析:SYNC_RECV,CLOSE_WAIT,TIME_WAIT(图有问题,TIME_WAIT应在send_ACK后面,CLOSE_WAIT应在send_ACK后面,有些send写成了receive)

在tcp协议中处于last_ack状态的连接,如果一直收不到对方的ack,会一直处于这个状态吗?

 
喜欢 0
分享