about timewait
一个established tcp链接结束需要经过类似“3次握手”的过程,
1 –---(fin)—> 2
1 <–—(ack)—2
1 <–—(fin)—2
1 –---(ack)—> 2
在active close方(1)发出fin后,就进入fin_wait1,(1)在这个状态中等待来自(2)的反应,如果(2)回一个ack,则(1)进入fin_wait2,继续等待接下来的(2)发出的fin,收到之后直接回一个ack,进入time_wait状态,
如果(2)此时也发了一个fin,则(1)回一个ack,并进入closing状态,只要(2)再来一个ack,就立马进入time_wait,
如果此时(2)在一个包里发了ack,和fin,则(1)直接进入tw状态。
so,对于activeclose方,time_wait 状态就是最终状态了。而对于passive close (2),状态转移就简单多了,在收到fin返回一个ack之后就进入close_wait,然后自己再发个fin,进入lastack,等到回复ack之后就关闭了。
why timewait ?
为什么不直接是一个close状态呢,为毛还要等待2msl时间。这是因为如果这个socket在短时间(2msl)内再次建立一个连接时,有可能会收到一个dalay的包(只要包在网络中delay的时间不超过msl就不会被丢弃),这个包有可能会引起双方通讯的混乱。
so,what does it costs anyway?
对于(1)而言几乎没有cost,是的,不占用openfd。占用一点内存,内核维持一张所有tw状态的socket的表,如果有过多的tw,有可能会报time wait bucket table overflow。这时需要调整内核参数:net.ipv4.tcp_max_tw_buckets。