簡述TCP鏈接的創建與釋放(三次握手、四次揮手)

        在介紹TCP鏈接的創建與釋放以前,先回顧一下相關知識。        前端

        TCP是面向鏈接的運輸層協議,它提供可靠交付的、全雙工的、面向字節流的點對點服務。HTTP協議即是基於TCP協議實現的。(雖然做爲應用層協議,HTTP協議並無明確要求必須使用TCP協議做爲運輸層協議,可是由於HTTP協議對可靠性的的要求,默認HTTP是基於TCP協議的。如果使用UDP這種不可靠的、盡最大努力交付的運輸層協議來實現HTTP的話,那麼TCP協議的流量控制、可靠性保障機制等等功能就必須所有放到應用層來實現)相比網絡層更進一步,運輸層着眼於應用進程間的通訊,而不是網絡層的主機間的通信。咱們常見的端口、套接字等概念就是由此而生。(端口表明主機上的一個應用進程、而套接字則是ip地址與端口號的合體,能夠在網絡範圍內惟一肯定一個應用進程) TCP協議的可靠傳輸是經過滑動窗口的方法實現的;擁塞控制則有着慢開始和擁塞避免、快重傳和快恢復、RED隨機早期檢測幾種辦法。(這幾個知識點在這裏就先不細緻總結了,你們能夠回顧計網課本23333)面試

        另外,TCP協議的報文格式也須要回顧一下: 緩存


                TCP報文段的首部分爲固定部分和選項部分,固定部分長20byte,而選項部分長度可變。(若整個首部長度不是4byte的整數倍的話,則須要用填充位來填充)在固定首部中,與本文密切相關的是如下幾項:服務器

                                seq(序號):TCP鏈接字節流中每個字節都會有一個編號,而本字段的值指的是本報文段所發送數據部分第一個字節的序號。
網絡

                                ack(確認號):表示指望收到的下一個報文段數據部分的第一個字節的編號,編號爲ack-1及之前的字節已經收到。spa

                                SYN:當本字段爲1時,表示這是一個鏈接請求或者鏈接接受報文。計算機網絡

                                ACK:僅當本字段爲1時,確認號纔有效。設計

                                FIN:用來釋放一個鏈接。當本字段爲1時,表示此報文段的發送端數據已發送完畢,要求釋放運輸鏈接。
