日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

TCP选项:TCP_NODELAY和TCP_CORK

發(fā)布時(shí)間:2023/12/9 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 TCP选项:TCP_NODELAY和TCP_CORK 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

From: http://blog.163.com/zhangjie_0303/blog/static/990827062012718316231/

?

Nagle算法 TCP_NODELAY和TCP_CORK

Nagle算法
根據(jù)創(chuàng)建者John Nagle命名。該算法用于對(duì)緩沖區(qū)內(nèi)的一定數(shù)量的消息進(jìn)行自動(dòng)連接。該處理過程

(稱為Nagling),通過減少必須發(fā)送的封包的數(shù)量,提高了網(wǎng)絡(luò)應(yīng)用 程序系統(tǒng)的效率。Nagle算法

,由Ford Aerospace And Communications Corporation Congestion Control in IP/TCP

internetworks(IETF RFC 896)(1984)定義,最初是用于緩沖Ford的私有TCP/IP網(wǎng)絡(luò)擁塞情況,不

過被廣泛傳播開來(lái)。

Nagle的文檔定義了一種他稱之為小封包問題的解決方法。當(dāng)某個(gè)應(yīng)用程序每次只產(chǎn)生一字節(jié)的數(shù)

據(jù),就會(huì)導(dǎo)致網(wǎng)絡(luò)由于這樣的小封包而過載(該情況通 常被稱為“發(fā)送端SB窗口并發(fā)癥”),從

而產(chǎn)生該問題。一個(gè)源自鍵盤的單一字符-1字節(jié)的數(shù)據(jù)-可能導(dǎo)致一個(gè)41字節(jié)的封包被傳送,該

封包包含了1字節(jié)的 有用數(shù)據(jù)和40字節(jié)的頭部數(shù)據(jù)。這種4000%過載的情況,在像APRANET這樣只有

很輕負(fù)載的網(wǎng)絡(luò)中是可以接受的,但在像Ford這樣的負(fù)載很重的網(wǎng) 絡(luò)中,可能強(qiáng)制重傳,導(dǎo)致封

包丟失,并且通過過度擁擠交換節(jié)點(diǎn)和網(wǎng)關(guān)降低了傳播速度。更進(jìn)一步,當(dāng)連接被丟棄時(shí),吞吐量

可能被降低。Nagle算法-通常 的實(shí)現(xiàn)方法是在一個(gè)TCP程序中插入兩行代碼-在發(fā)送方,對(duì)標(biāo)識(shí)

為沒有回應(yīng)的數(shù)據(jù)進(jìn)行緩沖(存儲(chǔ))(這句怪怪的,其實(shí)應(yīng)該是對(duì)未發(fā)送數(shù)據(jù)按順序進(jìn)行緩沖,在

發(fā)送時(shí)進(jìn)行拼接)。順序發(fā)送的數(shù)據(jù)將被保持到接收到被標(biāo)識(shí)數(shù)據(jù)的回應(yīng)或者一整包有價(jià)值的數(shù)據(jù)

需要被發(fā)送。

雖然Nagle算法用于解決Ford網(wǎng)絡(luò)內(nèi)產(chǎn)生的問題,但同樣的問題也出現(xiàn)在APRANet。通過網(wǎng)絡(luò),

Nagling被廣泛實(shí)現(xiàn),包括 internet,并且產(chǎn)生了巨大的效用-雖然某些時(shí)候在高交互性環(huán)境如一

些C/S情況下不希望進(jìn)行該處理。在這種情況下,可以通過 TCP_NODELAY套接字選項(xiàng)關(guān)閉Nagling。

注:Nagle雖然解決了小封包問題,但也導(dǎo)致了較高的不可預(yù)測(cè)的延遲,同時(shí)降低了吞吐量。


實(shí)際上這就的你動(dòng)手來(lái)自己實(shí)現(xiàn)以下Nagle算法了。實(shí)際上Nagle算法并不是很復(fù)雜,他的主要職責(zé)

是數(shù)據(jù)的累積,實(shí)際上有兩個(gè)門檻:一個(gè)就是緩 沖區(qū)中的字節(jié)數(shù)達(dá)到了一定量,另一個(gè)就是等待

