tcp ,基礎概念 三次握手,4次揮手

一。爲何建連接要3次握手,斷連接須要4次揮手?html

  • 對於建連接的3次握手:主要是要初始化Sequence Number 的初始值。通訊的雙方要互相通知對方本身的初始化的Sequence Number(縮寫爲ISN:Inital Sequence Number)——因此叫SYN,全稱Synchronize Sequence Numbers。也就上圖中的 x 和 y。這個號要做爲之後的數據通訊的序號,以保證應用層接收到的數據不會由於網絡上的傳輸的問題而亂序(TCP會用這個序號來拼接數據)。
  • 對於4次揮手:其實你仔細看是2次,由於TCP是全雙工的,因此,發送方和接收方都須要Fin和Ack。只不過,有一方是被動的,因此看上去就成了所謂的4次揮手。若是兩邊同時斷鏈接,那就會就進入到CLOSING狀態,而後到達TIME_WAIT狀態。

二。服務器保持了大量TIME_WAIT狀態算法

這種狀況比較常見,一些爬蟲服務器或者WEB服務器(若是網管在安裝的時候沒有作內核參數優化的話)上常常會遇到這個問題,這個問題是怎麼產生的呢?緩存

從 上面的示意圖能夠看得出來,TIME_WAIT是主動關閉鏈接的一方保持的狀態,對於爬蟲服務器來講他自己就是「客戶端」,在完成一個爬取任務以後,他就 會發起主動關閉鏈接,從而進入TIME_WAIT的狀態,而後在保持這個狀態2MSL(max segment lifetime)時間以後,完全關閉回收資源。爲何要這麼作?明明就已經主動關閉鏈接了爲啥還要保持資源一段時間呢?這個是TCP/IP的設計者規定 的,主要出於如下兩個方面的考慮:服務器

1.防止上一次鏈接中的包,迷路後從新出現,影響新鏈接(通過2MSL,上一次鏈接中全部的重複包都會消失)
2. 可靠的關閉TCP鏈接。在主動關閉方發送的最後一個 ack(fin) ,有可能丟失,這時被動方會從新發fin, 若是這時主動方處於 CLOSED 狀態 ,就會響應 rst 而不是 ack。因此主動方要處於 TIME_WAIT 狀態,而不能是 CLOSED 。另外這麼設計TIME_WAIT 會定時的回收資源,並不會佔用很大資源的,除非短期內接受大量請求或者受到攻擊。網絡

三、經過上面的ISN的描述,相信你也知道MSL是怎麼來的了。咱們注意到,在TCP的狀態圖中,從TIME_WAIT狀態到CLOSED狀態,有一個超時設置,這個超時設置是 2*MSL(RFC793定義了MSL爲2分鐘,Linux設置成了30s)爲何要這有TIME_WAIT?爲何不直接給轉成CLOSED狀態呢?主要有兩個緣由:1)TIME_WAIT確保有足夠的時間讓對端收到了ACK,若是被動關閉的那方沒有收到Ack,就會觸發被動端重發Fin,一來一去正好2個MSL,2)有足夠的時間讓這個鏈接不會跟後面的鏈接混在一塊兒(你要知道,有些自作主張的路由器會緩存IP數據包,若是鏈接被重用了,那麼這些延遲收到的包就有可能會跟新鏈接混在一塊兒)。你能夠看看這篇文章《TIME_WAIT and its design implications for protocols and scalable client server systemsasync

三。TCP重傳機制tcp

TCP要保證全部的數據包均可以到達,因此,必須要有重傳機制。

注意:接收端給發送端的Ack確認只會確認最後一個連續的包,好比,發送端發了1,2,3,4,5一共五份數據,接收端收到了1,2,因而回ack 3,而後收到了4(注意此時3沒收到),此時的TCP會怎麼辦?咱們要知道,由於正如前面所說的,SeqNum和Ack是以字節數爲單位,因此ack的時候,不能跳着確認,只能確認最大的連續收到的包,否則,發送端就覺得以前的都收到了。優化

四。快速重傳機制命令行

因而,TCP引入了一種叫Fast Retransmit 的算法,不以時間驅動,而以數據驅動重傳。也就是說,若是,包沒有連續到達,就ack最後那個可能被丟了的包,若是發送方連續收到3次相同的ack,就重傳。Fast Retransmit的好處是不用等timeout了再重傳。

好比:若是發送方發出了1,2,3,4,5份數據,第一份先到送了,因而就ack回2,結果2由於某些緣由沒收到,3到達了,因而仍是ack回2,後面的4和5都到了,可是仍是ack回2,由於2仍是沒有收到,因而發送端收到了三個ack=2的確認,知道了2尚未到,因而就立刻重轉2。而後,接收端收到了2,此時由於3,4,5都收到了,因而ack回6。scala

五。D-SACK,有這麼幾個好處:
 

  • 1)可讓發送方知道,是發出去的包丟了,仍是回來的ACK包丟了。
  • 2)是否是本身的timeout過小了,致使重傳。
  • 3)網絡上出現了先發的包後到的狀況(又稱reordering)
  • 4)網絡上是否是把個人數據包給複製了。


知道這些東西能夠很好得幫助TCP瞭解網絡狀況,從而能夠更好的作網絡上的流控。Linux下的tcp_dsack參數用於開啓這個功能(Linux 2.4後默認打開)

 

1:滑動窗口

2:流量控制
3:擁塞控制
4:Nagle算法
5:捎帶ACK的發送方式
這個策略是說,當主機收到遠程主機的TCP數據報以後,一般不立刻發送ACK數據報,而是等上一個短暫的時間,若是這段時間裏面主機還有發送到遠程主機的TCP數據報,那麼就把這個ACK數據報「捎帶」着發送出去,把原本兩個TCP數據報整合成一個發送。通常的,這個時間是200ms。能夠明顯地看到這個策略能夠把TCP數據報的利用率提升不少。

6.白癡綜合徵

滑窗機制有可能犯病,好比白癡窗口綜合症(Silly Window Syndrome)。假設這樣一種情形:接收方發佈(advertise)一個小的窗口。發送方根據發佈的窗口大小,發送一個小的片斷。接收方的小窗口被填滿,通過處理,接收方再宣佈一個小的窗口…… 這就是「白癡窗口綜合症」:TCP通訊的片斷中包含的數據量很小。在這樣的狀況下,TCP通訊的片斷所含的信息都很小,網絡流量主要是TCP片斷的頭部,這樣頭重腳輕的TCP片斷,會形成網絡流量的浪費。
若是發送方不斷髮送小的片斷,也會形成白癡窗口。爲了解決這個問題,須要從兩方面入手。TCP中有相關的規定,要求:

1》. 接收方宣告的窗口必須達到必定的尺寸,不然等待。
2》. 除了一些特殊狀況,發送方發送的片斷必須達到必定的尺寸,不然等待。特殊狀況主要是指須要最小化延遲的TCP應用,好比命令行互動。

7. 重傳

接收方(receiver)能夠經過校驗TCP片斷頭部中校驗(checksum)區域來檢驗TCP片斷是否出錯。校驗區域所在位置以下圖所示。咱們已經接觸過了IP協議詳解的校驗算法。TCP片斷的校驗算法與之相似。IP協議只校驗頭部,TCP片斷頭部的校驗會校驗包括IP頭部、TCP頭部和TCP數據在內的整個序列,確保IP地址、端口號和其餘相關信息正確。若是TCP片斷出錯,接收方能夠簡單的丟棄改TCP片斷,也就至關於TCP片斷丟失。

 

 

 

相關文章
相關標籤/搜索