進程



        下面就是本文的重點了:TCP的運輸鏈接管理。 ip

                運輸鏈接具備三個階段:鏈接創建、數據傳送以及鏈接釋放。運輸鏈接管理就是對鏈接創建以及鏈接釋放過程的管控,使得其能正常運行,達到這些目的:使通訊雙方可以確知對方的存在、能夠容許通訊雙方協商一些參數(最大報文段長度、最大窗口大小等等)、可以對運輸實體資源進行分配(緩存大小等)。TCP鏈接的創建採用客戶-服務器模式:主動發起鏈接創建的應用進程叫作客戶,被動等待鏈接創建的應用進程叫作服務器。

                鏈接創建階段:

                        第一次握手:客戶端的應用進程主動打開,並向客戶端發出請求報文段。其首部中:SYN=1,seq=x。

                        第二次握手:服務器應用進程被動打開。若贊成客戶端的請求,則發回確認報文,其首部中:SYN=1,ACK=1,ack=x+1,seq=y。

                        第三次握手:客戶端收到確認報文以後,通知上層應用進程鏈接已創建,並向服務器發出確認報文,其首部:ACK=1,ack=y+1。當服務器收到客戶端的確認報文以後,也通知其上層應用進程鏈接已創建。

                        在這個過程當中,通訊雙方的狀態以下圖,其中CLOSED:關閉狀態、LISTEN:收聽狀態、SYN-SENT:同步已發送、SYN-RCVD:同步收到、ESTAB-LISHED:鏈接已創建


                        至此,TCP鏈接就創建了,客戶端和服務器能夠愉快地玩耍了。只要通訊雙方沒有一方發出鏈接釋放的請求,鏈接就將一直保持。


                鏈接釋放階段:

                        第一次揮手:數據傳輸結束之後,客戶端的應用進程發出鏈接釋放報文段,並中止發送數據,其首部:FIN=1,seq=u。

                        第二次揮手:服務器端收到鏈接釋放報文段以後,發出確認報文,其首部:ack=u+1,seq=v。此時本次鏈接就進入了半關閉狀態,客戶端再也不向服務器發送數據。而服務器端仍會繼續發送。

                        第三次揮手:若服務器已經沒有要向客戶端發送的數據,其應用進程就通知服務器釋放TCP鏈接。這個階段服務器所發出的最後一個報文的首部應爲:FIN=1,ACK=1,seq=w,ack=u+1。

                        第四次揮手:客戶端收到鏈接釋放報文段以後,必須發出確認:ACK=1,seq=u+1,ack=w+1。 再通過2MSL(最長報文端壽命)後,本次TCP鏈接真正結束,通訊雙方完成了他們的告別。

                        在這個過程當中,通訊雙方的狀態以下圖,其中:ESTAB-LISHED:鏈接創建狀態、FIN-WAIT-1:終止等待1狀態、FIN-WAIT-2:終止等待2狀態、CLOSE-WAIT:關閉等待狀態、LAST-ACK:最後確認狀態、TIME-WAIT:時間等待狀態、CLOSED:關閉狀態



                統一解釋幾個問題:

                        一、在握手與揮手的過程當中,往復的ack與seq有什麼含義?

                              這是通訊雙方在通訊過程當中的一種確認手段,確保通訊雙方通訊的正確性。例如小時候模仿電視劇裏無線電呼叫的過程:「土豆土豆,我是地瓜,你能聽到嗎?」「地瓜地瓜,我是土豆,我能聽到」。 若客戶端的報文請求號爲「土豆」,則服務器端就將返回確認號「土豆+1」(標誌土豆已收到),是一種通訊雙方的確認手段。


                        二、在結束鏈接的過程當中,爲何在收到服務器端的鏈接釋放報文段以後,客戶端還要繼續等待2MSL以後才真正關閉TCP鏈接呢?

                              這裏有兩個緣由:第一個是:須要保證服務器端收到了客戶端的最後一條確認報文。假如這條報文丟失,服務器沒有接收到確認報文,就會對鏈接釋放報文進行超時重傳,而此時客戶端鏈接已關閉,沒法作出響應,就形成了服務器端不停重傳鏈接釋放報文,而沒法正常進入關閉狀態的情況。而等待2MSL,就能夠保證服務器端收到了最終確認;若服務器端沒有收到,那麼在2MSL以內客戶端必定會收到服務器端的重傳報文,此時客戶端就會重傳確認報文,並重置計時器。

                                                          第二個是:存在一種「已失效的鏈接請求報文段」,須要避免這種報文端出如今本鏈接中,形成異常。  

                                                                            這種「已失效的鏈接請求報文段」是這麼造成的:假如客戶端發出了鏈接請求報文,然而服務器端沒有收到,因而客戶端進行超時重傳,再一次發送了鏈接請求報文,併成功創建鏈接。然而,第一次發送的鏈接請求報文並無丟失,只是在某個網絡結點中發生了長時間滯留,隨後,這個最初發送的報文段到達服務器端,會使得服務器端誤覺得客戶端發出了新的請求,形成異常。


                        三、若通訊雙方同時請求鏈接或同時請求釋放鏈接,狀況如何?

                              這種狀況雖然發生的可能性極小,可是是確實存在的,TCP也特地設計了相關機制,使得在這種狀況下雙方僅創建一條鏈接。雙方同時請求鏈接的狀況下,雙方同時發出請求鏈接報文,並進入SYN-SENT狀態;當收到對方的請求鏈接報文後,會再次發送請求鏈接報文,確認號爲對方的SYN+1,並進入SYN-RCVD狀態;當收到對方第二次發出的攜帶確認號的請求報文以後,會進入ESTAB-LISHED狀態。 雙方同時請求釋放鏈接也是一樣的,雙方同時發出鏈接釋放報文,並進入FIN-WAIT-1狀態;在收到對方的報文以後,發送確認報文,並進入CLOSING狀態;在收到對方的確認報文後,進入TIME-WAIT狀態,等待2MSL以後關閉鏈接。須要注意的是,這個時候雖然不用再次發送確認報文並確認對方收到,雙方仍需等待2MSL以後再關閉鏈接,是爲了防止「已失效的鏈接請求報文段」的影響。 過程圖以下:

        


                這既是計算機網絡中的重要知識,也是前端技術筆試、面試中容易涉及的問題,特整理~

相關文章
相關標籤/搜索