lwip中Nagle 演算法實現
阿新 • • 發佈:2019-01-31
何謂愚笨視窗綜合症:
愚笨視窗綜合症有2種變現形式:接收方愚笨視窗綜合症和傳送方愚笨視窗綜合症。
考慮以下情形。當接收方的接收快取滿時,它會通知對方它的接收允許視窗為0,使傳送方不要再繼續傳送資料。這時接收應用程式從接收快取中讀入一個位元組,那麼就空出了一個位元組的空間。接收TCP馬上告知對方它的接收允許視窗為1。傳送方因此傳送1位元組的資料給接收方。這樣,每當接收應用程式讀取1位元組資料時都會觸發傳送方傳送1位元組資料。顯然每一個數據段僅攜帶如此少的使用者資料是相當低效的。這就是接收方愚笨視窗綜合症。
和接收方一樣,傳送方也會產生這個問題。如果傳送方每次只生成少量的資料,傳送TCP就會傳輸一個攜帶少量使用者資料的資料段。這就是傳送方愚笨視窗綜合症。
要避免這個問題可以採用很簡單的啟發式方法。當接收方有少量的可用快取時,不要急著增加接收允許視窗。同樣,當傳送方有少量的資料要傳送時,也不要急著傳送,等到資料足夠多時再發送。
傳送方愚笨視窗綜合症避免演算法又稱為Nagle演算法。它非常優美簡潔,而且是自適應的。它延遲傳送的時間取決於網路的當前效能,因此能自適應於慢速的和快速的網路。
當然有時候這個演算法是我們所不希望的。在遠端互動式程式中,使用者希望每敲入一個字元都能立即傳送到伺服器上去,而不是等待這個字元被確認後才能傳送下一個字元。可以通過一個TCP選項僅用Nagle演算法。
Nagle演算法:
Nagle演算法是以他的發明人John Nagle的名字命名的,它用於自動連線許多的小緩衝器訊息;這一過程(稱為nagling)通過減少必須傳送包的個數來增加網路軟體系統的效率。Nagle演算法於1984年定義為福特航空和通訊公司IP/TCP擁塞控制方法
Lwip對nagle演算法的解釋如下:儘量將使用者的資料合成一個數據包傳送。只有在以下情況下,會立即傳送:
- 在本連線上沒有已經發送了,但未被確認的資料。
- 使用者定義了nodelay標誌位或者infr標誌位(快速重傳)
- Pcb連線上存在超過1個的未傳送資料
- Pcb連線的未傳送資料的長度超過mss(就是TCP資料包每次能夠傳輸的最大資料分段)
/**
* This is the Nagle algorithm: try to combine user data to send as few TCP
* segments as possible. Only send if
* - no previously transmitted data on the connection remains unacknowledged or
* - the TF_NODELAY flag is set (nagle algorithm turned off for this pcb) or
* - the only unsent segment is at least pcb->mss bytes long (or there is more
* than one unsent segment - with lwIP, this can happen although unsent->len < mss)
* - or if we are in fast-retransmit (TF_INFR)
*/
#define tcp_do_output_nagle(tpcb) ((((tpcb)->unacked == NULL) || \
((tpcb)->flags & (TF_NODELAY | TF_INFR)) || \
(((tpcb)->unsent != NULL) && (((tpcb)->unsent->next != NULL) || \
((tpcb)->unsent->len >= (tpcb)->mss))) \
) ? 1 : 0)