促進高效資料傳輸的TCP IP選項

2021-06-03 03:28:42 字數 4870 閱讀 5307

議層定義的,從osi參考模型的物理層到應用層都可能會牽扯到。

tcp_cork選項禁用nagle化,其方式正好同tcp_nodelay相反(tcp_cork 和 tcp_nodelay 是互相排斥的)。

下面就讓我們仔細分析下其工作原理。

假設應用程式使用sendfile()函式來轉移大量資料。應用協議通常要求傳送某些資訊來預先解釋資料,這些資訊其實就是報頭內

容。典型情況下報頭很小,而且套接字上設定了tcp_nodelay。有報頭的包將被立即傳輸,在某些情況下(取決於內部的包計數

器),因為這個包成功地被對方收到後需要請求對方確認。這樣,大量資料的傳輸就會被推遲而且產生了不必要的網路流量交換。

但是,如果我們在套接字上設定了tcp_cork(可以比喻為在管道上插入「塞子」)選項,具有報頭的包就會填補大量的資料,所

有的資料都根據大小自動地通過包傳輸出去。當資料傳輸完成時,最好取消tcp_cork 選項設定給連線「拔去塞子」以便任一部

分的幀都能傳送出去。這同「塞住」網路連線同等重要。總而言之,如果你肯定能一起傳送多個資料集合(例如http響應

的頭和正文),那麼我們建議你設定tcp_cork選項,這樣在這些資料之間不存在延遲。

能極大地有益於www、ftp以及檔案伺服器的效能,同時也簡化了你的工作。示例**如下:

intfd, on = 1;

…/* 此處是建立套接字等操作,出於篇幅的考慮省略*/

…setsockopt (fd, sol_tcp, tcp_cork, &on, sizeof (on)); /*

cork */

write (fd, …);

fprintf (fd, …);

sendfile (fd, …);

write (fd, …);

sendfile (fd, …);

…on = 0;

setsockopt (fd, sol_tcp, tcp_cork, &on, sizeof (on)); /*

拔去塞子 */

不幸的是,許多常用的程式並沒有考慮到以上問題。例如,ericallman編寫的sendmail就沒有對其套接字設定任何選項。

apache httpd是網際網路上最流行的web伺服器,它的所有套接字就都設定了tcp_nodelay選項,而且其效能也深受大多數使用者的滿意。

這是為什麼呢?答案就在於實現的差別之上。由bsd衍生的tcp/ip協議棧(值得注意的是freebsd)在這種狀況下的操作

就不同。當在tcp_nodelay 模式下提交大量小資料塊傳輸時,大量資訊將按照一次write()函式呼叫傳送一塊資料的方式傳送出

去。然而,因為負責請求交付確認的記數器是面向位元組而非面向包(在linux上)的,所以引入延遲的概率就降低了很多。結果

僅僅和全部資料的大小有關係。而 linux 在第一包到達之後就要求確認,freebsd則在進行如此操作之前會等待好幾百個包。

在linux系統上,tcp_nodelay的效果同習慣於bsd tcp/ip協議棧的開發者所期望的效果有很大不同,而且在linux上的apache性

能表現也會更差些。其他在linux上頻繁採用tcp_nodelay的應用程式也有同樣的問題。

相得益彰

你的資料傳輸並不需要總是準確地遵守某一選項或者其它選擇。在那種情況下,你可能想要採取更為靈活的措施來控制網路連線

:在傳送一系列當作單一訊息的資料之前設定tcp_cork,而且在傳送應立即發出的短訊息之前設定tcp_nodelay。

把零拷貝和sendfile() 系統函式結合起來(前文有述)可以顯著地提公升系統整體效率並且降低cpu負載。我們採用這一技術為

swsoft』s virtuozzo公司開發了基於名稱的主機託管子系統,實踐經驗表明,該技術可以在裝備350-mhz pentium ii cpu的pc

上實現每秒9000個http請求,這一成績在以前幾乎是不可能實現的。效能上的提高顯而易見。

