? ? ? ? 前面已經介紹了傳輸層的UDP協議的報文以及一下相關的知識點,本次主要是傳輸層的TCP協議,包括TCP報文的詳細介紹;可靠傳輸、流量控制、擁塞控制等;建立連接、釋放連接。
一、TCP基本知識點介紹
1.1、TCP協議的幾個重要的知識點? ? ? ??
? ? ? ? (1)TCP報文的具體內容。
? ? ? ? (2)可靠傳輸。
????????????????如果服務器響應給客戶端的數據太大,那么會切成不同的包一次發過去。客戶端每接收一個包都會給服務 器一個回應:我收到這個了這個包。服務器就會知道這個給包成功發送了。
????????????????如果有一個包在發送過路程中被路由器丟掉了,那么客戶端收不到這個包,服務器也就收不到客戶端給 服務器關于接收到這個包的響應。那么服務器在之后就會重新再發送一遍這個包。
? ? ? ? (3)流量控制。
? ? ? ? (4)擁塞控制。
? ? ? ? (5)建立連接。
? ? ? ? (6)釋放連接。
1.2、TCP報文具體內容
????????TCP協議報文段首部包含兩個部分:
????????????????(1)20個字節的固定首部部分
????????????????(2)選項和填充部分長度不固定
所以TCP協議報文段的首部最少20個字節。
? ? ? ? 下面將詳細介紹TCP的報文的具體內容:
1.2.1、數據偏移
????????占4位,取值范圍是0x0101~0x1111。
????????乘以4:就是TCP報文段的首部長度,最小20~最大60字節。
????????因為TCP報文段首部最小是20字節,所以數據偏移的最小值是20/4=5,0x0101。
? ? ? ? 這部分和網絡層首部一樣。
-
TCP首部長度:就是右邊數據向右的偏移量。
1.2.2、保留
????????占3位,目前用不到。預防以后可能用到,現在全是0。
1.2.3、標志位
? ? ? ? 如下圖所示的,紅色框內的6位就是TCP報文中的標志位。
(1)共占9位、前三位是保留位,與保留位無關
(2)URG=Urgent
????????當URG=1時,緊急指針字段才有效。表明當前報文字段中有緊急數據,優先傳輸。
(3)ACK=Ackownledgment
????????當ACK=1時,確認號ack字段才有效。
(4)PSH=Push
????????一般不關注,用在交互式網絡通信中。
(5)RST=Reset
????????當RST=1時,表明連接中出現嚴重差錯,必須釋放連接,然后再重新建立連接。
(6)SYN=Synchronization
???????? 1.當:SYN=1,ACK=0時,表明這是一個建立連接的請求。
? ? ? ? ?2.若對方同意建立連接,則回復:SYN=1,ACK=1。
? ? ? ? ?3.三次握手中,用戶端恢復后會給應答:SYN=0,ACK=1。
(7)FIN=Finish
????????當FIN=1時,表明數據已經發送完畢,要求釋放連接。
? ? ? ? TCP的四次揮手釋放連接的時候,使用的標志位中,主要的就是FIN標志位。
(8)TCP校驗和-Checksum
????????1.跟UDP一樣,TCP校驗和的計算內容:偽首部+首部+數據
????????2.偽首部:占用12字節,僅在計算校驗和時起作用,并不會傳遞給網絡層。
(9)序號(Sequence Number)
????????1.占4字節,4*8=32個位。
????????2.首先,在傳輸過程中的每一個字節都會有一個編號,而且連續的字節編號也連續。類似于每一個字節都有一個內存地址。
????????3.在建立連接后,序號代表:這一次傳給對方的TCP數據部分的第一個字節的編號。
例子:?比如A要發給B400字節的數據,分成4段發。第一個TCP報文段的數據部分是1~100,那么這個報文段的序號部分就是1(假設第一個字節的編號就是1)。
????????那么第二個報文段的數據部分就是101~200,這個報文段的序號部分就是101。
(10)確認號(Ackownledgment Number)
????????1.占4字節,4*8=32個位。
????????2.在建立連接后,確認號代表:期望對方下一次傳過來的TCP數據部分的第一個字節的編號。
????????3.確認號ack,在標志位ACK為1時才有效。(重要)
(11)窗口(Window)
????????1.占2字節,2*8=16位;
????????2.這個字段有流量控制功能,用于告訴對方下一次允許發送的數據大小(單位字節)。
1.2.4、TCP報文內容的細節
(1)TCP中并沒有報文總長度的概念,只知道數據偏移,也就是TCP報文的頭部,這時候如何確定TCP數據部分的長度?
????????1.UDP首部中有個16位的字段記錄了整個UDP報文段的長度(首部+數據);
????????????????但是TCP首部中僅僅有4位的字段記錄了TCP報文段的首部長度,并沒有字段記錄TCP報文段的數據長度。
????????2.那怎么知道TCP報文段的數據長度呢?
????????????????1.其實UDP首部的這個記錄UDP報文段的長度的字段是冗余的,不用這個字段也能就計算出UDP報文數據部分 的長度:
????????UDP首部固定是8字節
????????所以UDP數據部分是:網絡層的總長度-網絡層的首部長度-UDP報文首部長度
????????2.UDP的這個16位的字段,純粹是為了保證首部是32bit對齊:
????????思考數據偏移*4代表了TCP報文段首部的長度,那么TCP報文首部長度能不能等于11?可能不行啊,
????????必須是4的倍數。所以這個16位的記錄UDP報文段的長度的字段之所以占16位,就是為了滿足UDP報文段
????????首部固定部分長度是4的倍數:如果沒有這16位,那么UDP報文段首部固定部分長度3個字節,就不是4的倍數 了。
????????3.所以TCP/UDP的數據長度,完全可以由IP數據包的首部推測出來。
????????傳輸層的首部長度是固定的或者可知的:
????????1.UDP首部:20字節
????????2.TCP首部:存放在首部的數據偏移字段
????????3.網絡層的總長度和首部長度:都有對應字段存儲。
????????傳輸層數據部分是=網絡層的總長度-網絡層的首部長度-傳輸層報文首部長度
(2)TCP報文的標志位的個數?
????????1.保留為6位,標志位6位。
????????但是其實兩種說法差不多,因為標志位的前3位也是基本上不用的,所以會被算作保留位。
????????所以有些資料干脆說保留位6位,標志位6位。
1.3、TCP可靠傳輸
1.3.1、實現TCP可靠傳輸 -- 停止等待ARQ協議
ARQ(Automatic Repeat-reQuest):自動重傳請求。
????????1.假設A要發送給B發送3個包,如果發送第一個包M1時,B沒有接收到。那么B就不會給A發送:確認收到M1包這個消息。然后A端等待接收這個消息,直到超時。然后就會重新發送M1包。
????????2.停止等待ARQ協議實現TCP可靠傳輸的兩種情況:
????????(1)確認(信息)丟失:
????????????????B收到A發送的M1包,然后返回一個確認信息。但是這個確認收到M1信息在傳輸時,丟失了。那么A在 等待超時后會在次發送一個M1包,此時B端接收后,就會收到兩個M1包,B端會丟掉一個M1包,再返回確 認收到M1包的信息給A端。
????????(2)確認(信息)遲到
????????????????B收到A發送的M1包,然后返回一個確認信息。但是這個確認收到M1信息可能因為線路或者網絡問題傳 輸的很慢,可能造成A端等待超時,再次發送M1包。B端接收到這第二個M1包后,發現已經收到過了,就 會丟掉一個M1包,再次發送確認收到M1信息。
????????????????對于A端來說,收到B端發送的確認收到M1信息后,就會接著發送M2信息。之后可能還會再次收到確認 收到M1信息。A端收到這個遲到的確認信息,發現之前收到過了,那么A端就會不響應這個信息。
????????3.停止等待ARQ協議能夠保證TCP的可靠傳輸,但是因為必須等上一個數據傳輸結束,下一個信息才能傳輸,所以效率很低,正是因為有這些原因,所以提出了下面的改進。
1.3.2、改進:連續ARQ協議+滑動窗口協議+SACK選擇性確認
????????1.連續ARQ:發送窗口中有4個分組,會一口氣發送完然后再等待確認信息。而且確認信息,也只會發送確認 收到最后一個分組的確認信息。等價于確認收到所有分組信息了。
????????2.滑動窗口:B這邊有一個緩存窗口,用來暫時存放每次從A發送來的數據。這個窗口的大小會告訴A。窗口的 大小,代表每次最多能能接收多少分組。發送方的窗口大小,一般是由接收方決定的。
????????3.圖示一個傳輸過程:注意序號Seq和確認號ack,圖中的ACK標志位有效的時候,TCP報文中的確認號ack才有效。
? ? ? ? 如上圖所示的第二次A給B連續發送四個數據包的時候,發現了丟失,反碼B給A的回復,就是“ACK=1,ack=601”也就是從丟包的位置開始上傳,丟包的前面的包不需要在從新上傳,后面的也不需要從新上傳。
4.SACK選擇性確認:Selective Acknowledgment
????????1.在TCP通信過程中,如果發送序列中間某個數據包丟失(比如1,2,3,4,5中的3丟失了)。
????????????????TCP會通過重傳最后確認的分組(2)的后續分組(3,4,5):收到的確認信息中的確認分組是2,那么發 送端會重傳3,4,5。這樣原先已經正確傳輸的分組也可能重復發送(比如4,5),降低了TCP性能。
????????2.為改善上述情況,發展了SACK(Selective Acknowledgment)技術:
????????????????告訴發送方哪些數據丟失,哪些數據已經提前收到。可以使TCP只重新發送丟失的包(比如3),不用發送 后續所有的分組(比如4,5)。
????????3.SACK信息會放在 TCP首部 的 選項部分 :此時TCP首部的選項部分就是SACK選項。這樣TCP的選項部分就使用上啦,TCP的首部就變長了。
1.3.3、抓包演示
(1)前面5個:發了5個分組。
????????前面5個包大小分別是312、1280、1280、1280、1280,并且返回的確認號都是748,說明用戶端沒有進行回應。
(2)后面1個:用戶給服務器回復一個確認信息。
? ? ? ? 用戶確認收到了5432字節,請給我發送5433及之后的字節,我的窗口大小是262400。
(3)注意服務器發給我的第一個包的Seq是1,但是其實這個序號是相對序號。
????????相對于誰的序號呢?注意到下面還有個原始(raw)序號,那么原始序號 - 相對序號 = 基準數。
????????3277832203 - 1 = 3277832202
????????看第二個包:得到基準數也是3277832202
(4)這個基準數其實是一個標識:標識這些連接屬于同一個請求。這個值在TCP連接的時候創建的,并且告訴對方。
(5)序號部分放的是原始值Sequence Number(raw),而不是相對值。
1.3.4、疑問解決
(1)如果一個包重傳了N次還是失敗,會一直持續重傳到成功為止嗎?
????????????????這個取決于操作系統的設置,比如有些操作系統,重傳5次還未成功就會發送reset報文(RST)斷開TCP。
????????????????即發送端超出一定的重傳次數或等待時間,還沒有收到來自接收端的確認報文,于是發送reset報文。
????????????????當RST=1時,表明連接出現嚴重錯誤,必須釋放連接,然后再重新建立連接。
(2)如果接收窗口最多能接收4個包,但是發送方只發送了2個包,接收方如何確定后面還有沒有第3個包呢?
????????????????等待一定時間后還是沒有第3個包發過來,接收端就認為只傳過來了2個包(無論是傳輸過程中丟包還是只有2 個包)。接收端就會返回確認信息:確認收到2個包。
(3)為什么選擇在傳輸層就將數據“大卸八塊”分成多個段,而不是等到網絡層再分片傳遞給數據鏈路層?
????????????????因為可以提高重傳的性能:需要明確的是,可靠傳輸是在傳輸層進行控制的,即沒有收到確認信息后,發送 端會重新發送這個報文段。
????????????????所以如果在傳輸層不分段,一旦出現數據丟失,整個傳輸層的數據都得重傳。
????????????????如果在傳輸層分了段,一旦出現數據丟失,只需要重傳丟失的那些段即可。
1.4、流量控制
????????(1)如果接收方的緩存區滿了,發送方還是瘋狂的發送數據,接收方只能把收到的數據包丟掉,大量的丟包會極大著浪費網絡資源。所以要進行流量控制。
????????(2)什么是流量控制:讓發送方的發送速率不要太快,讓接收方來得及接收處理。
????????(3)緩存區和窗口是不同的概念:緩存區要比窗口大很多,每次收到一窗口大小的數據,會先放到緩存區中。
????????(4)原理:
????????????????通過確認報文中窗口字段來控制發送方的發送速率,也就是實時調整窗口大小。
????????????????發送方的發送窗口大小不能超過接收方給出的窗口大小
????????????????當發送方收到接收窗口的大小為0時,發送方就會停止發送數據。
????????(5)流量控制:特殊情況
????????1.有一種特殊情況:一開始接收方給發送方發送了報文段中的窗口字段值為0。后面,接收方又有了一些存儲 空間,會給發送方發送一個非0窗口的報文但是這個報文丟了。
????????2.結果就是:發送方一直認為接收方的窗口為0,不發送報文;接收方一直等不到數據,一直等待;雙方陷入 僵局。
????????3.解決方案:發送方主動詢問窗口大小。
????????當發送方收到窗口為0的報文時,發送方會停止發送報文,但是同時會開啟一個定時器,隔一段時間就發個測 試報文去詢問接收方最新的窗口大小。如果接收方的窗口大小還是0,則發送方會再次刷新啟動這個定時器。
1.5、擁塞控制
1.5.1、什么是擁塞
1.如果一個路由器R3允許通過的最大帶寬是1000M,此時R3路由器左側又連接這個兩個路由器R1和R2,R1的最大帶寬是700M,R2的最大帶寬是600M。那么此時就極有可能發生擁塞現象。
????????在理想情況下,R3能同時允許1000M的數據通過,但是R1和R2最多能通過1300M。此時就可能發生R3路由器來不及處理這么多數據,或者無法一次性通過這么多數據,就會造成擁塞現象。R3就會丟棄掉過載的數據包。
????????擁塞是指到達通信子網中某一部分的分組數量過多,使得該部分網絡來不及處理,一致引起這個部分乃至整個網絡性能下降的現象,嚴重時甚至會導致網絡通信業務陷入停頓,即出現死鎖現象。
2.理想情況和實際情況是不同的
????????如果某個鏈路的理想情況下的吞吐量是1000M,但是實際情況由于數據可能在傳輸過程中可能會互相干擾。往往實際負載在不到1000M時,該鏈路的吞吐量就達到最大了。
????????之后再加大負載就會造成擁塞。
1.5.2、擁塞控制
????????(1)防止過多的數據注入到網絡中,避免網絡中的路由器或鏈路過載。
????????(2)擁塞控制是一個全局性的過程(流量控制,是兩端,點對點的控制過程)。
????????要整個鏈路來協同控制,涉及到所有的主機,路由器,以及與降低網絡傳輸性能有關的所有因素,是大家共 同努力的結果。
1.5.3、幾個單詞縮寫意思
(1)MSS(Maxium Segment Size):每個段的數據部分的最大長度
????????兩端建立連接時,會商定一個合適的MSS值,即MSS在建立連接時確定。
????????每個段數據部分最大值的理論值:1460字節.
-
抓包觀察這個字段:
首先這個MSS段的數據部分的最大長度是在建立連接時確定的,那肯定是在三次握手時確定的:
當SYN=1,ACK=0時,表明這是一個建立連接的請求。
-
查看這個TCP報文的首部:發現TCP首部長度是32字節,所以有12字節在選項Options部分中。
在Options部分中發現了MSS字段且是1460(注意這個值不是固定的,兩端發送的的TCP報文中這個值可能是 不一樣的)。
-
這個選項部分Options就是存放兩端確定的一些東西:
比如MSS段的數據部分的最大長度,是否允許SACK 選擇性確認(SACK permitted)
-
注意這個值不是固定的,兩端發送的的TCP報文中這個值可能是不一樣的。
比如A發給B的報文中MSS是1460,B發給A的報文中MSS是1412,那么此時MSS在兩者中取最小值。為了兼 顧兩者,這樣傳輸數據兩者都能接收。
MSS在建立連接時確定(協商的)。
-
2.cwnd(congestion window):擁塞窗口
-
進行擁塞控制,會動態的變化。
-
-
3.rwnd(receive window):接收窗口
-
接收方告訴發送方,你最多一次能發送多少的TCP報文段。
-
-
4.swnd(send window):發送窗口
-
swnd = min(cwnd, rwnd)
-
實際發送方的發送窗口,取擁塞窗口和接收窗口的最小值。
-
1.5.4、擁塞控制的方法
(1)慢開始(slow start,慢啟動)
????????加入一開始接收方告訴發送方的接收窗口rwnd=3000比較大,且MSS=100比較小。所以理論上發送方可以以口氣發30個報文段給接收方。但是考慮到擁塞控制的話,擁塞窗口cwnd=100一開始會設置的比較小。那么發送窗口swnd會取擁塞窗口cwnd和接收窗口rwnd兩者的最小值100,所以第一次會只發送1個報文段。
????????發送一個報文段后,發現網絡狀況良好。那么擁塞窗口會 * 2,cwnd=200。發送窗口取兩者最小值為swnd=200,所以這次發送2個報文段。發現網絡狀況依然良好,擁塞窗口繼續 * 2,cwnd=400。下一次發送4個報文段,如果網絡狀況依然良好的話,擁塞窗口cwnd * 2。
????????發送窗口緩慢增長,試探增長,慢慢開始。試探接收方的接收程度。
-
cwnd的初始值比較小,然后隨著TCP報文段被接收方確認(收到一個ACK)而成倍增長(指數級)。
(2)擁塞避免(congestion avoidacne)
????????1.在慢開始的基礎上,為擁塞窗口cwnd加上一個慢開始閾值slow start threshold,cwnd在到達閾值之前只要網絡良好沒有出現擁塞等狀況,就會成指數增長(乘以2);如果達到閾值而且網絡狀況依然良好,擁塞窗口cwnd會呈乘法級增長(每次加固定值)。
????????2.當出現擁塞時(發現開始丟包/報文段),就會把慢開始閾值slow start threshold減半,同時從頭開始執行慢開始算法(cwnd從初始值開始)。
????????3.ssthresh(slow start threshold):慢開始閾值,cwnd達到閾值后,以線性方式增長。
????????4.擁塞避免(加法增大):擁塞窗口緩慢增大,以防止網絡過早出現擁塞。
????????5.乘法減小:只要網絡出現擁塞(發現開始丟包了),把ssthresh減半,與此同時,開始重新執行慢開始算法。
????????6.當網絡出現頻繁擁塞的話,ssthresh這個值會下降的很快。
(3)快速重傳(fast restransmit)
????????1.之前的實現TCP可靠傳輸時,有一個重傳機制是“超時重傳”。在ARQ自動重傳請求機制中,如果A等待接受B的確認消息,如果等待超時的話,就會重新發送上一個報文段。
????????2.快重傳機制:在接收方和發送方都進行了限制
????????3.接收方:
????????之前的做法:A發送5個段給B時,B只有等A的5個都發送完時或最后一個段超時時,才給A發確認信息:我 收到了哪些段。
????????快重傳做法:當接收方收到第二個分組后,返回一個確認收到分組2。但是沒有收到第三個分組,直接收 到了分組4,即收到了一個失序的分組。那么在收到分組4后,會立即發出重復的確認(上一個確認信 息):確認收到了分組2。然后繼續收到分組5,再次發送確認收到了分組2;然后繼續收到分組6,再次發 送確認收到了分組2。
????????4.發送方:
????????如果連續收到3個重復的確認(總共4個相同的確認),就會立即重傳尚未收到的報文段。
而不必繼續等待重傳計時器到期后再重傳。
(4)快速恢復(fast recovery)
????????1.擁塞控制是上述4個方法綜合來治理的。
????????2.大致過程:
????????????????慢開始算法開始增大擁塞窗口,當擁塞窗口以指數增長,直到達到慢開始閾值后,執行擁塞避免算法即 擁塞窗口以線性增長。當收到3個重復的確認后,意識到此時開始掉包,產生擁塞了---->慢開始閾值乘法減 半,變成以前的一半:
????????????????之后又重新開始“慢開始算法”,擁塞窗口重初始值開始呈指數增長(這是舊版本的做法,已經棄置不 用)。但是這樣效率較低,擁塞窗口應該在一個合適的初始值開始增大。
????????????????擁塞窗口直接以新的慢開始閾值作為初始值,開始以線性增長。
????????3.當發送方連續收到3個重復確認后,就意識到此時發生了丟包的現象,可能出現了擁塞。就執行“乘法減 小”,把慢開始閾值減半。之后不會執行慢開始算法,而是將擁塞窗口的值直接設置為慢開始閾值減半后的 新閾值,并且呈線性增長。
(5)發送窗口的限制條件
????????1.發送窗口的最大值:swnd = min(cwnd, rwnd)? ? ? ? ? ? ?cwnd指網絡的擁塞窗口
????????2.當rwnd < cwnd時,是接收方的接收能力限制發送窗口的最大值。
????????3.cwnd < rwnd時,則是網絡的擁塞限制發送窗口的最大值。
(6)擁塞控制可以理解為是在可靠傳輸,流量控制的基礎上,進一步來控制網絡的狀態,協調網絡的情況。盡量避免網絡擁塞,出現狀況。
二、TCP連接管理? ? ??
? ? ? ? (1)建立連接 (三次握手)
????????(2)釋放連接 (四次揮手)
2.1、序號、確認號的值
2.1.1、序號、確認號的基本過程值
????????在發送一個http請求前,要先建立一個穩定的連接。
(1)序號和確認號概念
????????序號Seq:我當前發的包的數據部分的第一個字節的編號(在分段之前的整個數據包的編號)。
可以理解為我當前這個包的數據從哪個字節發。
????????確認號Ack:在建立連接后,確認號代表:期望對方下一次穿過來的TCP數據部分的第一個字節的編號。
????????也可以理解,我確認收到了這個編號前面字節的數據。確認號Ack只有在標志位ACK為1時明才有效。
(2)序號,確認號:相對值的確定
? ? ? ? 下面的圖片描述是比較書本的情況,實際情況可能是連發好幾個數據包,才會回應一次。