TCP/IP這本書講TCP鏈接是如何創建和終止的?

把書讀薄(TCP/IP詳解 卷一 第十八章)服務器

TCP的三次握手是過程是怎樣的?

image

  1. 請求端(客戶端)發起第一個SYN,執行主動打開,表示想要鏈接服務端,同時指明初始序號(ISN,好比這裏的141553152)
  2. 服務端作出迴應,指明本身的初始序號,執行被動打開,同時將確認序號設置成對客戶端的初始序號加1,表示確認了客戶端的SYN
  3. 客戶端將確認序號設置成服務端的初始序號加1,表示確認了服務端的SYN
ISN:初始序號,能夠看作是一個32比特的計數器,每4ms加1,詳見RFC 793

TCP的四次揮手過程是怎樣的?

image

  1. 請求端(客戶端)想斷開鏈接,因而發出一個FIN包
  2. 服務端接收到請求,在確認序號上對客戶端的序號加1表示已確認
  3. 服務端關閉本身的鏈接,發出一個FIN包
  4. 客戶端接收到請求,在確認序號上對服務端序號加1表示已經確認
TCP鏈接是全雙工的,每一個方向都必須單獨關閉

創建鏈接時若是超時了會發生什麼事情?

image

出現場景網絡

服務器在客戶端創建鏈接時恰好斷電。能夠看出客戶端進行了重試,可是重試之間的時間間隔第一次是5.81秒,而第二次間隔是24.00秒。併發

這種超時重試時間間隔對於BSD版的TCP軟件實現來說,是因爲500ms的定時器存在。第一次的間隔通常在5.5-6秒任意時刻超時,而第二次通常穩定在24秒。這是因爲TCP在500ms之內得到系統控制的瞬間,可能系統會優先處理其它中斷,從而第一次計數器減1會發生在0-500ms的任意一個時刻。而每次TCP 500ms定時器被內核調用時都會修正,於是後續穩定tcp

tos 0x10 表示IP數據報內的服務類型,這裏的值爲DNS的udp查詢

異常終止鏈接會發生什麼事情?

鏈接一方發送復位報文來中途釋放鏈接【正常是發送FIN】spa

異常釋放的一端將返回RST報文段,收到的一方將終止鏈接,並通知應用層進行復位,接收方並不對RST報文進行確認。設計

什麼是TCP的半關閉?

TCP的一端結束髮送後,仍然能接收另外一端發送的數據。排序

應用場景隊列

想僅進行一次排序的操做。流程爲從客戶端讀取用戶輸入的文件,從服務端進行排序,而後客戶端接收排序的結果。對於客戶端來說,當文件傳輸完畢以後不會再發送數據,此時能夠直接關閉,而服務端須要先對數據拍完序,再作迴應,此時客戶端要保持接收數據的能力,這樣就適合使用半關閉(服務端通知客戶端也可使用另外1次TCP鏈接,可是半關閉能夠省掉多餘1次的鏈接過程)進程

什麼是TCP的半打開?

鏈接的一端已經關閉或異常終止,可是另外一端確不知道這個狀況。圖片

出現場景

客戶端和服務端正在正常通訊的時候,忽然服務器斷電了,這個時候客戶端並不知道服務器斷電,對於這種狀況,若是服務器當即恢復電源再立馬重啓,當客戶端在服務器重啓以後發送數據時,服務端則回覆復位標識,即TCP的標識位R設置爲1,客戶端收到信息,知曉鏈接終止

相似場景:客戶使用完本身的電腦,直接把電腦電源線拔了,這時服務器並不知道客戶端已經消失,後續客戶端再開機又會創建新的鏈接,這樣致使服務器會存在許多半打開的鏈接

若是TCP兩端同時打開會怎麼樣?

通訊雙方發送的SYN同時到達對方,且一端發送的端口和另外一端要求接收的端口同樣。

出現場景

主機A應用程序使用本地端口7777,與主機B端口8888執行主動打開,主機B應用程序則使用本地端口8888,與主機A端口7777執行主動打開

報文狀態變遷以下

圖片描述

整個過程打開須要4次報文段交換,tcp自己的設計保證,這種場景僅創建了1個鏈接

其它協議族可能創建兩條,好比OSI運輸層