伺服器的響應時間延遲。下面就讓我們來了解一些此類選項。

tcp_defer_accept

我們首先考慮的第1個選項是tcp_defer_accept(這是linux系統上的叫法,其他一些作業系統上也有同樣的選項但使用不同的名字)。

為了理解tcp_defer_accept選項的具體思想,我們有必要大致闡述一下典型的http客戶/伺服器互動過程。

請回想下tcp是如何與傳輸資料的目標建立連線的。在網路上,在分離的單元之間傳輸的資訊稱為ip包(或ip 資料報)。

乙個包總有乙個攜帶服務資訊的包頭,包頭用於內部協議的處理,並且它也可以攜帶資料負載。服務資訊的典型例子就是一套所謂的標誌,它把包標

記代表tcp/ip協議棧內的特殊含義,例如收到包的成功確認等等。通常,在經過「標記」的包裡攜帶負載是完全可能的,但有時

,內部邏輯迫使tcp/ip協議棧發出只有包頭的ip包。這些包經常會引發討厭的網路延遲而且還增加了系統的負載,結果導致網路

效能在整體上降低。

現在伺服器建立了乙個套接字同時等待連線。tcp/ip式的連線過程就是所謂「3次握手」。首先,客戶程式傳送乙個設定syn標誌

而且不帶資料負載的tcp包(乙個syn包)。伺服器則以發出帶syn/ack標誌的資料報(乙個syn/ack包)作為剛才收到包的確認

響應。客戶隨後傳送乙個ack包確認收到了第2個包從而結束連線過程。在收到客戶發來的這個syn/ack包之後,伺服器會喚醒一

個接收程序等待資料到達。當3次握手完成後,客戶程式即開始把「有用的」的資料傳送給伺服器。通常,乙個http請求的量是

很小的而且完全可以裝到乙個包裡。但是,在以上的情況下,至少有4個包將用來進行雙向傳輸,這樣就增加了可觀的延遲時間

。此外,你還得注意到,在「有用的」資料被傳送之前,接收方已經開始在等待資訊了。

為了減輕這些問題所帶來的影響,linux(以及其他的一些作業系統)在其tcp實現中包括了tcp_defer_accept選項。

它們設定在偵聽套接字的伺服器方,該選項命令核心不等待最後的ack包而且在第1個真正有資料的包到達才初始化偵聽程序。在傳送

syn/ack包之後,伺服器就會等待客戶程式傳送含資料的ip包。現在,只需要在網路上傳送3個包了,而且還顯著降低了連線建

立的延遲,對http通訊而言尤其如此。

這一選項在好些作業系統上都有相應的對等物。例如,在freebsd上,同樣的行為可以用以下**實現:

/* 為明晰起見,此處略去無關** */

struct accept_filter_arg af = ;

setsockopt(s, sol_socket, so_acceptfilter, &af, sizeof

(af));

這個特徵在freebsd上叫做「接受過濾器」,而且具有多種用法。不過,在幾乎所有的情況下其效果與tcp_defer_accept是一樣

的:伺服器不等待最後的ack包而僅僅等待攜帶資料負載的包。要了解該選項及其對高效能web伺服器的重要意義的更多資訊請

參考apache文件上的有關內容。

就http客戶/伺服器互動而言,有可能需要改變客戶程式的行為。客戶程式為什麼要傳送這種「無用的」ack包呢?這是因為,

tcp協議棧無法知道ack包的狀態。如果採用ftp而非http,那麼客戶程式直到接收了ftp伺服器提示的資料報之後才傳送資料。

在這種情況下,延遲的ack將導致客戶/伺服器互動出現延遲。為了確定ack是否必要,客戶程式必須知道應用程式協議及其當前

狀態。這樣,修改客戶行為就成為必要了。

對linux客戶程式來說,我們還可以採用另乙個選項,它也被叫做tcp_defer_accept。我們知道,套接字分成兩種型別,

