一。爲何建連接要3次握手,斷連接須要4次揮手?html
二。服務器保持了大量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 systems》async
三。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,有這麼幾個好處:
知道這些東西能夠很好得幫助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片斷丟失。