TCP状态转移要点
TCP协议规定,对于已经建立的连接,网络双方要进行四次握手才能成功断开连接,如果缺少其中某个步骤,将会使连接处于假死状态,连接本身占用的资源不会被释放,网络服务器程序要同时管理大量连接,所以很有必要保证无用连接完全断开,否则大量僵死的连接会浪费许多服务器资源,在众多TCP状态中,最值得注意的状态有两个:CLOSE_WAIT和TIME_WAIT
1.LISTENING状态
FTP服务启动后首先处于侦听(LISTENING)状态。
2.ESTABLISHED状态
建立连接,表示两台机器正在通信。
3.CLOSE_WAIT
(1)对方主动关闭连接或者网络异常导致连接中断,(被迫断开连接)这时我方的状态变为CLOSE_WAIT(对方主动关闭连接),此时我方要调用close()使连接正确关闭
4.TIME_WAIT
(1)我方主动调用close()断开连接,(2)收到对方确认后状态变为TIME_WAIT,TCP协议规定TIME-WAIT状态一直持续2MSL(两倍的分段最大生存期),以此确保旧的连接状态不会对新连接产生影响,处于TIME_WAIT状态的连接占用的资源不会被内核释放,所以作为服务器,在可能的情况下,尽量不要主动断开连接,以减少TIME_WAIT状态造成的资源浪费。
TCP连接的四次握手
(1)HOST1上的应用程序关闭己方的连接导致TCP发送一个FIN消息给HOST2;
(2)HOST2发送一个确认消息给HOST1,并且HOST2把HOST1发来的FIN作为EOF消息给HOST2上的应用程序;
(3)一段时间过后,HOST2上的应用程序关闭它那里的连接,引发一个FIN消息给HOST1;
(4)HOST1给HOST2发送一个确认消息,然后HOST2关闭连接并释放资源,然而,HOST1并没有关闭连接,而是进入TIME_WAIT状态,并为两个最大段生存时间(2MSL)保留在此状态。
TIME-WAIT的好处
在第四步的时候,HOST1发送的aCK可能丢失导致HOST2重新发送FIN消息,TIME_WAIT维护连接状态,如果执行主动关闭的一方的HOST1不进入到TIME_WAIT状态就关闭连接,当重传的FIN消息到达时,因为TCP已经不再有连接的信息了,所有就用RST消息应答,导致HOST2进入错误的状态而不是有序终止状态,如果发送最后ACK消息的一方处于TIME-WAIT状态并仍然记录连接信息,它就可以正确的相应对方HOST2的FIN消息
缺陷:
在TIME_WAIT状态时,内核不释放资源,造成资源浪费,因此作为服务器不应该主动释放连接。
具体见:http://www.cppblog.com/toMyself/archive/2010/08/11/123072.html
TCP连接建立
TCP连接建立是3此握手
第一次:建立连接时,客户端发送syn(syn=j)到服务器,并进入SYN_SEND(客户端发送syn进入syn_send)状态,等待服务器确认;
第二次:服务器受到SYN包,必须确认客户的SYN(ack=j+1),同时自己也发送一个syn(syn=k),及SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次:客户端受到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。