![](http://hi.csdn.net/attachment/201112/11/0_132359028182UU.gif)
1: 当客户端应用程序主动请求关闭时,调用close或shutdown关闭连接,这时应用程序发送FIN,然后进入FIN_WAIT_1状态,
2: 服务器接收到FIN后, 协议返回ACK(不是应用程序发送的)。
3: 客户端接收到服务器端的ACK以后,客户端进入FIN_WAIT_2状态。等待服务器调用close,并发送FIN。
4: 在第2步骤中服务器的协议返回ACK后,同时向上面应用程序提交一个error,导致上面的socket的send或者recv返回socket_error,正常情况下,如果上面在接收到返回socket_error后调用了closesocket,服务器的tcp就会发送一个fin到客户端。
5: 当客户端接受到FIN后,发送ACK,进入最终的TIME_WAIT状态。执行主动关闭的那一端进入TIME_WAIT状态。留在TIME_WAIT的持续的时间是MSL(最长分节生命周期 maximum segment lifttime)时间的两倍,也就是2MSL. MSL一般情况下是30秒到2分种,所以TIME_WAIT的时间一般为1-4分种。
处于time_wait状态的连接占用的资源不会被内核释放,所以作为服务器,在可能的情况下,尽量不要主动断开连接,以减少time_wait状态造成的资源浪费。
目前有一种避免time_wait资源浪费的方法,就是关闭socket的linger选项。但这种做法是tcp协议不推荐使用的,在某些情况下这个操作可能会带来错误
状态的描述:
CLOSED:无连接是活动的或正在进行
LISTEN:服务器在等待进入呼叫
SYN_RECV:一个连接请求已经到达,等待确认
SYN_SENT:应用已经开始,打开一个连接
ESTABLISHED:正常数据传输状态
FIN_WAIT1:应用说它已经完成
FIN_WAIT2:另一边已同意释放
ITMED_WAIT:等待所有分组死掉
CLOSING:两边同时尝试关闭
TIME_WAIT:另一边已初始化一个释放
LAST_ACK:等待所有分组死掉
TCP/IP状态转换图的分析
参考:
http://qqchinaok.iteye.com/blog/1149548
http://blog.chinaunix.net/space.php?uid=20788636&do=blog&id=1841261