簡述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及以前的字節已經收到。

                                SYN:當本字段為1時,表示這是一個連接請求或者連接接受報文。

                                ACK:僅當本字段為1時,確認號才有效。

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



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

                運輸連接具有三個階段:連接建立、數據傳送以及連接釋放。運輸連接管理就是對連接建立以及連接釋放過程的管控,使得其能正常運行,達到這些目的:使通信雙方能夠確知對方的存在、可以允許通信雙方協商一些參數(最大報文段長度、最大窗口大小等等)、能夠對運輸實體資源進行分配(緩存大小等)。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:關閉狀態



                統一解釋幾個問題:

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

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


                        2、在結束連接的過程中,為什么在收到服務器端的連接釋放報文段之后,客戶端還要繼續等待2MSL之后才真正關閉TCP連接呢?

                              這里有兩個原因:第一個是:需要保證服務器端收到了客戶端的最后一條確認報文。假如這條報文丟失,服務器沒有接收到確認報文,就會對連接釋放報文進行超時重傳,而此時客戶端連接已關閉,無法做出響應,就造成了服務器端不停重傳連接釋放報文,而無法正常進入關閉狀態的狀況。而等待2MSL,就可以保證服務器端收到了最終確認;若服務器端沒有收到,那么在2MSL之內客戶端一定會收到服務器端的重傳報文,此時客戶端就會重傳確認報文,並重置計時器。

                                                          第二個是:存在一種“已失效的連接請求報文段”,需要避免這種報文端出現在本連接中,造成異常。  

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


                        3、若通信雙方同時請求連接或同時請求釋放連接,情況如何?

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

        


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


免責聲明!

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



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