搭配滑動窗口使用的
窗口大小
窗口越大,傳輸速度就越快,但是也不能無限大,太大了,對于可靠性會有影響
比如發生方以非常快的速度,發送,接收方的處理速度跟不上,也就會導致有效數據被接受方丟棄(又得重傳)
流量控制,就是根據接收方的處理能力(如何衡量?),干預到發送方的發送速度(調整滑動窗口的大小)
應用程序調用 read 之類的操作(scanner.next)
想象成"阻塞隊列",如果隊列里面沒有數據,應用程序在 read 就會阻塞
生產者消費者模型
發送者是生產者,接受方是消費者,通過 TCP 的接受緩沖區,作為中轉場地
所謂的"接收方的處理能力"就是接收方應用程序調用 read 的速度(調用 read 有多快,每次 read 多少) 調用 read 的速度和應用程序,代碼咋寫的 是直接相關的,想要直接衡量 read,還不太容易得
read 到的數據,一定是有序的數據
使用另一個指標來衡量 read 的速度.直接看接受緩沖區的剩余空間的大小
接收 receive, 接受accept
連接 connection 鏈接 link
TCP 是"有連接" 不是 "有鏈接"
如果發現水位比較低,就可以認為放水的速度比較快(應用程序 read 的速度比較快)
接受緩沖區的剩余空間大小:以這個指標反向制約發送方的發送速度
在接受方返回 ack 報文的時候,在 TCP 報頭中把接受緩沖區剩余空間的大小 數值 ,放到 ack 的報頭中,等發送方收到 ack 就知道接收方的處理速度了
發送方收到 ack 之后,就會根據窗口大小,重新設置下一輪 滑動窗口傳輸數據 窗口大小
16位 = > 64kb
是否意味著,TCP 的滑動窗口大小,最大只能是 64kb??? 并不是這樣
TCP 在設計的時候,充分的吸取了以前 UDP 的教訓,選項中有一個"窗口擴展因子"發送方收到 ack 之后,設置滑動窗口大小 16位窗口大小 << 窗口擴展因子,左移一位相當于 * 2,是指數增長的,這樣的窗口大小的取值范圍是非常非常大的
一般來說真實的情況是,大概率是一邊收到數據,一邊消耗數據
4001之后變成了 0 ,主機 A 這邊就會暫停發送,隊列滿了,如果不暫停發送,接下來 A 數據就會被 B 丟掉,這個時候接受緩沖區更像是阻塞隊列
A 不給 B 發數據,意味著 B 也就不給 A 返回 ack 了過了一會,主機 B 應用程序消耗了一部分數據
窗口探測包
當窗口大小為 0 的時候, A 只是不發送"業務數據"(TCP 載荷部分非空的數據,攜帶應用層數據包的數據) 但是 A 仍然會周期性的發送"窗口探測包"
另外 主機 B 也會在接受緩沖區不滿的時候給 A 發一個"窗口更新包"