您目前已離線,請等候您的網際網路重新連線

設計問題-透過 TCP 使用 Winsock 傳送小型的資料區段

請注意--重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,且可能由 Microsoft Community 利用 Community Translation Framework技術或人工進行事後編修。翻譯過程並無專業譯者參與。Microsoft 同時提供使用者人為翻譯、機器翻譯及社群編修後的機器翻譯三種版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,所有翻譯文章都可能不盡完美,內容都可能出現詞彙、語意或文法上的錯誤。就翻譯內容之不正確或錯誤,或客戶因使用翻譯內容所產生的任何損害,微軟不負擔任何責任。Microsoft將依合理的商業努力不斷地更新機器翻譯軟體和工具,以期能為使用者提供更好的服務。

按一下這裡查看此文章的英文版本:214397
結論
當您需要透過 TCP 傳送小型資料封包時,Winsock 應用程式的設計是十分重要的。不會考慮帳戶之間的延遲的認可、 Nagle 演算法和 Winsock 緩衝互動的設計可大幅影響效能。本文將告訴您這些問題,使用幾個案例研究,並衍生一系列的小型資料封包傳送從 Winsock 應用程式的有效的建議。
其他相關資訊

背景

當 Microsoft TCP 堆疊會接收資料封包時,200 ms 的延遲計時器便會執行程式。當最後傳送的 ACK 時,延遲計時器會重設,並接收到下一個資料封包時,會起始另一個 200 ms 的延遲。若要增加的網際網路和內部網路應用程式的效率,Microsoft 的 TCP 堆疊會使用下列準則,決定何時收到的資料封包中傳送一個 ACK:
  • 如果延遲計時器到期之前接收到的第二個資料封包時,會傳送的 ACK。
  • 如果沒有收到第二個資料封包,並延遲計時器到期之前,相同的方向為 ACK 傳送資料,ACK 將 piggybacked 的資料區段中,並立即傳送。
  • 延遲計時器過期時,會傳送的 ACK。
若要避免 congest 網路的小型資料封包,Microsoft 的 TCP 堆疊會啟用 Nagle 演算法,根據預設,聯合多個傳送呼叫和它直到先前的資料封包的 ACK 傳送接收到來自遠端主機所傳送的延遲的小型資料緩衝區。Nagle 演算法的兩個例外狀況如下:
  • 如果堆疊已經聯合大比最大傳輸單位 (MTU) 的資料緩衝區,會立即完整大小的封包傳送而不需等待從遠端主機的 ACK。在乙太網路,TCP/IP 的 MTU 是 1460 位元組。
  • TCP_NODELAY 的通訊端選項會套用至停用 Nagle 演算法,讓小型資料封包傳送至遠端主機經過時間延遲。
