计网笔记(6) 传输层
文章目錄
- 上課內容
- 服務原語
- 一、運輸層的端口
- 服務器端口號
- 客戶端端口號
- !擴展問題:一臺機器所能容納TCP連接的數量
- 二、用戶數據報協議UDP
- 首部字段結構
- 偽首部
- 三、傳輸控制協議TCP的基礎
- TCP連接
- 四、TCP可靠傳輸的工作原理
- 停止等待協議
- 無差錯情況與有差錯情況
- 確認丟失和確認遲到
- 信道利用率
- 連續ARQ協議
- 五、TCP報文段首部格式
- 六、TCP可靠傳輸的實現細節
- 以字節為單位的滑動窗口
- 超時重傳時間選擇
- 選擇確認(Selective ACK,SACK)
- 七、TCP的流量控制
- 利用滑動窗口實現
- persistence timer
- 傳輸效率
- 八、TCP的擁塞控制
- 一般原理
- 擁塞控制方法
- 1. 慢開始和擁塞避免
- 1.1 慢開始算法
- 1.2 擁塞避免算法
- 2.快重傳&快回復
- 3. 主動隊列管理AQM
- 九、TCP的運輸連接管理
- 連接建立
- issue
- 連接釋放
上課內容
- 用于在不可靠網絡中建立可靠鏈接
- 網絡層的復用,讓多個應用層應用使用一個網絡連接(通過端口及其相關機制區分)
服務原語
簡單傳輸層服務的原語:
服務原語的使用:
- TCP的socket原語(Berkeley Socket)
- 這里的accept相當于之前的listen,
一、運輸層的端口
TCP/IP端口號為16位,但其指具有本地意義,表只應用層中各個進程與運輸層交互時的層間接口。
服務器端口號
兩大類:
- 系統端口號:0-1023,他們被用于一些特殊用途,一般不改動
- 登記端口號:1024-49151 為沒有系統端口號的應用程序使用。
客戶端端口號
49152-65535 僅僅在酷虎進程運行時才動態選擇
!擴展問題:一臺機器所能容納TCP連接的數量
- 對于客戶端機器,TCP的連接使用系統分配的端口(一般在linux為50000個左右),以及自身的ip地址決定,所以單ip地址下客戶機能夠建立的連接受sysctl -a | grep ip_local_port_range提供的動態端口范圍限制。但docker等技術可以讓客戶機虛擬化多個網卡,這樣就擁有了多個ip,此時最大連接數為每個容器ip地址下range大小的限制,當然也受總內存的限制
- 對于服務端機器,TCP連接實際上是{自身ip,自身port,client ip,client port}四元組唯一決定,所以理論上其能維持的TCP連接無上限,但要維護一個連接最少需要3.3k內存,所以它維持連接數與內存有關
二、用戶數據報協議UDP
特點:
適用場景
- UDP沒有擁塞控制,故對實時應用(電話,視頻會議),可丟失但不允許大時延的場景有用
- 支持一對一,一對多,多對一和多對多
- 首部開銷小(8byte)
首部字段結構
可以看到,首部字段時四個2字節字段:
- 源端口
- 目的端口
- 長度:UDP用戶數據報長度,最小是8(也即頭部)
- 檢驗和:檢驗包括頭部和數據報(IP層只檢驗頭部)是否有錯,有則丟棄?
可以看到,同樣的IP報,可以通過UDP實現基于端口的分用和復用
偽首部
UDP在計算checksum之前要增加12字節偽首部,如圖
其中UDP長度與真正首部長度是相同的。偽首部只是臨時添加的(不下傳也不上交,信息是IP地址信息是應用層給的)。之后,將偽頭部,真頭部和數據包部分一起計算校驗和。
UDP以16bit為1個checksum單位(因為校驗和是16位),故當有奇數個數據字節時,會補上1個全0字節:
三、傳輸控制協議TCP的基礎
特點
TCP擁有緩存,并且不關心應用程序發來報文的長度,它根據對方給出的window size和當前網絡擁塞程度決定一個報文段應該包含多少字節
TCP連接
TCP連接的端點是套接字(socket)。而端口號拼接到IP地址即構成了套接字:
而每一條TCP連接唯一地被通信兩端的兩個socket確定:
四、TCP可靠傳輸的工作原理
停止等待協議
令A位發送方,B為接收方。停等協議指每發完一個分組就停止發送,等待對方的確認,收到確認后在發送下一個分組
無差錯情況與有差錯情況
最簡單的情況是上圖(a),接到了再發
如果B接受M1時出錯,就扔掉分組,之后什么也不做(不通知A沒收到),或者中間丟了,也是什么都不知道,相當于沒通知A。一段時間后,A在超時計時器到期時沒收到確認,就撤銷超時計時器,并且重傳M1分組,要實現這樣的機制應當注意:
- A發完分組后應當保存已發分組的副本直到其確認接受
- 分組和確認分組需要編號
- 顯然,超時計時器重傳時間要比數據在分組傳輸的平均時間長
確認丟失和確認遲到
對之前的出錯情況,如果B的確認包傳給A時丟了,A不知情,一段時間后這個分組M都會再被傳過來,此時B收到了2次正確的M,它應該采取2個行動:
這是確認丟失的方法,情況如下:
而如果B發回去的確認包遲到了,在A重傳之后才到,這是B會把第二次收到的M丟棄,并且發送重傳確認分組。而A則收下遲到的分組但什么也不做。A需要等收到重發的M的確認分組之后再傳之后的分組。這是確認遲到的方法
情況如下:
信道利用率
停等協議的優點是簡單,但缺點是信道利用率太低
令:
- TDT_DTD?=發送分組時間
- RTTRTTRTT=往返時間
- 處理分組時間忽略不計
- TAT_ATA?=發送確認分組時間
則信道利用率為:U=TDTD+RTT+TAU=\frac{T_D}{T_D+RTT+T_A}U=TD?+RTT+TA?TD??
為了提高效率,需要使用流水線傳輸的連續ARQ協議
連續ARQ協議
使用滑動窗口,是TCP協議的精髓所在,后仔細討論
五、TCP報文段首部格式
TCP傳送的數據單元是報文段,分首部和數據段。
TCP首部前20個字節是固定的,后有>=0的4N個byte的option,首段固定部分各個字段的示意圖和意義如下
| 源端口和目標端口(src/des port) | 各2byte | src和des的端口號 |
| 序號(Sequence Number) | 4byte | 其值= 真實序號%2322^{32}232,序號的編址單位是字節,整個要穿的字節流的其實序號要在連接建立時設置,而首部的需要字段值是本報文段發送數據的第一個字節的序號。 |
| 確認號(ACK number) | 4byte | 是期望收到對方下一個報文段的第一個數據字節的序號,也即期望收到下一個TCP包的Seq number。它也意味著:若ACK=N,則N-1及之前的所有數據都已經正確收到。 |
| 首部長度/數據偏移(header length) | 4bit | 指出TCP報文段的數據起始處距離TCP報文段的頭部起始處有多遠。這其實指示了TCP首部長度(因為有option,所以它是必要的)。但要注意的是,數據便宜的單位是32bit(4字節,因為option也是按這個單位增加的),這也意味著option最長不超過40bit,但其實之后的保留位也使得option有增長空間 |
| 保留位 | 已經減少到了4bit | 留作后用 |
| CWR(Congestion Window Reduced) | 1bit | 讓接收者直到發送者已經減緩發送,并且可以停止發送ECN-Echo |
| ECE(Explicit Congestion Notation) | 1bit | 向接收者發送ECN-Echo信號 |
| URG(URGent pointer) | 1bit | 置位時使緊急指針有效,表示報文段中有緊急數據,應盡快傳送(實際上是插到隊列最前面),而不要按照排隊順序(例:Ctrl+C的中斷應當立刻執行) |
| ACK | 1bit | 確認號,指示確認字段。TCP規定連接建立后所有報文段ACK都應當置1 |
| PSH(PuSH,推送) | 1bit | 少用。發送方把PSH置1時,接收方收到后就盡快把信息交付給接受的進程,而不必等待緩存填滿 |
| RST(ReSeT,復位) | 1bit | 它置位時,表示TCP連接種出現嚴重差錯,必須釋放連接后重新連接;他也用來拒絕一個非法報文段或拒接連接 |
| SYN(同步) | 1bit | 用于同步序號SYN=1,ACK=0時,表示這是一個連接請求報文段,如果同意,應讓ACK和SYN置位。 |
| FIN(終止) | 1bit | 置位時,表明報文端發送完畢,并要求釋放運輸連接 |
| 窗口長度(Window size) | 2byte | 指發送方對應的接收窗口,表示從本報文段首部中的確認號算起,接收方目前允許對方發送的數據量。這個限制基于接收方有限的緩存空間。它是接收方讓發送方設置其發送窗口的依據。 |
| 校驗和(checksum) | 2byte | 包括首部和數據,和UDP一樣要加上12byte偽頭部,格式相同,但應改為TCP的協議號和對應數據 |
| 緊急指針(Urgent Pointer) | 2byte | 與URG通用,指出緊急數據的末尾位置(緊急數據后是普通數據),因此它也指示本報文段種緊急數據的字節數。 |
| 選項(options) | 0-40byte | 變長選項 |
六、TCP可靠傳輸的實現細節
以字節為單位的滑動窗口
基本示意圖(A發,B接受):
如圖,假定A收到了B的ACK報文段,其中window size是20(單位是byte),而確認號ack=31(表示B期望從31開始收)。這樣A構造出了發送窗口。
超時重傳時間選擇
RTT = 收到確認時間-發出時間
使用加權的RTTsRTT_sRTTs?表示RTT,其中:
RTTs=(1?α)×oldRTTS+α×newsamRTTsRTT_s = (1-\alpha)\times oldRTT_S+\alpha \times newsamRTT_sRTTs?=(1?α)×oldRTTS?+α×newsamRTTs?,α多取0.125
超時重傳時間RTO應該設置為:RTTS+4×RTTDRTT_S+4\times RTT_DRTTS?+4×RTTD?
其中RTTD是RTT偏差的加權平均值:
RTTD=(1?β)×oldRTTD+β×∣RTTS?newsamRTTS∣RTT_D = (1-\beta)\times oldRTT_D+\beta\times |RTT_S-newsamRTT_S|RTTD?=(1?β)×oldRTTD?+β×∣RTTS??newsamRTTS?∣,β去0.25
報文每重傳1次,重傳時間為2倍的重傳時間,不再重傳時恢復上述算法
選擇確認(Selective ACK,SACK)
解決收到報文只有少量未按序號/序號缺失的情況。
如果要使用SACK,就要在TCP的首部中添加允許SACK的選項。使用后可以報告收到不連續的字節塊的邊界,而因為首部長度限制,其最多只能生命4個字節塊,SACK應用較少。
七、TCP的流量控制
利用滑動窗口實現
發送方的發送窗口不能超過接收方的接收窗口(單位為字節)
TCP窗口的單位是字節
流量控制在ACK置位時才有意義
persistence timer
當B從無空間到有空間,發送有存儲空間的ACK時,如果這個包丟了,A就會一直等B發送非0窗口,B也會一直等A發數據,就會產生死鎖。
為了防止這種情況,TCP設置了持續計時器,它在一方收到0窗口時開始,如到期就發送一個1byte數據,接收窗口為0的探測報文段,對方會確認這個報文段,并給出接收窗口,如果還是0意味著確實沒處理完,如果不是那么僵局就可以打破了。
傳輸效率
發送時機選擇策略:
Nagle算法:
應用進程要放到TCP緩存時,先發第一個byte,收到ACK后把緩存中所有數據打包。另外如果緩存數據達到發送窗口大小/達到MSS,立即發送一個報文段
糊涂窗口綜合征及其解決辦法:
接收方一次處理1byte,發送方一次發1byte,這會產生極大overhead,此時可以讓發送方等待,使得接收緩存有一半空閑或能容納一個MSS,再發出ACK通知窗口大小。并且發送方也要積累接收方緩存一半/MSS的報文段。
八、TCP的擁塞控制
一般原理
擁塞控制是防止過多數據進入網絡導致過載,流量控制是點對點通信量的控制
橫軸輸入是單位時間內輸入分組,縱軸是單位時間內輸出分組。
擁塞控制方法
假定:數據單方傳送,接收方緩存足夠,單位是一個MSS
1. 慢開始和擁塞避免
發送方維持一個擁塞窗口cwnd(congestion window)的狀態變量,其取決于網絡擁塞程度且動態變化,不超過2~4個SMSS(發送方最大報文段)。發送方讓自己的發送窗口小于等于擁塞窗口。
1.1 慢開始算法
主機發數據是從小到大逐漸增大發送窗口(事實上是cwnd數值)
通常在開始時,先把cwnd設置為1,而每收到一個對新報文段確認后,把cwnd增加1。
1.2 擁塞避免算法
2.快重傳&快回復
快重傳:接收方應當及時發送重復確認,接收方收到3個重復確認后就重傳重復確認指定的報文
快恢復:
3. 主動隊列管理AQM
網絡層策略對TCP擁塞空值有影響,其中影響最大的就是router分組丟棄策略。如果按照最簡單的FIFO原則,叫尾部丟棄。此時TCP的發送速率將急劇下降,可能導致全局同步(大量連接速率同快同慢)。
AQM的流行方法是隨機早期丟棄:
- 平均隊列長度<minthreshold,enque
- 平均隊列長度>max threshold,丟棄
- min<平均隊列長度<max,以概率p丟棄新到達分組
九、TCP的運輸連接管理
連接建立
一開始,B的TCP服務器進程先創建傳輸控制塊TCB, 準備接受客戶進程的連接請求。如有,即作出響應。
A的TCP客戶進程也是首先創建傳輸控制模塊TCB。 然后 , 在打算建立TCP連接時,向B發出連接請求報文段, 這時首部中的同步位SYN = 1, 同時選擇一個初始序號 seq = x。TCP規定, SYN報文段(即 SYN=1的報文段)不能攜帶數據, 但要消耗掉一個序號。 這時, TCP客戶進程進入SYN-SENT (同步已發送)狀態。
B收到連接請求報文段后, 如同意建立連接, 則向A發送確認。 在確認報文段中應把SYN位和ACK位都置1, 確認號是ack = x + 1, 同時也為自己選擇一個初始序號seq = y。 請注意, 這個報文段也不能攜帶數據, 但同樣要消耗掉一個序號。 這時 TCP服務器進程進入SYN-RCVD (同步收到)狀態。
TCP客戶進程收到B的確認后, 還要向B給出確認。 確認報文段的ACK置1, 確認號ack = y+ 1, 而自己的序號seq = x+1。TCP的標準規定, ACK報文段可以攜帶數據。 但如 果不攜帶數據則不消耗序號, 在這種情況下, 下一個數據報文段的序號仍是seq = x+1。這 時, TCP連接已經建立, A進入ESTABLISHED (已建立連接)狀態。
當B收到A的確認后, 也進入ESTABLISHED狀態。
issue
- A為什么要最后一次確認?
防止已失效的連接請求報文突然傳送到了B。如果一個連接請求報文在長時間阻塞后(指A不在和B建立連接),B返回的確認報文A自然不會理睬,但B卻認為連接已建立,耗費資源等待數據(或是自己空發數據)。
連接釋放
通信雙方都可釋放連接。現在A和B都處于ESTABLI SHED狀態。A的應用進程先向其TCP發出連接釋放報文段, 并停止再發送數據, 主動關閉TCP連接。 A把連接釋放報文段首部的終止控制位FIN置1, 其序號seq = u, 它等于前面已傳送過的數據的最后一個字節序號+1.此時A進入FIN-WAIT-1狀態,等待B確認,即便不攜帶數據也消耗一個信號。
B收到連接釋放報文段后即發出確認, 確認號是ack = u + 1, 而這個報文段自己的序號是v,等于B之前傳送的最后一個byte序號+1,之后B進入CLOSE-WAIT(關閉等待)狀態。TCP服務器進程這時應通知高層應用進程, 因而從A到B這個方向的連接 釋放了, 這時的 TCP連接處于半關閉(half-close)狀態, 即A 已經沒有數據要發
送了, 但B若發送數據, A仍要接收。 也就是說, 從B到A這個方向的連接并未關閉, 這個狀態可能會持續一段時間。
A收到來自B的確認后, 就進入FIN-WAIT-2(終止等待2)狀態, 等待B發出的連接釋放報文段。
總結
以上是生活随笔為你收集整理的计网笔记(6) 传输层的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于python语言和人工智能下哪个说法
- 下一篇: Cocos2d-x学习笔记(十二)3D特