1.TCP建立連接,三次握手
建立的TCP連接可靠的連接,必須經過三次握手建立連接才能正式通信彼此傳輸數數據。
客戶端請求服務端建立連接
第一次握手:客戶給服務發送一個請求報文SYN, 客戶端的狀態置SYN_SENT狀態
第二次握手:服務端在收到客戶端發過來的SYN請求報文后,開始給客戶端發送ACK報文和SYN報文,狀態置為SYN_RECE
第三次握手:客戶端口收到服務端口過來的SYN報文和ACK報文后,狀態由原來的SYN_SENT狀態變為ESTABLISHED;並且給服務發送一個ACK報文告知對方已經送到服務端發送的SYN報文,服務端收到報文后,由原來的SYN_RECE變為ESTABLISHED
至此客戶到服務端,服務端到客戶端的雙向連接建立好了並且處理ESTABLISHED。雙方可以進行數據交換了。
2.TCP斷開連接,四次揮手。
當客戶端把所有數據傳送完畢的時候,給服務端口送一個FIN報文,告知服務端:我這邊沒有數據可傳,希望關閉客戶端到服務端方向的連接。之后其狀態由原來的
ESTABLISHED 變為FIN_WAIT_1,;
服務端收到客戶的FIN報文后,送一個ACK報文給客戶端,告知“我服務端知道你客戶端口已經沒有數據可傳,但是我這邊什么關閉連接,還需要等我的數據傳完;如果我這里數據也傳送完了,我也會給發送一個FIN報文。”。此時服務端發送ACK報文后,狀態由之前的ESTABLISHED 變為CLOSE_WAIT
客戶端端收到服務的ACK報文,將FIN_WAIT_1置FIN_WAIT_2,同時,繼續等來的服務發送FIN報文。
當服務端數據傳送也完畢的后,開始給客戶端發送FIN包,發送FIN包后,其狀態CLOSE_WAIT置為LAST_ACK
客戶端口收到了服務的發過來的FIN包后,又給服務端發送ACK。發送ACK后,狀態由原來的FIN_WAIT_2置為TIME_WAIT,客戶在經過2MSL 時間進入CLOSE狀態
服務端口收到客戶端發送的ACK后,由LAST_ACK也進入CLOSE
3.TCP遷移狀態:
LISTEN:服務端已經啟動一個socket,其狀態處於監聽狀態,等待客戶發起請求連接。
ESTABLISHED:客戶端和服務端經過三次握手建立,兩個方向上連接狀態都建立,狀態置為ESTABLISHED
客戶端狀態變遷:(主動端)
FIN_WAIT_1: 發送FIN給服務端口。
FIN_WAIT_2:收到服務端的ACK報文
TIME_WAIT :收到服務端發過來的FIN報文,發送ACK報文給服務端口。主動關閉連接端,接收到服務(TIME_WAIT是主動端關閉)之后進入2MSL時間的等待
CLOSE:2MSl過后,關閉進入初始化狀態。
服務端狀態變遷:(服務端)
CLOSE_WAIT:收到客戶端FIN報文,給客戶端發送ACK狀態后,表示知道客戶端要關閉連接請求,服務端可能數據還沒有傳送完,所以處於等
等待關閉狀態。(CLOSE_WAIT是被動端關閉)
LAST_ACK:服務端數據傳輸完畢,發送FIN報文給客戶端,同時等待客戶端發ACK報文狀態
CLOSE:收到客戶端ACK報文后,進入初始化狀態
連接是雙方建立的。發送數據的端客戶也轉變為接受數據的服務端口,服務端和客戶角色是相互轉換的
4.MSL時間:
MSL就是maximum segment lifetime(最大分節生命期),這是一個IP數據包能在互聯網上生存的最長時間,超過這個時間IP數據包將在網絡中消失 。MSL在RFC 1122上建議是2分鍾,而源自berkeley的TCP實現傳統上使用30秒
TIME_WAIT狀態維持時間
TIME_WAIT狀態維持時間是兩個MSL時間長度,也就是在1-4分鍾。Windows操作系統就是4分鍾。
5.用於統計當前各種狀態的連接的數量的命令
#netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
返回結果如下:
LAST_ACK 14
SYN_RECV 348
ESTABLISHED 70
FIN_WAIT1 229
FIN_WAIT2 30
CLOSING 33
TIME_WAIT 18122
學習參考資料 TIME_WAIT狀態原理分析:http://elf8848.iteye.com/blog/1739571
學習參考資料 TIME_WAIT狀態過多解決方法:http://blog.sina.com.cn/s/blog_8e5d24890102w9yi.html