1、LISTENING狀態
FTP服務啓動後首先處於偵聽(LISTENING)狀態。
2、ESTABLISHED狀態
ESTABLISHED的意思是建立連接。表示兩臺機器正在通信。
3、CLOSE_WAIT
對方主動關閉連接或者網絡異常導致連接中斷,這時我方的狀態會變成CLOSE_WAIT 此時我方要調用close()來使得連接正確關閉
4、TIME_WAIT
我方主動調用close()斷開連接,收到對方確認後狀態變爲TIME_WAIT。TCP協議規定TIME_WAIT狀態會一直持續2MSL(即兩倍的分段最大生存期),以此來確保舊的連接狀態不會對新連接產生影響。處於TIME_WAIT狀態的連接佔用的資源不會被內核釋放,所以作爲服務器,在可能的情況下,儘量不要主動斷開連接,以減少TIME_WAIT狀態造成的資源浪費。目前有一種避免TIME_WAIT資源浪費的方法,就是關閉socket的LINGER選項。但這種做法是TCP協議不推薦使用的,在某些情況下這個操作可能會帶來錯誤。
TCP連接關閉的幾種方式:
1、“正常”關閉:調用close()關閉socket、沒close但進程正常結束(當然這是不應該的做法)、進程core掉、在shell命令行中kill掉進程,都可抽象成“正常”關閉。因爲即使core掉,內核也會馬上幫應用程序回收(close)socket文件描述符。
“正常”關閉,默認情況下(非默認即設置Linger下面會介紹),關閉端即客戶端TCP層會發FIN包,對端即服務器TCP層收到後,回ACK,客戶端進入FIN_WAIT2狀態。此時,TCP終止連接的4個分組中服務器應該發的第3個分組FIN包,其TCP層是不會主動發的,只有服務器端socket“正常”關閉,纔會發出這個FIN包。至此,客戶端進入TIME_WAIT狀態。
2、“非”正常關閉:客戶端崩潰了,此時肯定發不出FIN包了(當然啦,內核都沒機會幫應用程序回收資源了)。這種情況,服務器端有如下兩種情況:
A、服務器send數據,因爲客戶端已經崩潰,服務器收不到ACK自然會不停的重傳。源自
Berkeley的重傳機制,重傳8次,相對第一次傳的15分鐘後仍沒收到ACK,則返回
ETIMEDOUT或EHOSTUNREAC錯誤。如果服務器不理會這個錯誤,再次調用send,則
立馬返回Broken Pipe錯誤。
注:15分鐘超時可以在 /proc/sys/net/ipv4/tcp_retries2 中修改
B、 服務器不發任何數據了,那只有靠應用層心跳檢測機制或Keepalive,來發覺TCP斷連了。