套接字選項SO_RESUEADDR
即使端口處于2MSL狀態(tài),使用該選項,仍然能夠在該端口建立連接。
服務(wù)器常會設(shè)置該選項薄嫡,以防服務(wù)器重啟。
TIME_WAIT狀態(tài)時收到數(shù)據(jù)
時間等待錯誤
如果在TIME_WAIT時間內(nèi)谈飒,收到了對端發(fā)送來的數(shù)據(jù)報(不是重置報文段都行)岂座,那么該狀態(tài)將被破壞,稱為時間等待錯誤杭措。原因是费什,當(dāng)收到報文段以后,通常Seq是舊的,所以本端就會發(fā)送ACK鸳址,對端已經(jīng)關(guān)閉或者是別的連接瘩蚪,就會發(fā)送RST,導(dǎo)致TIME_WAIT狀態(tài)被破壞稿黍。
但是許多系統(tǒng)規(guī)定疹瘦,TIME_WAIT狀態(tài)是不對重置報文段做出反應(yīng)。
同時關(guān)閉
兩端同時發(fā)送FIN巡球,兩端又同時ACK言沐。又同時進(jìn)入TIME_WAIT
異常連接狀態(tài)及處理
非常規(guī)的11中狀態(tài),可能因為進(jìn)程崩潰或是其他原因之類的
靜默時間
當(dāng)處于TIME_WAIT的主機(jī)崩潰以后酣栈,重啟险胰,然后需要等待相當(dāng)與一個MSL的時間才能建立新的連接。
這段時間成為靜默時間矿筝。
重置報文段
當(dāng)一段發(fā)現(xiàn)到達(dá)的報文段對相關(guān)連接(也就是進(jìn)程起便,套接字對)而言不正確的時候,TCP就會發(fā)送一個重置報文段窖维,從而導(dǎo)致對端的連接快速拆卸(也就是結(jié)束吧S茏邸)。
重置報文段要求
重置報文段的ACK位必須有铸史,而且ACK的值必須在正確的窗口范圍內(nèi)鼻疮,這樣可以防止被攻擊。
重置報文終止與FIN終止
FIN正常關(guān)閉一條連接成為有序釋放沛贪,通常不會出現(xiàn)丟失數(shù)據(jù)的情況陋守。
重置報文段終止一條連接成為終止釋放震贵。重置報文段在任何時候都可以發(fā)送利赋,代替FIN來終止連接,且不學(xué)校對端ACK
終止報文段特性:
- 任何排隊的數(shù)據(jù)都將被拋棄猩系,一個重置報文段立即被發(fā)出媚送。
- 重置報文段的接收方會說明通信另一端采用了終止連接的方式而不是一次正常關(guān)閉。API必須提供一種實現(xiàn)上述終止行為的方式取代正常的關(guān)閉連接
發(fā)生情況
- 對沒有在監(jiān)聽的端口發(fā)起連接請求
當(dāng)連接請求到一端的時候寇甸,該端沒的端口上沒有進(jìn)程在監(jiān)聽塘偎,TCP的話就會發(fā)從一個重置報文段。而UDP則會生成一個目標(biāo)地不可達(dá)的ICMP拿霉。 -
半開鏈接
通信一端崩潰又重啟吟秩,此時如果對端發(fā)送信息,那么本端會發(fā)送重置報文绽淘。
套接字選項SO_LINGER
此選項指定函數(shù)close對面向連接的協(xié)議如何操作(如TCP)涵防。內(nèi)核缺省close操作是立即返回,如果有數(shù)據(jù)殘留在套接口緩沖區(qū)中則系統(tǒng)將試著將這些數(shù)據(jù)發(fā)送給對方沪铭。
參考文章1壮池,參考文章2
當(dāng)該數(shù)值設(shè)置為0偏瓤,那么也意味著,不會再連接終止之前為了確保本端緩存中的數(shù)據(jù)都發(fā)送出去而等待椰憋。
TCP超時重傳
TCP擁有兩套獨立雞翅來完成重傳厅克,一、基于時間橙依,二证舟、給予確認(rèn)信息ACK
TCP在發(fā)送數(shù)據(jù)時會設(shè)置計時器,如果計時器超時認(rèn)為受到數(shù)據(jù)確認(rèn)信息窗骑,就會引發(fā)相應(yīng)的超時褪储,或給予計時器的重傳操作,計時器超時時成為重傳超時(RTO)慧域。
TCP累計確認(rèn)無法返回新的ACK鲤竹,或者當(dāng)ACK包含選擇確認(rèn)信息(SACK)時,表明出現(xiàn)書序數(shù)據(jù)報昔榴,空洞辛藻。就會引起快速重傳。
基于時間的超時重傳
超時重傳計時器的設(shè)置
TCP超時和重傳的基礎(chǔ)是如何根據(jù)給點連接RTT設(shè)置RTO互订。
若RTO短與RTT吱肌,那么沒分都會重傳,反之仰禽,整個網(wǎng)絡(luò)利用率就會隨之下降氮墨。
RTT樣本:TCP在收到數(shù)據(jù)后會返回確認(rèn)信息ACK,該信息中攜帶一個字節(jié)的數(shù)據(jù)吐葵,測量傳輸該確認(rèn)需要的時間规揪,該測量結(jié)果成為RTT樣本。
每個連接的RTT軍獨立計算温峭。
如何根據(jù)RTT來設(shè)置RTO猛铅,有如下的方法
經(jīng)典方法
平滑RTT估計值SRTT
公式:SRTT=a*SRTT+(1-a)RTT
,a取0.8-0.9
凤藏。
當(dāng)TCP運行在RTT變化較大的網(wǎng)絡(luò)中奸忽,無法取得期望的結(jié)果。
標(biāo)準(zhǔn)方法
以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)
快速重傳
帶選擇確認(rèn)的重傳
偽超時與重傳
因為丟失ACK揖庄,或者實際RTT顯著增長栗菜,可能出現(xiàn)偽超時的現(xiàn)象。
以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)
包失序與包重復(fù)
造成包失序的原因
每個包可以選擇各自的傳送路徑蹄梢。某些高級路由器的采用多個并行數(shù)據(jù)鏈路疙筹,不同的處理演示也會導(dǎo)致包的離開順序和到達(dá)順序不匹配
包的失序會造成重傳,很近單嘛,前面一個小號的Seq沒到達(dá)腌歉,后面的先到達(dá)蛙酪,那么ACK就會 重復(fù)
包重復(fù)
包重組
當(dāng)TCP超時重發(fā)是,循序執(zhí)行重新租寶翘盖,發(fā)送送一個更大的報文段提高性能桂塞,不超過MSS和MTU。
出現(xiàn)在每次傳送的包較小馍驯,又丟包的情況
數(shù)據(jù)流與窗口管理
交互式通信
SSH
每個交互鍵通常會生成一個單獨的數(shù)據(jù)報阁危,也就是每個按鍵是獨立傳輸?shù)摹?br> ssh調(diào)用一個shell,對客戶端輸入的字符做出輝縣汰瘫,因此狂打,每個字符生成4個tcp數(shù)據(jù)段,客戶端的交互按鍵輸入混弥,服務(wù)器對按鍵的ACK趴乡,服務(wù)器生成的輝縣,客戶端對回顯的ACK蝗拿。通常第二段和第三段合并晾捏,成為捎帶延時確認(rèn)。
PSH位設(shè)置哀托,意味著發(fā)送端的緩存為空惦辛,也就是沒什么可以發(fā)送了。
延時確認(rèn)
許多情況下仓手,TCP并不是對每個到來的包都單獨的ACK胖齐,利用累計ACK可以確認(rèn)之前的ACK。累計確認(rèn)可以允許TCP延時一段時間發(fā)送ACK嗽冒,以便將ACK和相同方向上需要傳輸?shù)臄?shù)據(jù)結(jié)合發(fā)呀伙。這種捎帶傳輸?shù)姆椒ǔS糜谂繑?shù)據(jù)傳輸。
不能任意的延遲ACK辛慰,會造成重傳区匠。同時當(dāng)失序發(fā)生時干像,必須立刻傳送ACK帅腌。
系統(tǒng)可以設(shè)置,一般延時為200-600毫秒麻汰。
Nagle算法
該算法要求速客,當(dāng)TCP連接中有在傳數(shù)據(jù)(那些已發(fā)送,但是未確認(rèn)的數(shù)據(jù))時五鲫,小的報文段就不能被發(fā)送溺职,知道所有的數(shù)據(jù)都受到ACK。并且受到ACK后,TCP收集這些小的數(shù)據(jù)浪耘,整合到一個報文段中發(fā)送乱灵。
這種方法破事TCP遵循等停規(guī)程,只有收到所有傳送數(shù)據(jù)的ACK后才能繼續(xù)發(fā)送新數(shù)據(jù)七冲。
該算法的不同之處在于他實現(xiàn)了自時鐘控制痛倚,ACK返回越快,傳輸也越快澜躺。在相對高延遲的廣域網(wǎng)中蝉稳,更需要減小小報文的數(shù)目,該算法使得單位時間內(nèi)發(fā)送的報文數(shù)目更少掘鄙,RTT控制發(fā)包速率耘戚。
該算法減少小包數(shù)目的同時,也增大了傳輸時延操漠,也就是總的發(fā)送時間收津。
流量控制與窗口管理
窗口大小表明本端可用緩存大小,對端傳送的數(shù)據(jù)不應(yīng)該超過改大小浊伙。
也表明對端發(fā)送的數(shù)據(jù)的最大大小為TCP頭部ACK號和窗口大小字段之和朋截。
也就是Seq = ACK+MSS
滑動窗口
發(fā)送窗口
TCP活動的兩端都維護(hù)一個發(fā)送窗口結(jié)構(gòu)和接受窗口結(jié)構(gòu)。
TCP以字節(jié)為單位維護(hù)窗口結(jié)構(gòu)吧黄。
每個TCP報文段都包含ACK號和窗口通告信息部服,TCP發(fā)送端可以據(jù)此調(diào)節(jié)窗口結(jié)構(gòu)。
窗口左邊界不能左移拗慨。
窗口的動作分為廓八,關(guān)閉(收到ACK,左邊右移)赵抢,打開(MSS擴(kuò)大剧蹂,右邊右移),收縮(MSS減小烦却,右邊左移)
當(dāng)收到ACK號增大宠叼,而MSS不變時窗口向前滑動
當(dāng)當(dāng)左邊界與右邊界相等時,成為零窗口其爵,此時發(fā)送端不能在發(fā)送新的數(shù)據(jù)冒冬,這種情況下,TCP開始探測對端窗口摩渺,伺機(jī)增大窗口简烤。
接受窗口
接受窗口也有左邊界和右邊界,但窗口內(nèi)的字節(jié)并沒有區(qū)分摇幻,到達(dá)序號小于左邊便捷横侦,被認(rèn)為是重復(fù)的挥萌,丟棄!超過右邊界的則超出處理范圍枉侧,丟棄引瀑!只有Seq在窗口內(nèi)的包才能被確認(rèn),SACK的包也能被確認(rèn)榨馁,因為對端發(fā)送的包的最大大小為ACK+MSS伤疙,因此整個包的大小不會超過MSS,同時MSS一般都不是太小辆影,不會緩沖區(qū)溢出徒像。
因此,上面提到那些蛙讥,不同連接的包因為網(wǎng)絡(luò)阻塞锯蛀,最后又到達(dá)新連接的包,大概率是要被丟棄的次慢。
接受窗口只有收到左邊界序號的數(shù)據(jù)時才會向右滑動旁涤。
零窗口
當(dāng)接受窗口值變?yōu)?是,可以郵箱的組織發(fā)送端繼續(xù)發(fā)送迫像,知道窗口大小回復(fù)為非0值劈愚。當(dāng)接收端窗口得到可用空間是,就會給發(fā)送端傳輸一個窗口更新闻妓,告知器可以繼續(xù)發(fā)送數(shù)據(jù)菌羽,這樣的這樣的窗口更新通常不包含數(shù)據(jù),成為純ACK由缆,因此不能保證傳輸?shù)目煽啃浴?br>
如果一端的窗口更新ACK丟失注祖,通信雙方就會處于等待狀態(tài)。為避免這種情況發(fā)生均唉。發(fā)送端會采用一個持續(xù)計時器間歇性的查詢接收端是晨,看其窗口是否已經(jīng)增長。
持續(xù)計時器會觸發(fā)窗口探測的傳輸舔箭,強(qiáng)制要求對端返回ACK罩缴。窗口探測包包含一個字節(jié)數(shù)據(jù),采用TCP傳輸层扶,因此可以避免窗口更新丟失導(dǎo)致的死鎖箫章。因為包含一個字節(jié)數(shù)據(jù)Seq改變,接受端必須處理怒医,如果接受就會ACK炉抒。窗口大小還是0,那么就會丟棄該報稚叹,沒有響應(yīng)焰薄。這時候發(fā)送端會持續(xù)的發(fā)送窗口探測包。
糊涂窗口SWS
當(dāng)接收端通告窗口較小扒袖,或者發(fā)送端發(fā)送的數(shù)據(jù)較小塞茅。這樣數(shù)據(jù)報的有效攜帶率小,耗費網(wǎng)絡(luò)資源多季率。
避免方法
- 接收端
不應(yīng)該通告小的窗口值野瘦。這個沒看懂啊。 - 發(fā)送端
不應(yīng)發(fā)送曉得報文段飒泻,而應(yīng)該采用Nagle算法控制何時發(fā)送鞭光。直到:數(shù)據(jù)報到達(dá)MSS全場,或者數(shù)據(jù)段長度超過最大窗口值的一半泞遗。
緊急機(jī)制
以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)以后再補(bǔ)