若是TCP兩端同時關閉會怎麼樣?

通訊雙方都執行主動關閉。狀態變化以下:

圖片描述

交換的報文段和正常的關閉使用的數目同樣。

TCP的狀體變遷過程是怎樣的?

3次握手的狀態變遷

圖片描述

鏈接創建超時狀態變遷

圖片描述

同時打開狀態變遷

圖片描述

4次揮手狀態變遷

圖片描述

同時關閉狀態變遷

圖片描述

收到RST的可能狀態變遷

RST發生通常是接收端收到的包很明顯和當前鏈接沒有啥關係,這時候就觸發RST包產生

  • 因爲某種未知因素,客戶端發出的SYN屢次,可是服務端接收到的倒是舊的SYN,這時候客戶端發出RST,服務端收到RST從新建鏈接

圖片描述

  • 處於半打開狀態,鏈接已經創建的時候,忽然客戶端掛了,這時當客戶端嘗試再次打開鏈接或者服務端再次發送數據都會讓服務端收到

圖片描述

上圖爲客戶端CRASH而後客戶端重連,下圖爲客戶端CRASH而後服務端向客戶端返回數據

圖片描述

從SYN_RECEVIED狀態進入FIN_WAIT_1狀態

此時沒有須要發送的東西,隊列中也沒有未完成的東西須要發送,就生成一個FIN包,發送出去,斷開鏈接

有要發送的東西,好比ack,就去創建鏈接

2MSL等待時間是什麼?

MSL(Maximum Segment Lifetime)是報文段的最大生存時間。

生存時間是有限的,因爲TCP報文段是以IP數據報在網絡內傳輸,而IP數據報經過TTL的跳數限制,於是報文段被丟棄以前,在網絡內生存時間有限

當TCP執行主動關閉併發回最後一個ACK,該鏈接必須在TIME_WAIT狀態內等待2倍的MSL時間。

緣由:1:TCP主動關閉端發送的ACK若是丟失了,被動關閉端再次重發FIN,這時候的時間等待可以使得TCP主動關閉端發送最後的ACK不會丟失;2下次新的鏈接可能會複用同一個端口,若是因爲網絡延遲,老的數據纔到,會與新數據發生混合,等待2MSL可使得老數據徹底消失

在2MSL時間段以內,定義這個鏈接的插口(客戶端IP和端口,服務端IP和端口),不能再被 被動斷開方使用

若是服務端的鏈接忽然斷開再立馬從新啓動,服務器的這個端口在2MSL時間內客戶端沒法鏈接【這裏客戶端是被動斷開方】;同理若是是客戶端本身斷開,再立馬使用相同的端口,在2MSL時間內去連服務器也是沒法成功的【這裏服務器是被動斷開方】。這種場景客戶端能夠再隨便換一個端口便可,可是服務端的通常應用端口都是固定的,容易形成麻煩

若是多個請求同時到達服務端,服務端是如何處理的?

TCP服務器會專門安排一個進程,它永遠處於LISTEN狀態,用來接收客戶端的請求,當請求被接收時,系統中的TCP模塊就會建立一個處於ESTABLISHED狀態的進程

處於LISTEN狀態的進程不能接收數據報文段,處於ESTABLISHED狀態進程不能接收SYN報文段

伯克利TCP實現多鏈接處理規則爲:

  1. 正等待鏈接請求一端有一個固定長度的鏈接隊列,隊列中的鏈接已被TCP接受,可是應用層尚未感知
  2. 應用層指明改隊列的最大長度,它一般稱爲積壓值(backlog),取值範圍是0-5
  3. 新鏈接到達時,若是鏈接隊列有空間,TCP模塊將對SYN進行確認並完成鏈接創建。但應用層只有在3次握手的第3次報文段接收到後才知道這個新鏈接
  4. 新鏈接到達,可是鏈接隊列沒有空間,TCP模塊不理會SYN,也不發回RST,若是應用層沒有及時接受已被該TCP接受的鏈接,鏈接佔滿,客戶端的主動打開最終將超時
TCP接收鏈接是放入鏈接隊列,應用層接收鏈接是從隊列中移除

隊列的積壓數與服務器能處理的最大鏈接數沒有關係

相關文章
相關標籤/搜索