TCP_NODELAY和TCP_CORK

先上代碼:

         int flag = 1;
         int result = setsockopt(sock,            /* socket affected */
                                 IPPROTO_TCP,     /* set option at TCP level */
                                 TCP_NODELAY,     /* name of option */
                                 (char *) &flag,  /* the cast is historical
                                                         cruft */
                                 sizeof(int));    /* length of option value */
         if (result < 0)
            ... handle the error ...

注意:TCP_NODELAY需要頭文件 <netinet/tcp.h>

TCP_NODELAY 不使用Nagle算法,不會將小包進行拼接成大包再進行發送,直接將小包發送出去,會使得小包時候用戶體驗非常好。

TCP_NODELAY 和 TCP_CORK,這兩個選項都對網絡連接的行爲具有重要的作用。許多UNIX系統都實現了TCP_NODELAY選項,但是,
TCP_CORK則是Linux系統所獨有的而且相對較新;它首先在內核版本2.4上得以實現。此外,其他UNIX系統版本也有功能類似的選項,
值得注意的是,在某種由BSD派生的系統上的TCP_NOPUSH選項其實就是TCP_CORK的一部分具體實現。

TCP_NODELAY和TCP_CORK基本上控制了包的“Nagle化”,Nagle化在這裏的含義是採用Nagle算法把較小的包組裝爲更大的幀。
John Nagle是Nagle算法的發明人,後者就是用他的名字來命名的,他在1984年首次用這種方法來嘗試解決福特汽車公司的網絡擁塞
問題(欲瞭解詳情請參看IETF RFC 896)。他解決的問題就是所謂的silly window syndrome,中文稱“愚蠢窗口症候羣”,具體
含義是,因爲普遍終端應用程序每產生一次擊鍵操作就會發送一個包,而典型情況下一個包會擁有一個字節的數據載荷以及40個字節長的
包頭,於是產生4000%的過載,很輕易地就能令網絡發生擁塞。

Nagle化後來成了一種標準並且立即在因特網上得以實現。它現在已經成爲缺省配置了,但在我們看來,有些場合下把這一選項關掉也是
合乎需要的。現在讓我們假設某個應用程序發出了一個請求,希望發送小塊數據。我們可以選擇立即發送數據或者等待產生更多的數據然
後再一次發送兩種策略。如果我們馬上發送數據,那麼交互性的以及客戶/服務器型的應用程序將極大地受益。例如,當我們正在發送一個
較短的請求並且等候較大的響應時,相關過載與傳輸的數據總量相比就會比較低,而且,如果請求立即發出那麼響應時間也會快一些。以
上操作可以通過設置套接字的TCP_NODELAY選項來完成,這樣就禁用了Nagle算法。

另外一種情況則需要我們等到數據量達到最大時才通過網絡一次發送全部數據,這種數據傳輸方式有益於大量數據的通信性能,典型的應用
就是文件服務器。應用Nagle算法在這種情況下就會產生問題。但是,如果你正在發送大量數據,你可以設置TCP_CORK選項禁用Nagle化,
其方式正好同TCP_NODELAY相反。

注意:TCP_NODELAY和TCP_CORK都會禁止nagle算法,但是它們的行爲不同。 TCP_CORK設置後將不發送部份幀。所有排隊的部份幀只在此項清除後,才能發送。在調用sendfile(2)前準備數據報頭或對網絡吞吐量 進行優化有用處。在現在的實現中,當設置了TCP_CORK後,會有阻塞200ms,當阻塞時間過後,數據就會自動傳送。這個選項在2.5.71後 可以跟TCP_NODELAY聯合使用。
出處:http://blog.chinaunix.net/space.php?uid=20357359&do=blog&id=1963602
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章