前言:
tcp協議棧是個面向連接的協議棧,其面向連接不是說真的有一個什麼連接在,而是收發雙方在協議棧層面各自會維持一個數據結構,這個數據結構保存了當前通訊的狀態、數據和其他重要信息。可以理解爲tcp的狀態機詮釋了什麼是 “有鏈接”。
狀態機:
半打開:
半打開狀態出現在 三次握手階段,主動建立鏈接方 和 被動建立鏈接方都會進入這個狀態。
三次握手由 2個 SYN 和 2個 ACK組成,發送出SYN 還沒 收到對端的 ACK的狀態就是半打開狀態,所以主動/被動都可能進入半打開狀態。
有關超時:
發送SYN後,一定時間內沒有收到ACK,則會再次發送SYN,之後會按照倍數間隔的模式繼續發送6次,63秒後超時
半打開狀態是 SNY 洪流攻擊的切入點。
半關閉:
半關閉狀態出現在 四次揮手階段,主動關閉鏈接方 和 被動關閉鏈接方 都會進入這個狀態。
三次握手由 2個 FIN 和 2個 ACK組成,發送出FIN 還沒 收到對端的 ACK的狀態就是半關閉狀態,所以主動/被動都可能進入半打開狀態。
有關超時:不涉及超時機制
注:TIME_WAIT 不是半關閉狀態,此時已經走完四次揮手了; CLOSE_WAIT也不是半關閉狀態,因爲此時作爲被動關閉方,其已經收到對端的FIN,只是應用程序沒有主動關閉socket(讀socket發現讀到文件結束符,然後調用close函數)。
四次揮手流程圖:
圖片來源:https://www.cnblogs.com/lshs/p/6038472.html
TIME_WAIT:
TIME_WAIT狀態僅發生在 主動關閉鏈接的一側,進入此狀態說明四次揮手流程已經結束。主動關閉側需要保持此狀態2MSL時長,一般在2分鐘左右。
維持此狀態的目的在於確保所有對端的數據都被接受或者被網絡丟棄,起到保護作用。
CLOSE_WAIT:
CLOSE_WAIT狀態僅發生在 被動關閉鏈接 的一側,進入此狀態說明收到對端的FIN,此時本端進入CLOSE_WAIT狀態,需要應用程序調用close函數來觸發對FIN的ACK,並清理資源後發送自己的FIN。
注:進入此狀態,如果不調用close,則四次揮手永遠只能停留在第一步,這也會導致主動關閉側處於FIN_WAIT_1狀態