探究 tcp 協議中的三次握手與四次揮手

OSI

OSI是Open System Interconnection的縮寫,意爲開放式系統互聯。國際標準化組織(ISO)制定了OSI模型,該模型定義了不一樣計算機互聯的標準,是設計和描述計算機網絡通訊的基本框架。OSI模型把網絡通訊的工做分爲7層,分別是物理層、數據鏈路層、網絡層、傳輸層、會話層、表示層和應用層。 首先來看看OSI的七層模型:面試

咱們須要知道TCP工做在網絡OSI的七層模型中的第四層——Transport層,IP在第三層——Network層,ARP 在第二層——Data Link層;在第二層上的數據,咱們把它叫Frame,在第三層上的數據叫Packet,第四層的數 據叫Segment。 同時,咱們須要簡單的知道,數據從應用層發下來,會在每一層都會加上頭部信息,進行 封裝,而後再發送到數據接收端。這個基本的流程你須要知道,就是每一個數據都會通過數據的封裝和解封 裝的過程。 在OSI七層模型中,每一層的做用和對應的協議以下:安全

TCP/IP 參考模型

TCP/IP是傳輸控制協議/網絡互聯協議的簡稱。早期的TCP/IP模型是一個四層結構,從下往上依次是網絡接口層、互聯網層、傳輸層和應用層。後來在使用過程當中,借鑑OSI七層參考模型,將網絡接口層劃分爲了物理層和數據鏈路層,造成五層結構。服務器

TCP是一個協議,那這個協議是如何定義的,它的數據格式是什麼樣子的呢?要進行更深層次的剖析,就 須要瞭解,甚至是熟記TCP協議中每一個字段的含義。

上面就是TCP協議頭部的格式,因爲它過重要了,是理解其它內容的基礎,下面就將每一個字段的信息都詳 細的說明一下。網絡

Source Port和Destination Port:分別佔用16位,表示源端口號和目的端口號;用於區別主機中的不一樣進程, 而IP地址是用來區分不一樣的主機的,源端口號和目的端口號配合上IP首部中的源IP地址和目的IP地址就能惟一 的肯定一個TCP鏈接;併發

Sequence Number:用來標識從TCP發端向TCP收端發送的數據字節流,它表示在這個報文段中的的第一個數據 字節在數據流中的序號;主要用來解決網絡報亂序的問題;框架

Acknowledgment Number:32位確認序列號包含發送確認的一端所指望收到的下一個序號,所以,確認序號應 當是上次已成功收到數據字節序號加1。不過,只有當標誌位中的ACK標誌(下面介紹)爲1時該確認序列號的字 段纔有效。主要用來解決不丟包的問題;學習

Offset:給出首部中32 bit字的數目,須要這個值是由於任選字段的長度是可變的。這個字段佔4bit(最多能 表示15個32bit的的字,即4*15=60個字節的首部長度),所以TCP最多有60字節的首部。然而,沒有任選字段, 正常的長度是20字節;計算機網絡

TCP Flags:TCP首部中有6個標誌比特,它們中的多個可同時被設置爲1,主要是用於操控TCP的狀態機的,依次 爲URG,ACK,PSH,RST,SYN,FIN。每一個標誌位的意思以下:設計

URG:此標誌表示TCP包的緊急指針域(後面立刻就要說到)有效,用來保證TCP鏈接不被中斷,而且督促 中間層設備要儘快處理這些數據;3d

ACK:此標誌表示應答域有效,就是說前面所說的TCP應答號將會包含在TCP數據包中;有兩個取值:0和1, 爲1的時候表示應答域有效,反之爲0;

PSH:這個標誌位表示Push操做。所謂Push操做就是指在數據包到達接收端之後,當即傳送給應用程序, 而不是在緩衝區中排隊;

RST:這個標誌表示鏈接復位請求。用來複位那些產生錯誤的鏈接,也被用來拒絕錯誤和非法的數據包;

SYN:表示同步序號,用來創建鏈接。SYN標誌位和ACK標誌位搭配使用,當鏈接請求的時候,SYN=1, ACK=0;鏈接被響應的時候,SYN=1,ACK=1;這個標誌的數據包常常被用來進行端口掃描。掃描者發送 一個只有SYN的數據包,若是對方主機響應了一個數據包回來 ,就代表這臺主機存在這個端口;可是因爲這 種掃描方式只是進行TCP三次握手的第一次握手,所以這種掃描的成功表示被掃描的機器不很安全,一臺安全 的主機將會強制要求一個鏈接嚴格的進行TCP的三次握手;

FIN: 表示發送端已經達到數據末尾,也就是說雙方的數據傳送完成,沒有數據能夠傳送了,發送FIN標誌 位的TCP數據包後,鏈接將被斷開。這個標誌的數據包也常常被用於進行端口掃描。