了一定的時(shí)間(一般的Nagle算法都是等待200ms);這兩個(gè)門檻的任何一個(gè)達(dá)到都必須發(fā)送數(shù)據(jù)了

。一般 情況下,如果數(shù)據(jù)流量很大,第二個(gè)條件是永遠(yuǎn)不會(huì)起作用的,但當(dāng)發(fā)送小的數(shù)據(jù)包時(shí),

第二個(gè)門檻就發(fā)揮作用了,防止數(shù)據(jù)被無(wú)限的緩存在緩沖區(qū)不是好事情哦。 了解了TCP的Nagle算

法的原理之后我們可以自己動(dòng)手來(lái)實(shí)現(xiàn)一個(gè)類似的算法了,在動(dòng)手之前我們還要記住一個(gè)重要的事

情,也是我們動(dòng)手實(shí)現(xiàn)Nagle算 法的主要?jiǎng)訖C(jī)就是我想要緊急發(fā)送數(shù)據(jù)的時(shí)候就要發(fā)送了,所以對(duì)

于上面的兩個(gè)門檻之外還的增加一個(gè)門檻就是緊急數(shù)據(jù)發(fā)送。現(xiàn)在可以開始工作了,我們這里主要

給出思路:

首先我們必須在SOCKET之上再建立一層,來(lái)定義我們的自己的傳輸控制,我們的Nagle算法也是在

這層里面實(shí)現(xiàn)的。?
Disable哪個(gè)TCP的Nagle算法,都自己動(dòng)手寫了,要它干嗎?
使 用Select函數(shù)來(lái)查看是否可以發(fā)送數(shù)據(jù),當(dāng)然我們實(shí)質(zhì)是否可寫的fd_set的時(shí)候需要加入我們

的三個(gè)門檻,首先是按照字節(jié)和緊急數(shù)據(jù)來(lái)檢查,一般情 況下這兩個(gè)條件就搞定了,然后再按照

時(shí)間來(lái)決定。我們可是使用一個(gè)累積字節(jié)記數(shù)器和一個(gè)等待時(shí)間計(jì)時(shí)器。累積字節(jié)記數(shù)器在每次添

加數(shù)據(jù)到我們的控制層的時(shí) 候就累加一下,發(fā)送完畢的時(shí)候減去響應(yīng)的字節(jié)數(shù);而計(jì)時(shí)器在第一

次將數(shù)據(jù)提交給控制層的時(shí)候啟動(dòng)(可以使用Windows的GetTickcount來(lái)得 到當(dāng)前的時(shí)間),然后

在每次發(fā)送數(shù)據(jù)完畢的時(shí)候重新復(fù)位一下。?
實(shí)際上這樣就已經(jīng)實(shí)現(xiàn)了Nagle算法,而且不需要經(jīng)常調(diào)用GetTickCount而降低了系統(tǒng)的性能。

TCP_CORK

TCP鏈接的過程中,默認(rèn)開啟Nagle算法,進(jìn)行小包發(fā)送的優(yōu)化。優(yōu)化網(wǎng)絡(luò)傳輸,兼顧網(wǎng)絡(luò)延時(shí)和網(wǎng)

絡(luò)擁塞。這個(gè)時(shí)候可以置位TCP_NODELAY關(guān)閉Nagle算法,有數(shù)據(jù)包的話直接發(fā)送保證網(wǎng)絡(luò)時(shí)效性。

在進(jìn)行大量數(shù)據(jù)發(fā)送的時(shí)候可以置位TCP_CORK關(guān)閉Nagle算法保證網(wǎng)絡(luò)利用性。盡可能的進(jìn)行數(shù)據(jù)

的組包,以最大mtu傳輸,如果發(fā)送的數(shù)據(jù)包大小過小則如果在0.6~0.8S范圍內(nèi)都沒能組裝成一個(gè)

MTU時(shí),直接發(fā)送。如果發(fā)送的數(shù)據(jù)包大小足夠間隔在0.45內(nèi)時(shí),每次組裝一個(gè)MTU進(jìn)行發(fā)送。如果

間隔大于0.4~0.8S則,每過來(lái)一個(gè)數(shù)據(jù)包就直接發(fā)送。


