網上查了一下端口狀態的資料,我下面總結了一下,自己學習學習:
TCP狀態轉移要點
TCP協議規定,對於已經建立的連接,網絡雙方要進行四次握手才能成功斷開連接,如果缺少了其中某個步驟,將會使連接處於假死狀態,連接本身占用的資源不會被釋放。網絡服務器程序要同時管理大量連接,所以很有必要保證無用連接完全斷開,否則大量僵死的連接會浪費許多服務器資源。在眾多TCP狀態中,最值得注意的狀態有兩個:CLOSE_WAIT和TIME_WAIT。
1、LISTENING狀態
FTP服務啟動后首先處於偵聽(LISTENING)狀態。
2、ESTABLISHED狀態
ESTABLISHED的意思是建立連接。表示兩台機器正在通信。
3、CLOSE_WAIT
對方主動關閉連接或者網絡異常導致連接中斷,這時我方的狀態會變成CLOSE_WAIT 此時我方要調用close()來使得連接正確關閉
4、TIME_WAIT
我方主動調用close()斷開連接,收到對方確認后狀態變為TIME_WAIT。TCP協議規定TIME_WAIT狀態會一直持續2MSL(即兩倍的分段最大生存期),以此來確保舊的連接狀態不會對新連接產生影響。處於TIME_WAIT狀態的連接占用的資源不會被內核釋放,所以作為服務器,在可能的情況下,盡量不要主動斷開連接,以減少TIME_WAIT狀態造成的資源浪費。
目前有一種避免TIME_WAIT資源浪費的方法,就是關閉socket的LINGER選項。但這種做法是TCP協議不推薦使用的,在某些情況下這個操作可能會帶來錯誤。
socket的狀態
狀態變遷圖
TCP的三次握手和四次揮手
總結圖
左邊為客戶端的狀態轉變,后邊為服務器的狀態轉變。
三次握手
最開始的時候客戶端和服務器都是處於CLOSED狀態。主動打開連接的為客戶端,被動打開連接的是服務器。
TCP服務器進程先創建傳輸控制塊TCB,時刻准備接受客戶進程的連接請求,此時服務器就進入了**LISTEN(監聽)**狀態;
TCP客戶進程也是先創建傳輸控制塊TCB,然后向服務器發出連接請求報文,這是報文首部中的**同部位SYN=1,同時選擇一個初始序列號 seq=x **,此時,TCP客戶端進程進入了 SYN-SENT(同步已發送狀態)狀態。TCP規定,SYN報文段(SYN=1的報文段)不能攜帶數據,但需要消耗掉一個序號。
TCP服務器收到請求報文后,如果同意連接,則發出確認報文。確認報文中應該 ACK=1,SYN=1,確認號是ack=x+1,同時也要為自己初始化一個序列號 seq=y,此時,TCP服務器進程進入了**SYN-RCVD(同步收到)**狀態。這個報文也不能攜帶數據,但是同樣要消耗一個序號。
TCP客戶進程收到確認后,還要向服務器給出確認。確認報文的ACK=1,ack=y+1,自己的序列號seq=x+1,此時,TCP連接建立,客戶端進入**ESTABLISHED(已建立連接)**狀態。TCP規定,ACK報文段可以攜帶數據,但是如果不攜帶數據則不消耗序號。
當服務器收到客戶端的確認后也進入ESTABLISHED狀態,此后雙方就可以開始通信了。
三次握手主要目的是:信息對等和防止超時。防止超時導致臟連接。如果使用的是兩次握手建立連接,假設有這樣一種場景,客戶端發送了第一個請求連接並且沒有丟失,只是因為在網絡結點中滯留的時間太長了,由於TCP的客戶端遲遲沒有收到確認報文,以為服務器沒有收到,此時重新向服務器發送這條報文,此后客戶端和服務器經過兩次握手完成連接,傳輸數據,然后關閉連接。此時此前滯留的那一次請求連接,網絡通暢了到達了服務器,這個報文本該是失效的,但是,兩次握手的機制將會讓客戶端和服務器再次建立連接,這將導致不必要的錯誤和資源的浪費。如果采用的是三次握手,就算是那一次失效的報文傳送過來了,服務端接受到了那條失效報文並且回復了確認報文,但是客戶端不會再次發出確認。由於服務器收不到確認,就知道客戶端並沒有請求連接。
四次揮手
數據傳輸完畢后,雙方都可釋放連接。最開始的時候,客戶端和服務器都是處於ESTABLISHED狀態,然后客戶端主動關閉,服務器被動關閉。
客戶端進程發出連接釋放報文,並且停止發送數據。釋放數據報文首部,FIN=1,其序列號為seq=u(等於前面已經傳送過來的數據的最后一個字節的序號加1),此時,客戶端進入FIN-WAIT-1(終止等待1)狀態。 TCP規定,FIN報文段即使不攜帶數據,也要消耗一個序號。
服務器收到連接釋放報文,發出確認報文,ACK=1,ack=u+1,並且帶上自己的序列號seq=v,此時,服務端就進入了CLOSE-WAIT(關閉等待)狀態。TCP服務器通知高層的應用進程,客戶端向服務器的方向就釋放了,這時候處於半關閉狀態,即客戶端已經沒有數據要發送了,但是服務器若發送數據,客戶端依然要接受。這個狀態還要持續一段時間,也就是整個CLOSE-WAIT狀態持續的時間。
客戶端收到服務器的確認請求后,此時,客戶端就進入**FIN-WAIT-2(終止等待2)**狀態,等待服務器發送連接釋放報文(在這之前還需要接受服務器發送的最后的數據)。
服務器將最后的數據發送完畢后,就向客戶端發送連接釋放報文,FIN=1,ack=u+1,由於在半關閉狀態,服務器很可能又發送了一些數據,假定此時的序列號為seq=w,此時,服務器就進入了**LAST-ACK(最后確認)**狀態,等待客戶端的確認。
客戶端收到服務器的連接釋放報文后,必須發出確認,ACK=1,ack=w+1,而自己的序列號是seq=u+1,此時,客戶端就進入了TIME-WAIT(時間等待)狀態。注意此時TCP連接還沒有釋放,必須經過2MSL(最長報文段壽命)的時間后,當客戶端撤銷相應的TCB后,才進入CLOSED狀態。
服務器只要收到了客戶端發出的確認,立即進入CLOSED狀態。同樣,撤銷TCB后,就結束了這次的TCP連接。可以看到,服務器結束TCP連接的時間要比客戶端早一些。
TIME_WAIT:主動要求關閉的機器表示收到了對方的FIN報文,並發送出了ACK報文,進入TIME_WAIT狀態,等2MSL后即可進入到CLOSED狀態。如果FIN_WAIT_1狀態下,同時收到待FIN標識和ACK標識的報文時,可以直接進入TIME_WAIT狀態,而無需經過FIN_WAIT_2狀態。
CLOSE_WAIT:被動關閉的機器收到對方請求關閉連接的FIN報文,在第一次ACK應答后,馬上進入CLOSE_WAIT狀態。這種狀態其實標識在等待關閉,並且通知應用發送剩余數據,處理現場信息,關閉相關資源。
為什么客戶端最后還要等待2MSL?
MSL(Maximum Segment Lifetime),TCP允許不同的實現可以設置不同的MSL值。**第一,保證客戶端發送的最后一個ACK報文能夠到達服務器,因為這個ACK報文可能丟失。**站在服務器的角度看來,我已經發送了FIN+ACK報文請求斷開了,客戶端還沒有給我回應,應該是我發送的請求斷開報文它沒有收到,於是服務器又會重新發送一次,而客戶端就能在這個2MSL時間段內收到這個重傳的報文,接着給出回應報文,並且會重啟2MSL計時器。如果客戶端收到服務端的FIN+ACK報文后,發送一個ACK給服務端之后就“自私”地立馬進入CLOSED狀態,可能會導致服務端無法確認收到最后的ACK指令,也就無法進入CLOSED狀態,這是客戶端不負責任的表現。**第二,防止失效請求。**防止類似與“三次握手”中提到了的“已經失效的連接請求報文段”出現在本連接中。客戶端發送完最后一個確認報文后,在這個2MSL時間中,就可以使本連接持續的時間內所產生的所有報文段都從網絡中消失。這樣新的連接中不會出現舊連接的請求報文。
在TIME_WAIT狀態無法真正釋放句柄資源,在此期間,Socket中使用的本地端口在默認情況下不能再被使用。該限制對於客戶端機器來說是無所謂的,但對於高並發服務器來說,會極大地限制有效連接的創建數量,稱為性能瓶頸。所以建議將高並發服務器TIME_WAIT超時時間調小。RFC793中規定MSL為2分鍾。但是在當前的高速網絡中,2分鍾的等待時間會造成資源的極大浪費,在高並發服務器上通常會使用更小的值。
在服務器上通過變更/etc/sysctl.conf文件來修改該默認值net.ipv4.tcp_fin_timout=30(建議小30s)。修改完之后執行 /sbin/sysctl -p 讓參數生效。
通過如下命令查看各連接狀態的技術情況:
[root@node1 ~]# netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' TIME_WAIT 63 ESTABLISHED 13
為什么建立連接是三次握手,關閉連接確是四次揮手呢?
建立連接的時候, 服務器在LISTEN狀態下,收到建立連接請求的SYN報文后,把ACK和SYN放在一個報文里發送給客戶端。 而關閉連接時,服務器收到對方的FIN報文時,僅僅表示對方不再發送數據了但是還能接收數據,而自己也未必全部數據都發送給對方了,所以己方可以立即關閉,也可以發送一些數據給對方后,再發送FIN報文給對方來表示同意現在關閉連接,因此,己方ACK和FIN一般都會分開發送,從而導致多了一次。
說明
connect返回-1
errno=110(ETIMEDOUT),當服務器端網線拔了的時候,客戶端發送SYN過去就會收不到ACK,因此就會出現這個錯誤,1分鍾內就會返 回這個錯誤。
errno=111(ECONNREFUSED),當服務器未listen時,就會報這個錯
ESTABLISHED不一定真的establish
會出現這種情況:client為ESTABLISHED狀態而server為SYN_REVD狀態。
這是因為LINUX不像其他操作系統在收到SYN為該連接立馬分配一塊內存空間用於存儲相關的數據和結構,而是延遲到接收到client的ACK,即三次握手 真正完成后才分配空間,這是為了防范SYN flooding攻擊。 如果是這種情況,那么就會出現client端未ESTABLISHED狀態,server為SYN_RECV狀態。
並且server的SYN_RECV狀態在一定時間后會消失,client的established狀態也會消失。這是因為server在SYN_RECV狀態時,會像client發送多次的SYN+ACK(因為他以為自己的這個包對方沒收到),發送的次數定義在/proc/sys/net/ipv4/tcp_synack_retries中,默認為5.在發送5次之后還沒有收到ACK,就將其回收了,所以用netstat查看就看不到這個SYN_RECV狀態了。並且會像client發送RST信號。這就會導致client的這種半連接最后也會消失。這個可以通過tcpdump抓包得到(最好知道src這樣看到的包比較集中)。
TIME_WAIT處理方法
實現的目標就是不要讓處於TIME_WAIT的端口占滿所有本地端口,導致沒有新的本地端口用來創建新的客戶端。
1,別讓客戶端的速率太快
似乎上面的案例告訴我們別優化用力過猛,否則容易扯到蛋……將客戶端請求的速率降下來就可以避免端時間占用大量的端口,吞吐量限制就是470tps或者235tps,具體根據系統TIME_WAIT默認時長決定,如果考慮到其他服務正常運行這個值還要保守一些才行;此外還需要注意,如果客戶端和服務端增加了一層NAT或者L7負載均衡,那么這個限制可能會在負載均衡器上面。
2,客戶端改成長連接的方式
長連接效率高又不會產生大量TIME_WAIT端口。目前對我們來說還是不太現實的,雖然HTTP支持長連接,但是CGI調用應該是不可能的了,除非用之前的介紹的方式將CGI的請求轉換成HTTP服務來實現。對於一般socket直連的程序來說,短連接改成長連接就需要額外的封裝來標識完整請求在整個字節流中的起始位置,需要做一些額外的工作。
3,SO_LINGER選項
通常我們關閉socket的時候,即使該連接的緩沖區有數據要發送,close調用也會立即返回,TCP本身會嘗試發送這些未發送出去的數據,只不過應用程序不知道也無法知道是否發送成功過了。如果我們將套接字設置SO_LINGER這個選項,並填寫linger結構設置參數,就可以控制這種行為:
如果linger結構的l_onoff==0,則linger選項就被關閉,其行為就和默認的close相同;如果打開,那么具體行為依據另外一個成員l_linger的值來確定:如果l_linger!=0,則內核會將當前close調用掛起,直到數據都發送完畢,或者設置的逗留時間超時返回,前者調用會返回0並且正常進入TIME_WAIT狀態,后者調用會返回EWOULDBLOCK,所有未發送出去的數據可能會丟失(此處可能會向對端發送一個RST而快速關閉連接);如果l_linger==0,則直接將緩沖區中未發送的數據丟棄,且向對等實體發送一個RST,自己不經過TIME_WAIT狀態立即關閉連接。
我們都認為TIME_WAIT是TCP機制的正常組成部分,應用程序中不應該依賴設置l_linger=0這種機制避免TIME_WAIT。
4,修改系統參數
(a). 增加本地端口范圍,修改net.ipv4.ip_local_port_range,雖然不能解決根本問題但情況可以得到一定的緩解;
(b). 縮短TIME_WAIT的時間。這個時長在書中描述到RFC推薦是2min,而BSD實現通常是30s,也就說明這個值是可以減小的,尤其我們用在內網通信的環境,數據包甚至都流不出路由器,所以根本不需要設置那么長的TIME_WAIT。這個很多資料說不允許修改,因為是寫死在內核中的;也有說可以修改netfilter.ip_conntrack_tcp_timeout_time_wait(新版本nf_conntrack_tcp_timeout_time_wait)的,他們依賴於加載nf_conntract_ipv4模塊,不過我試了一下好像不起作用。
(c). 像之前在項目中推薦的,做出如下調整。
net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_timestamps=1 net.ipv4.tcp_tw_recycle=1
很多文獻說這種設置是不安全的,所以在測試環境以外就別嘗試了,因為這些選項還涉及到timestamp特性,我還不清楚什么回事,后面有時間再看什么吧。
我們在開發服務端的時候,通常都會設置SO_REUSEADDR這個選項。其實像上面描述到的,該選項也牽涉到偵聽socket端口處於TIME_WAIT的情況,設置這個選項將允許處於TIME_WAIT的端口進行綁定。
TCP報文格式
TCP大家都知道什么東西,現在說明一下格式:
說明:
URG:指示報文中有緊急數據,應盡快傳送(相當於高優先級的數據)。
PSH:為1表示是帶有push標志的數據,指示接收方在接收到該報文段以后,應盡快將這個報文段交給應用程序,而不是在緩沖區排隊。
RST:TCP連接中出現嚴重差錯(如主機崩潰),必須釋放連接,在重新建立連接。
FIN:發送端已完成數據傳輸,請求釋放連接。
SYN:處於TCP連接建立過程。 (Synchronize Sequence Numbers)
ACK:確認序號標志,為1時表示確認號有效,為0表示報文中不含確認信息,忽略確認號字段。
窗口:
滑動窗口大小,這個字段是接收端用來告知發送端自己還有多少緩沖區可以接受數據。於是發送端可以根據這個接收端的處理能力來發送數據,而不會導致接收端處理不過來。(以此控制發送端發送數據的速率,從而達到流量控制。)窗口大小時一個16bit字段,因而窗口大小最大為65535。
頭部長度:
由於TCP首部包含一個長度可變的選項和填充部分,所以需要這么一個值來指定這個TCP報文段到底有多長。或者可以這么理解:就是表示TCP報文段中數據部分在整個TCP報文段中的位置。該字段的單位是32位字,即:4個字節。TCP的滑動窗口大小實際上就是socket的接收緩沖區大小的字節數。
選項和填充部分:
TCP報文的字段實現了TCP的功能,標識進程、對字節流拆分組裝、差錯控制、流量控制、建立和釋放連接等。其最大長度可根據TCP首部長度進行推算。TCP首部長度用4位表示,那么選項部分最長為:(2^4-1)*(32/8)-20=40字節。
滑動窗口
TCP滑動窗口技術通過動態改變窗口大小來調節兩台主機間數據傳輸。每個TCP/IP主機支持全雙工數據傳輸,因此TCP有兩個滑動窗口:一個用於接收數據,另一個用於發送數據。TCP使用肯定確認技術,其確認號指的是下一個所期待的字節。 假定發送方設備以每一次三個數據包的方式發送數據,也就是說,窗口大小為3。發送方發送序列號為1、2、3的三個數據包,接收方設備成功接收數據包,用序列號4確認。發送方設備收到確認,繼續以窗口大小3發送數據。當接收方設備要求降低或者增大網絡流量時,可以對窗口大小進行減小或者增加,本例降低窗口大小為2,每一次發送兩個數據包。當接收方設備要求窗口大小為0,表明接收方已經接收了全部數據,或者接收方應用程序沒有時間讀取數據,要求暫停發送。發送方接收到攜帶窗口號為0的確認,停止這一方向的數據傳輸。當鏈路變好了或者變差了這個窗口還會發生變話,並不是第一次協商好了以后就永遠不變了。
滑動窗口協議,是TCP使用的一種流量控制方法。該協議允許發送方在停止並等待確認前可以連續發送多個分組。由於發送方不必每發一個分組就停下來等待確認,因此該協議可以加速數據的傳輸。 只有在接收窗口向前滑動時(與此同時也發送了確認),發送窗口才有可能向前滑動。收發兩端的窗口按照以上規律不斷地向前滑動,因此這種協議又稱為滑動窗口協議。
流量控制:端到端,接收端的應用層處理速度決定和網速無關,由接收端返回的rwnd控制
cwnd:發送端窗口( congestion window )
rwnd:接收端窗口(receiver window)
擁塞控制
擁塞控制: 發送端主動控制cwnd,有慢啟動(從cwnd初始為1開始啟動,指數啟動),擁塞避免(到達ssthresh后,為了避免擁塞開始嘗試線性增長),快重傳(接收方每收到一個報文段都要回復一個當前最大連續位置的確認,發送方只要一連收到三個
重復確認就知道接收方丟包了,快速重傳丟包的報文,並TCP馬上把擁塞窗口 cwnd 減小到1),快恢復(直接從ssthresh線性增長)。
如果網絡上的延時突然增加,那么TCP對這個事作出的應對只有重傳數據,但是重傳會導致網絡的負擔更重,於是會導致更大的延遲以及更多的丟包,於是這個情況就會進入惡性循環被不斷地放大。試想一下,如果一個網絡內有成千上萬的TCP連接都這么行事,那么馬上就會形成“網絡風暴”,TCP這個協議就會拖垮整個網絡。所以TCP不能忽略網絡上發生的事情,而無腦地一個勁地重發數據,對網絡造成更大的傷害。對此TCP的設計理念是:TCP不是一個自私的協議,當擁塞發生的時候,要做自我犧牲。就像交通阻塞一樣,每個車都應該把路讓出來,而不要再去搶路了。
慢啟動
只有在TCP連接建立和網絡出現超時時才使用。每經過一個傳輸輪次,擁塞窗口 cwnd 就加倍。一個傳輸輪次所經歷的時間其實就是往返時間RTT。不過“傳輸輪次”更加強調:把擁塞窗口cwnd所允許發送的報文段都連續發送出去,並收到了對已發送的最后一個字節的確認。另外,慢開始的“慢”並不是指cwnd的增長速率慢,而是指在TCP開始發送報文段時先設置cwnd=1,使得發送方在開始時只發送一個報文段(目的是試探一下網絡的擁塞情況),然后再逐漸增大cwnd。
為了防止擁塞窗口cwnd增長過大引起網絡擁塞,還需要設置一個慢開始門限ssthresh狀態變量(如何設置ssthresh)。慢開始門限ssthresh的用法如下:
當 cwnd < ssthresh 時,使用上述的慢開始算法。
當 cwnd > ssthresh 時,停止使用慢開始算法而改用擁塞避免算法。
當 cwnd = ssthresh 時,既可使用慢開始算法,也可使用擁塞控制避免算法。
擁塞避免算法:讓擁塞窗口cwnd緩慢地增大,即每經過一個往返時間RTT就把發送方的擁塞窗口cwnd加1,而不是加倍。這樣擁塞窗口cwnd按線性規律緩慢增長,比慢開始算法的擁塞窗口增長速率緩慢得多。
無論在慢開始階段還是在擁塞避免階段,只要發送方判斷網絡出現擁塞(其根據就是沒有收到確認),就要把慢開始門限ssthresh設置為出現擁塞時的發送方窗口值的一半(但不能小於2)。然后把擁塞窗口cwnd重新設置為1,執行慢開始算法。這樣做的目的就是要迅速減少主機發送到網絡中的分組數,使得發生擁塞的路由器有足夠時間把隊列中積壓的分組處理完畢。
當TCP連接進行初始化時,把擁塞窗口cwnd置為1。前面已說過,為了便於理解,圖中的窗口單位不使用字節而使用報文段的個數。慢開始門限的初始值設置為16個報文段,即 cwnd = 16 。
在執行慢開始算法時,擁塞窗口 cwnd 的初始值為1。以后發送方每收到一個對新報文段的確認ACK,就把擁塞窗口值另1,然后開始下一輪的傳輸(圖中橫坐標為傳輸輪次)。因此擁塞窗口cwnd隨着傳輸輪次按指數規律增長。當擁塞窗口cwnd增長到慢開始門限值ssthresh時(即當cwnd=16時),就改為執行擁塞控制算法,擁塞窗口按線性規律增長。
假定擁塞窗口的數值增長到24時,網絡出現超時(這很可能就是網絡發生擁塞了)。更新后的ssthresh值變為12(即變為出現超時時的擁塞窗口數值24的一半),擁塞窗口再重新設置為1,並執行慢開始算法。當cwnd=ssthresh=12時改為執行擁塞避免算法,擁塞窗口按線性規律增長,每經過一個往返時間增加一個MSS的大小。
強調:“擁塞避免”並非指完全能夠避免了擁塞。利用以上的措施要完全避免網絡擁塞還是不可能的。“擁塞避免”是說在擁塞避免階段將擁塞窗口控制為按線性規律增長,使網絡比較不容易出現擁塞。
如果發送方設置的超時計時器時限已到但還沒有收到確認,那么很可能是網絡出現了擁塞,致使報文段在網絡中的某處被丟棄。這時,TCP馬上把擁塞窗口 cwnd 減小到1,並執行慢開始算法,同時把慢開始門限值ssthresh減半。這是不使用快重傳的情況。快重傳算法首先要求接收方每收到一個失序的報文段后就立即發出重復確認(為的是使發送方及早知道有報文段沒有到達對方)而不要等到自己發送數據時才進行捎帶確認。
接收方收到了M1和M2后都分別發出了確認。現在假定接收方沒有收到M3但接着收到了M4。顯然,接收方不能確認M4,因為M4是收到的失序報文段。根據可靠傳輸原理,接收方可以什么都不做,也可以在適當時機發送一次對M2的確認。但按照快重傳算法的規定,接收方應及時發送對M2的重復確認,這樣做可以讓發送方及早知道報文段M3沒有到達接收方。發送方接着發送了M5和M6。接收方收到這兩個報文后,也還要再次發出對M2的重復確認。這樣,發送方共收到了接收方的四個對M2的確認,其中后三個都是重復確認。快重傳算法還規定,發送方只要一連收到三個重復確認就應當立即重傳對方尚未收到的報文段M3,而不必繼續等待M3設置的重傳計時器到期。由於發送方盡早重傳未被確認的報文段,因此采用快重傳后可以使整個網絡吞吐量提高約20%。
與快重傳配合使用的還有快恢復算法,其過程有以下兩個要點:
當發送方連續收到三個重復確認,就執行“乘法減小”算法,把慢啟動門限ssthresh減半。這是為了預防網絡發生擁塞。請注意:接下去不執行慢開始算法。
由於發送方現在認為網絡很可能沒有發生擁塞,因此與慢開始不同之處是現在不執行慢開始算法(即擁塞窗口cwnd現在不設置為1),而是把cwnd值設置為慢開始門限ssthresh減半后的數值,然后開始執行擁塞避免算法(“加法增大”),使擁塞窗口緩慢地線性增大。
上圖給出了快重傳和快恢復的示意圖,並標明了“TCP Reno版本”。區別:新的 TCP Reno 版本在快重傳之后采用快恢復算法而不是采用慢開始算法。
發送方窗口的上限值 = Min [ rwnd, cwnd ]
當rwnd < cwnd 時,是接收方的接收能力限制發送方窗口的最大值。
當cwnd < rwnd 時,則是網絡的擁塞限制發送方窗口的最大值。
差錯控制
TCP使用差錯控制來提供可靠性。差錯控制包括以下的一些機制:檢測和重傳受到損傷的報文段、重傳丟失的報文段、保存失序到達的報文段直至缺失的報文到期,以及檢測和丟棄重復的報文段。TCP通過三個簡單的工具來完成其差錯控制:檢驗和、確認以及超時。
總結
感謝網絡大神的分享:https://blog.csdn.net/zzhongcy/article/details/38851271