Window:窗口大小,也就是有名的滑動窗口,用來進行流量控制;這是一個複雜的問題,這篇博文中並不會進行 總結的;

好了,基本知識都已經準備好了,開始下一段的征程吧。

三次握手又是什麼?

TCP是面向鏈接的,不管哪一方向另外一方發送數據以前,都必須先在雙方之間創建一條鏈接。在TCP/IP協議中,TCP 協議提供可靠的鏈接服務,鏈接是經過三次握手進行初始化的。三次握手的目的是同步鏈接雙方的序列號和確認號 並交換 TCP窗口大小信息。這就是面試中常常會被問到的TCP三次握手。只是瞭解TCP三次握手的 概念,對你得到一份工做是沒有任何幫助的,你須要去了解TCP三次握手中的一些細節。先來看圖說話。

1.第一次握手:創建鏈接。客戶端發送鏈接請求報文段,將SYN位置爲1,Sequence Number爲x;而後,客戶端進入SYN_SEND狀態,等待服務器的確認;

2.第二次握手:服務器收到SYN報文段。服務器收到客戶端的SYN報文段,須要對這個SYN報文段進行確認,設置Acknowledgment Number爲x+1(Sequence Number+1);同時,本身本身還要發送SYN請求信息,將SYN位置爲1,Sequence Number爲y;服務器端將上述全部信息放到一個報文段(即SYN+ACK報文段)中,一併發送給客戶端,此時服務器進入SYN_RECV狀態;

3.第三次握手:客戶端收到服務器的SYN+ACK報文段。而後將Acknowledgment Number設置爲y+1,向服務器發送ACK報文段,這個報文段發送完畢之後,客戶端和服務器端都進入ESTABLISHED狀態,完成TCP三次握手。

完成了三次握手,客戶端和服務器端就能夠開始傳送數據。以上就是TCP三次握手的整體介紹。

那四次分手呢?

當客戶端和服務器經過三次握手創建了TCP鏈接之後,當數據傳送完畢,確定是要斷開TCP鏈接的啊。那對於TCP的斷開鏈接,這裏就有了神祕的「四次分手」。

1.第一次分手:主機1(可使客戶端,也能夠是服務器端),設置Sequence Number和Acknowledgment Number,向主機2發送一個FIN報文段;此時,主機1進入FIN_WAIT_1狀態;這表示主機1沒有數據要發送給主機2了;

2.第二次分手:主機2收到了主機1發送的FIN報文段,向主機1回一個ACK報文段,Acknowledgment Number爲Sequence Number加1;主機1進入FIN_WAIT_2狀態;主機2告訴主機1,我也沒有數據要發送了,能夠進行關閉鏈接了;

3.第三次分手:主機2向主機1發送FIN報文段,請求關閉鏈接,同時主機2進入CLOSE_WAIT狀態;

4.第四次分手:主機1收到主機2發送的FIN報文段,向主機2發送ACK報文段,而後主機1進入TIME_WAIT狀態;主機2收到主機1的ACK報文段之後,就關閉鏈接;此時,主機1等待2MSL後依然沒有收到回覆,則證實Server端已正常關閉,那好,主機1也能夠關閉鏈接了。

至此,TCP的四次分手就這麼愉快的完成了。當你看到這裏,你的腦子裏會有不少的疑問,不少的不懂,感受很凌亂;沒事,咱們繼續總結。

爲何要三次握手?

既然總結了TCP的三次握手,那爲何非要三次呢?怎麼以爲兩次就能夠完成了。那TCP爲何非要進行三次鏈接呢?在謝希仁的《計算機網絡》中是這樣說的:

爲了防止已失效的鏈接請求報文段忽然又傳送到了服務端,於是產生錯誤。

在書中同時舉了一個例子,以下:

"已失效的鏈接請求報文段」的產生在這樣一種狀況下:client發出的第一個鏈接請求報文段並無丟失,

而是在某個網絡結點長時間的滯留了,以至延誤到鏈接釋放之後的某個時間纔到達server。原本這是一

個早已失效的報文段。但server收到此失效的鏈接請求報文段後,就誤認爲是client再次發出的一個新

的鏈接請求。因而就向client發出確認報文段,贊成創建鏈接。假設不採用「三次握手」,那麼只要server

發出確認,新的鏈接就創建了。因爲如今client並無發出創建鏈接的請求,所以不會理睬server的確認,

也不會向server發送數據。但server卻覺得新的運輸鏈接已經創建,並一直等待client發來數據。這樣,

server的不少資源就白白浪費掉了。採用「三次握手」的辦法能夠防止上述現象發生。例如剛纔那種狀況,

client不會向server的確認發出確認。server因爲收不到確認,就知道client並無要求創建鏈接。"

這就很明白了,防止了服務器端的一直等待而浪費資源。

