TCP的數(shù)據(jù)流可以大致分為兩類:交互數(shù)據(jù)流和成塊數(shù)據(jù)流,。交互數(shù)據(jù)流通常很小,,而成塊數(shù)據(jù)流通常是滿長度的(512字節(jié))。TCP在處理兩類數(shù)據(jù)的時候,,其算法有所不同,。 數(shù)據(jù)捎帶ACK對于交互式輸入,一種可能的按鍵回顯方法如下: 圖中,,中間的數(shù)據(jù)字節(jié)的確認(rèn)和數(shù)據(jù)字節(jié)的回顯可以合并發(fā)送,,即通過經(jīng)受時延的確認(rèn)(數(shù)據(jù)捎帶ACK)來合并。 數(shù)據(jù)捎帶ACK:TCP在收到數(shù)據(jù)的時候并不立即發(fā)送ACK,,而是推遲發(fā)送,,以便將ACK與需要沿該方向發(fā)送的數(shù)據(jù)一起發(fā)送,通常的實現(xiàn)時延為200ms,。 Nagle算法前面可以看到,,TCP交互的雙方每次發(fā)送數(shù)據(jù)的時候(即便是只有一個字節(jié)的數(shù)據(jù)),都需要產(chǎn)生一個(數(shù)據(jù)長度+40字節(jié))的分組,。當(dāng)數(shù)據(jù)的長度遠(yuǎn)小于40字節(jié)時,,網(wǎng)絡(luò)的實際利用率其實很低,并且大量的小分組也會增加擁塞的可能,。 Nagle 算法正是解決了該問題,。它要求一個TCP連接上最多只能有一個未被確認(rèn)的未完成的小分組,在該分組的確認(rèn)到達(dá)之前不能發(fā)送其他的小分組,。TCP收集這些小 的分組,,并在確認(rèn)到來時以一個分組的形式發(fā)出去,。其特點是:確認(rèn)到達(dá)的越快,數(shù)據(jù)也就發(fā)送的越快,,并可以發(fā)送更少的分組,。 TCP鏈接的過程中,默認(rèn)開啟Nagle算法,,進(jìn)行小包發(fā)送的優(yōu)化,。優(yōu)化網(wǎng)絡(luò)傳輸,兼顧網(wǎng)絡(luò)延時和網(wǎng)絡(luò)擁塞,。 Nagle雖然解決了小封包問題,,但也導(dǎo)致了較高的不可預(yù)測的延遲,同時降低了吞吐量,。這個時候可以置位TCP_NODELAY關(guān)閉 Nagle算法,,有數(shù)據(jù)包的話直接發(fā)送保證網(wǎng)絡(luò)時效性。 在 進(jìn)行大量數(shù)據(jù)發(fā)送的時候可以置位TCP_CORK關(guān)閉Nagle算法保證網(wǎng)絡(luò)利用性,。盡可能的進(jìn)行數(shù)據(jù)的組包,,以最大mtu傳輸,,如果發(fā)送的數(shù)據(jù)包大小過 小則如果在0.6~0.8S范圍內(nèi)都沒能組裝成一個MTU時,,直接發(fā)送。如果發(fā)送的數(shù)據(jù)包大小足 夠間隔在0.45內(nèi)時,,每次組裝一個MTU進(jìn)行發(fā)送,。如果間隔大于0.4~0.8S則,每過來一個數(shù)據(jù)包就直接發(fā)送,。 TCP_NODELAY 選項 默認(rèn)情況下,,發(fā)送數(shù)據(jù)采用Negale 算法。這樣雖然提高了網(wǎng)絡(luò)吞吐量,,但是實時性卻降低了,,在一些交互性很強(qiáng)的應(yīng)用程序來說是不允許的,使用TCP_NODELAY選項可以禁止Negale 算法,。 此時,,應(yīng)用程序向內(nèi)核遞交的每個數(shù)據(jù)包都會立即發(fā)送出去。需要注意的是,,雖然禁止了Negale 算法,,但網(wǎng)絡(luò)的傳輸仍然受到TCP確認(rèn)延遲機(jī)制的影響。 TCP_CORK 選項
所謂的CORK就是塞子的意思,,形象地理解就是用CORK將連接塞住,,使得數(shù)據(jù)先不發(fā)出去,等到拔去塞子后再發(fā)出去,。設(shè)置該選項后,,內(nèi)核會盡力把小數(shù)據(jù)包
拼接成一個大的數(shù)據(jù)包(一個MTU)再發(fā)送出去,,當(dāng)然若一定時間后(一般為200ms,該值尚待確認(rèn)),,內(nèi)核仍然沒有組合成一個MTU時也必須發(fā)送現(xiàn)有的
數(shù)據(jù)(不可能讓數(shù)據(jù)一直等待吧),。 Nagle算法與CORK算法區(qū)別
參考: |
|
來自: xn00 > 《TCP/IP詳解》