# 傳輸層通訊協議 ## 傳輸層協議預期具有的特色 #### 傳輸曾希望達到 的 **理想** * **保證**訊息傳遞 (可靠傳輸) * 訊息傳遞順序**不變** * 一個訊息最多傳一份 * **任意**訊息大小 * 支援發送者與接收者的**同步** * 允許接收者對發送者執行流量控制 * 支援一台主機上執行多個不同應用程式 #### 傳輸層之下的現實 (IP網路) * 丟棄訊息 * 重新排序訊息 * 傳遞多份相同訊息 * 傳遞的訊息有大小限制 * 訊息傳遞可能有任意長短的時間延遲 :::info 所以很不可靠 ::: ## 簡易反多工協議(UDP) * demultiplexing 讓在同一個主機上的多個應用可以共享網路。   ## 可靠位組元組串流協議(TCP) Transmission Control Protocol 提供 * 可靠的服務 (Reliable) * 連線導向(Connection oriented) * 字元組串流服務(byte-stream service) #### 流量控制(Flow control) 因為一個client 上可能有多個應用,但是資料不可能即時處理,所以會先放在queue裡面。 當queue快爆炸得時候,會用這個機制去讓 sender 送慢一點,預防發送者傳送過多,的流量使接收者超出可負荷的容量 :::warning receiver只告訴 sender 自己的buffer 中剩下多少**量**(byte) ,要用幾個封包去填滿它不是關心的重點。 ::: * 封包滿了就叫sender 不要送 #### 壅塞控制(Congestion control) 用來預防網路被注 入過多的資料而造成路由器/交換器或鏈路超出負荷 * TCP 需要一個機制讓發送端得知網路的負荷量 #### End-to-end * TCP run **over the Internet**,非於一個點對點的鏈結上 * Sliding windows 須考慮: * 支援 互聯網上不同主機間建立邏輯連線(logical connections) * 不同TCP連線的 RTT 可能差異過大 * 封包充新排序 ### TCP Segment * 傳送端將若干位元組寫入一個 TCP連線,接收 端則從該 TCP 連線讀取位元組 因為 header 本身也是有大小的,所以如果data太小,很浪費頻寬 TCP 傳送端將應用程式傳送的位元組先儲存起 來, 等位元組數量形成一個合理大小的資料段 ,再將此資料段送至 TCP 的目的端主機 *  :::info sneder 每次送一些bytes string 下去,reciver 每次收一些bytes string 上來,而TCP 不管下層是如何切割以及封裝這些bytes string 。 ::: ### TCP Header  :::danger Source 以及 Destination 的 IP adderss 是寫在 IP header 裡面 ::: #### SrcPort * 源端口號(source port) #### DstPort * 目的端口號(destination port) #### Acknowledgment #### SequenceNum: * 而SequenceNum 欄位為此資料段上的第一個 資料位元組的序號 :::info 之前再講滑動視窗演算法中的 Seqnum 是layer two 對於每一個 package 的編號, 但是因為TCP是 byte-stream 所以他的編號會細緻到對每個byte 做編號。 ::: :::info Acknowledgment , SequenceNum 都是32bit ::: #### Flag:  * 6-位元旗標欄位用來傳遞 TCP 連線兩端之間的控制訊息 * **FIN**、**SYN** 結束連線 * **ACK** * 1 Acknowledgment 是有意義的 * 0 Acknowledgment 無意義 * **RST** 用來偵測連線是不是異常,用來強制清除一個連線 * **PSH** 強制送出 Buffer 的所有內容 * **URG** 這個封包裡面有警急資料 * **RESET** 接收端想要中止此連線 :::info URG=1 他會去看Urgent Pointer 指到data 中的哪個位置,此位置之前的都是警急資料。 ::: #### Advertised Windows 65532 bits = 64kb #### Checksum * 檢查碼欄位,TCP Header、TCP data 與 pseudoheader 算出 * pseudoheader 組成 * 標頭的 Source IP 位址 * 標頭的 Destination IP 位址 * length of IP header ## TCP 連線管理 * 交換資料段之前會先建立 **連線** * TCP 連線初始變數: * 序號 * 緩衝器, 流量控制訊息 (e.g. RcvWindow) 由client 提出連線需求。 ### 連線 * Client: 連線啟動者,利用一個socket 去建立連線 * Server: 等待 client 接觸,建立一個welcom socket 等待client 連線   :::info 教學: [三向交握](http://c.biancheng.net/cpp/html/3042.html) (我覺得不錯的) [數據傳輸](http://c.biancheng.net/cpp/html/3046.html) [四次握手斷開連線](http://c.biancheng.net/cpp/html/3043.html) ::: ### 斷線  :::warning client 在傳送完最後一個ACK後等帶30s 的Time wait ,去讓還在網路上跑得封包結束傳輸。 server 只要收到那個ACK就可以關閉 connection 了 ::: ### Client 狀態圖  ### Server 狀態圖  ## 重送 time out  ### 原始方法 紀錄近幾次的rtt值,做平滑計算 $SRTT_t = \alpha*SRTT_{t-1} + (1-\alpha)*RTT$ , ($\alpha =$ 0.8 ~ 0.9) $TimeOut = 2 * SRTT_t$ 如果我們單純只用送出的時間以及ACK回來的時間差來計算RTT,已左邊的case來看,我們會把重送的封包當成原本封包回來得ACK 而誤判了RTT。 若是右邊這個case 我們可能因為client 的 ACK delate ,因此server重送。 但是當原本的ACK回來時就讓我們誤判了RTT ### Karn/Partidge * 重新傳輸時**不計算 RTT 值** * 在每次**重送**之後 **逾時器值加倍** * 無法解決壅塞問題 ### Jacobson/Karels * 可以除理RTT變異化大的狀況 $SRTT_t = SRTT_{t-1}+α(RTT–SRTT_{t-1})$ $DevRTT_t = ( 1-β ) * DevRTT_{t-1} + β * ( | RTT - SRTT_{t-1} | )$ (計算差距) $RTO= SRTT + 4*DevRTT$ ### TCP 快速重送 * 重複回覆 * 接收端收到封包,皆回傳一個回覆序號,即使此序號已經回覆過 * 當傳送端收到重複回覆,它得知另一端一定是接收到非以原先發送順序抵達的封包 * 當server連續三次收到重複的回覆,TCP 會重送該封包 ## 壅塞控制 * TCP壅塞控制的概念是讓每個**傳送端決定目前網路有多大容量**,以便知道自己可以同時傳送多少 封包 * TCP被稱為**自我時序調節(self-clocking)** ,也就是**透過 ACKs 來調節封包傳輸的節奏** #### 壅塞判斷 * 發生 **封包遺失** * TCP傳送端收到三個 **重複回覆** * TCP 傳送端發生 **逾時事件** ### 線性增加倍數減少法 AIMD [例子](https://blog.csdn.net/guo_jia_liang/article/details/53064427) * 每經過一個RTT 增量一個封包,直到丟失 * Additive Increase Multiplicative Decrease * 壅塞視窗 CongestionWindow : 在收到確認 (ACK) 之前,可以發送到網絡中的資料量的 傳送端限制 * 傳送端 可傳送的資料量 : min(接收端的接收視窗, 壅塞視窗) * 如何決定『壅塞視窗』的值? TCP 觀察網路得知 * 封包遺失(收到三個重複回覆) 視為壅塞的訊號,然後減低傳輸速率 * 封包遺失,傳送端便將壅塞視窗值減半 * CongestionWindow值不可小於單一封包的最大值(也就是資料段最大值maximum segment size (MSS)) * 當網路有新增的容量(壅塞減輕),可增加CongestionWindow值(用加的) * $Increment = MSS ×(MSS/CongestionWindow)$ * $CongestionWindow+= Increment$ :::info 每當傳送端成功送出數量等於 CongestionWindow 值的封包 (所有在上一個 RTT 期間傳送的封包都成功收到回覆),便將CongestionWindow 值加上MSS值 ::: ### 慢啟動 和前面一樣,TCP 傳送端收到一個封包的回覆時,將雍塞視窗的值加上 MSS 值 * 探測網路的容量極限 * 以**指數**方式增加CongestionWindow,直到封包首次遺失(以每次收到ACK就增加) * 傳送端每經過一個RTT 時間封包就傳送**兩倍**的封包數量 ### Case * 傳送端收到三個重複回覆 * 網路雖然雍塞, 但還可以傳送一些封包 * $CongestionWindow = \dfrac{CongestionWindow}{2}$ * 逾時 * 網路雍塞嚴重!! * $CongestionWindow = 1 MSS$ ## TCP 吞吐量 * 忽略慢啟動期間 * W 為封包遺失發生時的CongWin值,當時吞吐量為$\dfrac{W}{RTT}$ * 封包遺失後,CongWin值減為$\dfrac{W}{2}$,吞吐量則減為$\dfrac{W}{2RTT}$ * 平均吞吐量: $\dfrac{0.75W}{RTT}$
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up