爲何要四次分手?

那四次分手又是爲什麼呢?TCP協議是一種面向鏈接的、可靠的、基於字節流的運輸層通訊協議。TCP是全雙工 模式,這就意味着,當主機1發出FIN報文段時,只是表示主機1已經沒有數據要發送了,主機1告訴主機2, 它的數據已經所有發送完畢了;可是,這個時候主機1仍是能夠接受來自主機2的數據;當主機2返回ACK報文 段時,表示它已經知道主機1沒有數據發送了,可是主機2仍是能夠發送數據到主機1的;當主機2也發送了FIN 報文段時,這個時候就表示主機2也沒有數據要發送了,就會告訴主機1,我也沒有數據要發送了,以後彼此 就會愉快的中斷此次TCP鏈接。若是要正確的理解四次分手的原理,就須要瞭解四次分手過程當中的狀態變化。

FIN_WAIT_1: 這個狀態要好好解釋一下,其實FIN_WAIT_1和FIN_WAIT_2狀態的真正含義都是表示等 待對方的FIN報文。而這兩種狀態的區別是:FIN_WAIT_1狀態其實是當SOCKET在ESTABLISHED狀態時, 它想主動關閉鏈接,向對方發送了FIN報文,此時該SOCKET即進入到FIN_WAIT_1狀態。而當對方迴應ACK報 文後,則進入到FIN_WAIT_2狀態,固然在實際的正常狀況下,不管對方何種狀況下,都應該立刻迴應ACK 報文,因此FIN_WAIT_1狀態通常是比較難見到的,而FIN_WAIT_2狀態還有時經常能夠用netstat看到。 (主動方)

FIN_WAIT_2:上面已經詳細解釋了這種狀態,實際上FIN_WAIT_2狀態下的SOCKET,表示半鏈接,也即 有一方要求close鏈接,但另外還告訴對方,我暫時還有點數據須要傳送給你(ACK信息),稍後再關閉鏈接。 (主動方)

CLOSE_WAIT:這種狀態的含義實際上是表示在等待關閉。怎麼理解呢?當對方close一個SOCKET後發送FIN 報文給本身,你係統毫無疑問地會迴應一個ACK報文給對方,此時則進入到CLOSE_WAIT狀態。接下來呢,實 際上你真正須要考慮的事情是察看你是否還有數據發送給對方,若是沒有的話,那麼你也就能夠 close這個 SOCKET,發送FIN報文給對方,也即關閉鏈接。因此你在CLOSE_WAIT狀態下,須要完成的事情是等待你去關 閉鏈接。(被動方)

LAST_ACK: 這個狀態仍是比較容易好理解的,它是被動關閉一方在發送FIN報文後,最後等待對方的ACK報 文。當收到ACK報文後,也便可以進入到CLOSED可用狀態了。(被動方)

TIME_WAIT: 表示收到了對方的FIN報文,併發送出了ACK報文,就等2MSL後便可回到CLOSED可用狀態了。 若是FINWAIT1狀態下,收到了對方同時帶FIN標誌和ACK標誌的報文時,能夠直接進入到TIME_WAIT狀態,而無 須通過FIN_WAIT_2狀態。(主動方)

CLOSED: 表示鏈接中斷。

爲何 TIME_WAIT 狀態要等待 2MSL 以後才關閉鏈接

一、2MSL表示兩個MSL的時長,MSL全稱爲Maximum Segment Life,表示TCP 對TCP Segment 生存時間的限制。

二、爲了保證主動關閉方A發送的最後一個ACK報文段可以到達被動關閉方B。這個ACK報文段有可能丟失,於是使處在LAST_ACK狀態的B收不到對本身已發送的FIN+ACK報文段的確認。B會超時重傳這個FIN+ACK報文段。而A就能在2MSL時間內收到這個重傳的FIN+ACK報文段。接着A重傳一次確認,從新啓動2MSL計時器。最後A和B都正常進入到CLOSED狀態。若是A在TIME_WAIT狀態不等待一段時間,而是在發送完ACK報文段後當即釋放鏈接,那麼就沒法收到B重傳的FIN+ACK報文段,於是也不會在發送一次確認報文段。這樣,B就沒法按照正常步驟進入CLOSED狀態。

三、防止已失效的鏈接請求報文段出如今本鏈接中。A在發送完最後一個ACK報文段後,在通過2MSL,就可使本鏈接持續的時間內所產生的全部報文段都從網絡中消失。這樣就可使下一個新的鏈接中不會出現這種舊的鏈接請求報文段。

總結到這裏,也該結束了,可是對於TCP的學習遠尚未結束。TCP是一個很是複雜的協議,這裏稍微總結了一 下TCP的鏈接與斷開鏈接是發生的事情,不足之處,敬請賜教。

相關文章
相關標籤/搜索