若要將應用程式層級的效能最佳化,Winsock 複本資料緩衝區,從應用程式會傳送 Winsock 核心緩衝區的呼叫。然後,堆疊會使用它自己的啟發學習法 (例如 Nagle 演算法),來判斷何時實際放置在網路上的 [封包。您可以變更配置給使用 SO_SNDBUF 選項 (它將是預設的 8k) 通訊端的 Winsock 核心緩衝區數量。如有必要,Winsock 可以在多個 SO_SNDBUF 緩衝大小明顯緩衝區。在大部分的情況下,應用程式中的傳送完成只表示應用程式中的資料緩衝區傳送呼叫就會複製到 Winsock 核心緩衝區,並不表示資料已經達到網路媒體。唯一的例外是當您停用 Winsock 緩衝處理設定為 0 的 SO_SNDBUF。

Winsock 會使用下列規則來指示應用程式傳送完成進度 (取決於傳送叫用方式,完成通知可能會從 [封鎖的呼叫,信號的事件,或是要呼叫的告知函式,傳回的函式等等):
  • 如果通訊端仍位於 SO_SNDBUF 的配額,Winsock 就會將應用程式傳送資料複製,並指出應用程式的傳送完成。
  • 如果通訊端已超出 SO_SNDBUF 配額,且仍在堆疊的核心緩衝區中只有一個先前緩衝的傳送,Winsock 就會將應用程式傳送資料複製,並指出應用程式的傳送完成。
  • 如果通訊端已超出配額 SO_SNDBUF,而且沒有一個先前緩衝以上傳送堆疊核心緩衝區中,則 Winsock 複製從應用程式傳送資料。Winsock 堆疊完成不足,無法傳送,將通訊端 SO_SNDBUF 配額或只有一個未完成的傳送條件中的上一步之前,並不代表應用程式的傳送完成。

個案研究 1

概觀:

Winsock TCP 用戶端需要 10000 的資料錄傳送至 Winsock TCP 伺服器來儲存在資料庫中。記錄的大小而異 20 位元組至 100 個位元組。若要簡化應用程式邏輯,設計如下:
  • 用戶端會只封鎖傳送。伺服器會只封鎖接收。
  • 用戶端通訊端,將 SO_SNDBUF 設定為 0,使每一筆記錄熄滅時,單一的資料區段中。
  • 伺服器會呼叫在迴圈中的接收。張貼在接收緩衝區是 200 個位元組,因此可以接收到一個接收呼叫中的每一筆記錄。

效能:

在測試期間,開發人員會尋找用戶端無法只傳送給伺服器的每秒的五筆記錄。總 10000 資料錄,在 976 的 64k 位元組的資料的最大值 (10000 * 100 / 1024年),會傳送到伺服器的多個半個小時。

分析:

用戶端未設定 [TCP_NODELAY] 選項,因為 Nagle 演算法會強迫 TCP 堆疊,它可以傳送另一個封包在網路傳輸之前等候的 ACK。不過,用戶端已停用 [SO_SNDBUF] 選項設定為 0 Winsock 緩衝處理。因此,10000 傳送已傳送的呼叫,並確認個別。每個 ACK 是延遲的 200 毫秒,因為伺服器的 TCP 堆疊上的下列狀況發生:
  • 當伺服器收到的封包時,其 200 ms 的延遲計時器便會執行程式。
  • 伺服器不需要傳送任何項目上一步],因此無法 piggybacked 的 ACK。
  • 除非確認前一個封包,用戶端不會傳送另一個封包。
  • 在伺服器上的延遲計時器逾時和 ACK 送回。

如何改善:

有兩個這種設計問題。首先,沒有延遲計時器問題。用戶端必須能夠將兩個封包傳送 200 毫秒區內的伺服器,因為用戶端預設會使用 Nagle 演算法,應該只要使用 [預設 Winsock 的緩衝處理,並不將 SO_SNDBUF 設定為 0。一旦 TCP 堆疊已經聯合緩衝區大比最大傳輸單位 (MTU),會立即完整大小的封包傳送而不需等待從遠端主機的 ACK。

第二,這種設計會呼叫一個傳送這類範圍較小的每一筆記錄。傳送此大小的小型則顯得沒有效率。在此情況下,開發人員可能想要填補至 100 個位元組的每一筆記錄,並傳送 80 的資料錄從一部用戶端一次傳送的呼叫。若只要讓伺服器知道幾筆記錄將會傳送在總計中,用戶端可能想要開始通訊和修正程式大小的頁首,其中包含要遵循的記錄數目。

個案研究 2

概觀:

Winsock TCP 用戶端應用程式與提供股票報價服務 Winsock TCP 伺服器應用程式中開啟兩個連線。第一個連線作為命令通道傳送到伺服器的股票符號。第二個連線做為資料通道用於接收即時股票報價。在建立兩個連線之後,用戶端會透過命令通道傳送的股票符號,並等待 [即時股票報價通過資料通道。只能在已收到第一個即時股票報價之後,它可以傳送至伺服器的下一個股票符號要求。用戶端和伺服器未設定 [SO_SNDBUF 和 TCP_NODELAY 選項。

效能:

在測試期間,開發人員會尋找用戶端只取得每秒的五個引號。

分析:

這項設計只允許一個未完成的即時股票報價要求,一次。第一個股票符號會傳送到伺服器,透過命令通道 (連線),回應會立即傳送由伺服器回傳給用戶端透過資料通道 (連線)。然後,用戶端會立即傳送第二個股票代號要求,並要求緩衝區,在傳送呼叫至 Winsock 核心緩衝區中複製時,傳送立即傳回。不過,用戶端的 TCP 堆疊無法傳送要求從其核心緩衝區立即因為透過傳送的第一個命令通道未收到尚未。200-ms 延遲計時器在之後的伺服器命令通道過期,,第一個符號要求 ACK 恢復至用戶端。然後,第二個引號要求成功傳送至伺服器之後的第二個股票符號的報價恢復立即透過資料通道,因為在這個階段中,在用戶端資料通道延遲計時器已過期的 200 毫秒延遲。伺服器收到的 ACK,先前的報價回應時。(請記住,用戶端無法傳送 200 毫秒,第二個股票報價要求因此讓延遲計時器過期,而且傳送到伺服器的 ACK 用戶端上的 [時間)。如此一來,用戶端取得第二個報價回應,並可以發出另一個引號要求,就會受到相同的週期。

如何改善:

此處的這兩個連接 (通道) 的設計是必要的。如果只有一個連線用於即時股票報價要求和回應時,可以 piggybacked 報價回應引號要求 ACK,並立即回來。若要進一步改善效能,用戶端無法"振"多個即時股票報價要求到一個傳送至伺服器的呼叫,伺服器可能也"振"多個的報價回應到一個傳送至用戶端的呼叫。如果兩個單向通道設計是真的有必要,因為某些原因,雙方應該設定 [TCP_NODELAY] 選項,以便可以立即傳送小的封包,而不必等待前一個封包的 ACK。

建議:

這些兩個案例研究傳遞,但是有助於說明一些壞的情況。當您設計牽涉到大量的小型資料區段的應用程式傳送和 recvs,您應該考慮下列方針:
  • 如果區段的資料不會時間關鍵項目,則應用程式應該聯合它們到較大的資料區塊,若要傳遞至傳送呼叫。傳送緩衝區很可能是被複製到 Winsock 核心緩衝區的因為不應該太大的緩衝區。有點小於 8 K 是通常是有效的。只要 Winsock 核心取得大於 MTU 的區塊,會送出多個完整大小的封包,以及與任何剩下的最後一個封包。傳送的一邊,除了最後一個封包,不會 200 ms 的延遲計時器所叫用。最後一個封包,它的問題似乎奇數封包仍然能夠延遲的認可演算法。如果傳送結束堆疊會取得大於 MTU 另一個區塊,它仍然可以略過 Nagle 演算法。
  • 如果可能的話,避免與單向的資料流量的通訊端連線。透過單向通訊端的通訊會變得更加容易受到 Nagle,並且延遲認可演算法。如果通訊的要求及回應流程,您應該使用單一的通訊端傳送 」 和 「 recvs 」 都使 ACK 可以 piggybacked 上回應。
  • 如果要立即傳送所有小型的資料區段,設定 TCP_NODELAY 選項,傳送端。
  • 除非您想要保證由 Winsock 表示傳送完成時,將會傳送在網路上的封包,不應該將 SO_SNDBUF 設定為零。事實上,預設 8k 緩衝區啟發決定不適用於大部分的情況下,而且您不應加以變更除非已經測試過,您的新 Winsock 緩衝區設定能讓您更佳的效能,比預設值。此外,設定為零的 SO_SNDBUF 很有幫助,執行大量資料傳輸的應用程式。即使如此,最大的效率,您應該它搭配使用雙重緩衝 (在任何時候的多個未完成傳送),並重疊的 I/O。
  • 如果資料傳送沒有保證,使用 UDP。
参考
如需有關延遲認可及 Nagle 演算法的詳細資訊,請參閱下列:

Braden,R [1989],RFC 1122、 需求進行網際網路主機-通訊階層,網際網路工程任務推動。

警告:本文為自動翻譯

內容

文章識別碼:214397 - 最後檢閱時間:02/15/2016 04:34:00 - 修訂: 6.0

  • kbdswnet2003swept kbapi kbinfo kbip kbnetwork kbwinsock kbmt KB214397 KbMtzh
意見反應
"; var Ctrl = ""; document.write("