偵聽套接字和連線套接字,所以它們也各自具有相應的tcp選項集合。

因此,經常同時採用的這兩類選項卻具有同樣的名字也是完全可能的。在連線套接字上設定該選項以後,客戶在收到乙個

syn/ack包之後就不再傳送ack包,而是等待使用者程式的下乙個傳送資料請求;因此,伺服器傳送的包也就相應減少了。

tcp_quickack

阻止因傳送無用包而引發延遲的另乙個方法是使用tcp_quickack選項。這一選項與 tcp_defer_accept不同,

它不但能用作管理連線建立過程而且在正常資料傳輸過程期間也可以使用。另外,它能在客戶/伺服器連線的任何一方設定。

如果知道資料不久即將傳送,那麼推遲ack包的傳送就會派上用場,而且最好在那個攜帶資料的資料報上設定ack 標誌以便把網路負載減到最小。

當傳送方肯定資料將被立即傳送(多個包)時,tcp_quickack選項可以設定為0。對處於「連線」狀態下的套接字該選項的預設值

是1,首次使用以後核心將把該選項立即復位為1(這是個一次性的選項)。

在某些情形下,發出ack包則非常有用。ack包將確認資料塊的接收,而且,當下一塊被處理時不至於引入延遲。這種資料傳輸模

式對互動過程是相當典型的,因為此類情況下使用者的輸入時刻無法**。在linux系統上這就是預設的套接字行為。

在上述情況下,客戶程式在向伺服器傳送http請求,而預先就知道請求包很短所以在連線建立之後就應該立即傳送,這可謂http

的典型工作方式。既然沒有必要傳送乙個純粹的ack包,所以設定tcp_quickack為0以提高效能是完全可能的。在伺服器方,這

兩種選項都只能在偵聽套接字上設定一次。所有的套接字,也就是被接受呼叫間接建立的套接字則會繼承原有套接字的所有選項。

通過tcp_cork、tcp_defer_accept和tcp_quickack選項的組合,參與每一http互動的資料報數量將被降低到最小的可接受水平

(根據tcp協議的要求和安全方面的考慮)。結果不僅是獲得更快的資料傳輸和請求處理速度而且還使客戶/伺服器雙向延遲實現了最小化。

小結網路程式的效能優化顯然是一項複雜的任務。優化技術包括:盡可能使用零拷貝、用tcp_cork及其等價選項組裝適當的資料報、

把傳輸資料報的數量最小化以及延遲優化等。為了提公升網路、系統的效能和可伸縮性,有必要在程式**中聯合一致地採用以上

各種可用方法。當然,清楚了解tcp/ip協議棧和作業系統的內部工作原理也是必要的。

TCP IP通訊資料傳輸流向

網路中傳輸的資料由兩部分組成 一部分是該層協議需要用到的首部,一部分是上一層傳過來的資料。首部的結構由協議具體規範詳細定義。首部明確標明了協議該如何讀取資料,從首部中可以了解該協議的必要資訊以及所要處理的內容,例如識別上一層協議的域應該從包的哪一位開始取多少個位元等等。比如乙個tcp包的資料,其在傳...

C SFTP資料傳輸

我們有些客戶公司的資料比較重要,為了安全集團公司內部都使用的是區域網,但是有時候又不得不予外界網際網路做資料互動,所以有些不重要的系統是放在外界網際網路的,這樣以來內部系統和外部系統的資料互動就成為了問題,這樣以來就使用到了sftp伺服器來作為資料傳輸的中介。下面不說了,直接上c 此處使用了第三方動...

資料傳輸方式

資料傳輸方式 1 並行傳輸與序列傳輸 並行傳輸指的是資料以成組的方式,在多條並行通道上同時進行傳輸。常用的就是將構成一 個字元 的幾位二進位製碼,分別在幾個並行通道上進行傳輸。例如,採用8單位 的字 符 可以用8個通道並行傳輸。一次傳送乙個字元,因此收 發雙方不存在字元的同步問題,不需要另加 起 止...