1. 程式人生 > >TCP面試題(一)之TCP的三次握手和accept()的順序

TCP面試題(一)之TCP的三次握手和accept()的順序

     經過騰訊的六次技術面的考驗,每次基本必問TCP的一些知識。因此,筆者一直都想總結一下,但由於太忙(懶),一直沒有去做,趁這會兒有時間,特在此處總結下,希望對大家有幫助。

     眾所周知,TCP是面向連線的協議,此處的“連線”,只是抽象的連線,即,服務端和客戶端進行指定埠的資料傳輸,由於TCP協議是對端傳送資料的,所以,兩端在通訊時,就相當於通過抽象的通道,將兩個埠進行連線,從而形成抽象的“連線”。

     具體資料傳輸過程如下圖所示:


     而對於連線的建立和拆除,則分別需要三次和四次。若這部分不太清楚可以參考一下我之前的文章:TCP三次握手和四次揮手詳解,這裡我就不再贅述了。

     為了敘述和讀者理解方便,此處貼一張圖:alt

     經過上面繁雜的介紹,那麼我們來一步步分析一下“三次握手”的過程:

                          1、服務端處於LISTEN狀態,客戶端處於CLOSED狀態;

                          2、客戶端開啟,並進行SYN的傳送,處於SYN_SENT狀態;

                          3、服務端收到此條訊息後,轉為SYN_RCVD狀態,並對客戶端進行訊息回覆;

                          4、客戶端收到此條訊息後,轉為ESTABLISHED狀態,併發送一個ACK的確認訊息。

                          5、服務端收到此條訊息後,轉為ESTABLISHED狀態。

    至此,三次握手完成。

    然而,聰明的你,通過上面的分析,你可能會得到這樣的結論:accept()發生在第3步,原因是,此時accept()函式需要給此次連線分配資源。的確,最初是想這樣設計的。但是,設想一個情景,若有10000個客戶端都和該服務端進行連線,傳送SYN,服務端收到之後,這些客戶端卻不再理會服務端的回覆,然而此時服務端的資源卻都用accept()分配了。這就是所謂的“DDOS攻擊”。

    為了解決這個問題,accept()於是被放在三次握手之後。

    當然,這樣也不能保證不能被攻擊,當然這是後話。