下面摘自:http://blog.csdn.net/lin49940/archive/2009/07/26/4382303.aspx
TCP_NODELAY 選項(xiàng)

設(shè)置該選項(xiàng): public void setTcpNoDelay(boolean on) throws SocketException?
讀取該選項(xiàng): public boolean getTcpNoDelay() throws SocketException?
???? 默認(rèn)情況下, 發(fā)送數(shù)據(jù)采用Negale 算法. Negale 算法是指發(fā)送方發(fā)送的數(shù)據(jù)不會(huì)立即發(fā)出,

而是先放在緩沖區(qū), 等緩存區(qū)滿了再發(fā)出. 發(fā)送完一批數(shù)據(jù)后, 會(huì)等待接收方對(duì)這批數(shù)據(jù)的回應(yīng),

然后再發(fā)送下一批數(shù)據(jù). Negale 算法適用于發(fā)送方需要發(fā)送大批量數(shù)據(jù), 并且接收方會(huì)及時(shí)作出

回應(yīng)的場(chǎng)合, 這種算法通過減少傳輸數(shù)據(jù)的次數(shù)來(lái)提高通信效率.

???? 如果發(fā)送方持續(xù)地發(fā)送小批量的數(shù)據(jù), 并且接收方不一定會(huì)立即發(fā)送響應(yīng)數(shù)據(jù), 那么Negale

算法會(huì)使發(fā)送方運(yùn)行很慢. 對(duì)于GUI 程序, 如網(wǎng)絡(luò)游戲程序(服務(wù)器需要實(shí)時(shí)跟蹤客戶端鼠標(biāo)的移

動(dòng)), 這個(gè)問題尤其突出. 客戶端鼠標(biāo)位置改動(dòng)的信息需要實(shí)時(shí)發(fā)送到服務(wù)器上, 由于Negale 算法

采用緩沖, 大大減低了實(shí)時(shí)響應(yīng)速度, 導(dǎo)致客戶程序運(yùn)行很慢.


下面摘自http://hi.baidu.com/dirlt/blog/item/5ea4be1795d30b03c83d6d7f.html

TCP_NODELAY和TCP_CORK

這里了解一下問題的背景就好理解了[不考慮滑動(dòng)窗口加入,只是說(shuō)packet的組織]
1.歷史上TCP是每發(fā)送一次包等待一個(gè)ACK然后下一個(gè)

2.但是在一些交互式應(yīng)用下比如Telnet,結(jié)果就是我們每按一次鍵就會(huì)發(fā)送一個(gè)packet.每一個(gè)字

符配一個(gè)TCP頭效率不高,那個(gè)Nagle算法出來(lái)了。發(fā)送方法送數(shù)據(jù)A時(shí)然后再等待接受方的ACK時(shí),

積累本地收集到的所有TCP數(shù)據(jù)包然后一次性發(fā)送。但是很明顯Nagle算法不利于交互式情景

3.但是現(xiàn)代應(yīng)用下面還是存在交互式應(yīng)用的,所以有時(shí)候我們需要關(guān)閉Nagle那么可以設(shè)置

TCP_NODELAY

4.但是Nagle組織包的長(zhǎng)度是由系統(tǒng)決定的,有時(shí)候我們知道我們會(huì)每個(gè)1分鐘產(chǎn)生1字節(jié),共1000

字節(jié)。如果完全由Nagle算法來(lái)發(fā)送的話,可能還是會(huì)1字節(jié)1字節(jié)發(fā)送[這是一種極端情況,假設(shè)返

回ACK時(shí)間不是很長(zhǎng)]。這個(gè)時(shí)候首先設(shè)置TCP_CORK能夠阻塞住TCP[盡量阻塞住],等我們write完

1000字節(jié)之后,取消TCP_CORK,這個(gè)時(shí)候就能夠?qū)?000字節(jié)一次發(fā)出
TCP_NODELAY和TCP_CORK都是禁用Nagle算法,只不過NODELAY完全關(guān)閉而TCP_CORK完全由自己決定

發(fā)送時(shí)機(jī)。Linux文檔上說(shuō)兩者不要同時(shí)設(shè)置。

總結(jié)

以上是生活随笔為你收集整理的TCP选项:TCP_NODELAY和TCP_CORK的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。