【筆記】關於TCP三次握手和四次揮手的理解


1. 三次握手:

  服務器一定處於Listen狀態,否則客戶端發過來的連接會被拒絕。注:服務器和客戶端的角色是相對的。

  客戶端發送第一次握手(客戶端發送連接請求(SYNC包)到服務器)之后由Closed狀態轉為Sync-Send狀態;

  服務器收到第一次握手的客戶端SYNC包,然后發送第二次握手(服務器發送SYNC+ACK(客戶端SYNC包的確認)包給客戶端)之后服務器由Listen狀態轉為Sync-Recv狀態;

  客戶端收到第二次握手的服務器SYNC+ACK包,然后發送第三次握手(客戶端對“服務器的SYNC+ACK包“的ACK包給給服務器)之后客戶端就轉為ESTABLISHED狀態;

  服務器收到第三次握手的客戶端ACK包之后也進入了ESTABLISHED。

 

2. 四次揮手:

  服務器與客戶端都處於ESTABLISHED狀態,且有一方主動發起了關閉,另外一方會被動關閉。被動關閉的一方需要處理socket的資源回收等,被動關閉的一方需要及時關閉,所以說被動關閉的一方出現大量CLOSE_WAIT狀態通常都是因為程序代碼問題。

  主動關閉的一方(可能是服務器也可能是客戶端)的狀態遷移:FIN-WAIT1->FIN-WAIT2->TIME_WAIT-CLOSED

  被動關閉的一方的狀態遷移:CLOSE_WAIT->LAST_ACK->CLOSED

  同時關閉:雙方狀態一致: FIN_WAIT1->CLOSING->TIME_WAIT

  假設客戶端主動關閉連接,以下說明客戶端和服務器如何遷移:

  客戶端發送第一次揮手(客戶端第一個FIN包給服務器)之后由ESTABLISHED狀態轉為FIN_WAIT1狀態;

  服務器收到客戶端的第一次揮手(客戶端第一個FIN包給服務器)之后,發送第二次揮手(對客戶端FIN的ACK確認包)給服務器,服務器進入CLOSE_WAIT狀態,等待服務器自身的socket關閉等處理(等待IO,業務處理,資源回收等等);

  客戶端收到服務器的第二次揮手(對客戶端FIN的ACK確認包),進入FIN_WAIT2狀態,等待服務器關閉(服務器調用close函數發送服務器的FIN包);

  服務器發送第三次揮手(在處理完自己的事情,調用close函數之后,發送服務器的FIN包),進入LAST_ACK狀態;

  客戶端收到第三次揮手(服務器的FIN包),發送第四次揮手(客戶端第二個FIN包+ACK(對服務器FIN包的確認)),客戶端進入TIME_WAIT狀態;

  服務器收到第四次揮手(客戶端第二個FIN包+ACK(對服務器FIN包的確認)),進入CLOSED狀態;

  客戶端等待2MSL時間,進入CLOSED狀態

  注:FIN_WAIT2狀態等待時間是有限的,系統可配:tcp_fin_timeout 這個參數可以控制改狀態存活的時間

    FIN_WAIT1和CLOSE_WAIT是比較危險的狀態,一般服務器網絡鼓掌首先要查看這倆個狀態是否正常:CLOSE_WAIT在上面說過,如果服務器代碼有問題(忘記close等),服務器會一直有需要的CLOSE_WAIT狀態的socket,造成服務器不可連接;FIN_WAIT1會在發出來FIN而沒有手到ACK會重新發送FIN,重發次數由系統參數配置:tcp_orphan_retries;如果系統負載過重,減少tcp_orphan_retries值可能有作用。

    一般來說FIN_WAIT1幾乎不可見,因為服務器之間的ACK速度非常快;

    FIN_WAIT1 的DDos攻擊舉例說明:http://huoding.com/2014/11/06/383

 

參考:http://coolshell.cn/articles/1484.html

TCP共有11個網路狀態,其中涉及到關閉的狀態有5個。

在我們編寫網絡相關程序的時候,這5個狀態經常出現。因為這5個狀態相互關聯,相互糾纏,而且狀態變化觸發都是由應用觸發,但是又涉及操作系統和網絡,所以正確的理解TCP 在關閉時網絡狀態變化情況,為我們診斷網絡中各種問題,快速定位故障有着非常重要的作用和意義。

下是是根據W.Richard Stevens的《TCP/IP詳解》一書的TCP狀態轉換圖。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM