• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            牽著老婆滿街逛

            嚴(yán)以律己,寬以待人. 三思而后行.
            GMail/GTalk: yanglinbo#google.com;
            MSN/Email: tx7do#yahoo.com.cn;
            QQ: 3 0 3 3 9 6 9 2 0 .

            TCP傳輸小數(shù)據(jù)包效率問題

            轉(zhuǎn)載自:http://blog.csdn.net/stamhe/archive/2009/09/19/4569530.aspx


            TCP傳輸小數(shù)據(jù)包效率問題(譯自MSDN)

            http://www.ftpff.com/blog/?q=node/16

            摘要:當(dāng)使用TCP傳輸小型數(shù)據(jù)包時,程序的設(shè)計是相當(dāng)重要的。如果在設(shè)計方案中不對TCP數(shù)據(jù)包的延遲應(yīng)答,Nagle算法,Winsock緩沖作用引起重視,將會嚴(yán)重影響程序的性能。這篇文章討論了這些問題,列舉了兩個案例,給出了一些傳輸小數(shù)據(jù)包的優(yōu)化設(shè)計方案。

            背景:當(dāng)Microsoft TCP棧接收到一個數(shù)據(jù)包時,會啟動一個200毫秒的計時器。當(dāng)ACK確認(rèn)數(shù)據(jù)包發(fā)出之后,計時器會復(fù)位,接收到下一個數(shù)據(jù)包時,會再次啟動200毫秒的計時器。為了提升應(yīng)用程序在內(nèi)部網(wǎng)和Internet上的傳輸性能,Microsoft TCP棧使用了下面的策略來決定在接收到數(shù)據(jù)包后什么時候發(fā)送ACK確認(rèn)數(shù)據(jù)包:
            1、如果在200毫秒的計時器超時之前,接收到下一個數(shù)據(jù)包,則立即發(fā)送ACK確認(rèn)數(shù)據(jù)包。
            2、如果當(dāng)前恰好有數(shù)據(jù)包需要發(fā)給ACK確認(rèn)信息的接收端,則把ACK確認(rèn)信息附帶在數(shù)據(jù)包上立即發(fā)送。
            3、當(dāng)計時器超時,ACK確認(rèn)信息立即發(fā)送。
            為了避免小數(shù)據(jù)包擁塞網(wǎng)絡(luò),Microsoft TCP棧默認(rèn)啟用了Nagle算法,這個算法能夠?qū)?yīng)用程序多次調(diào)用Send發(fā)送的數(shù)據(jù)拼接起來,當(dāng)收到前一個數(shù)據(jù)包的ACK確認(rèn)信息時,一起發(fā)送出去。下面是Nagle算法的例外情況:
            1、如果Microsoft TCP棧拼接起來的數(shù)據(jù)包超過了MTU值,這個數(shù)據(jù)會立即發(fā)送,而不等待前一個數(shù)據(jù)包的ACK確認(rèn)信息。在以太網(wǎng)中,TCP的MTU(Maximum Transmission Unit)值是1460字節(jié)。
            2、如果設(shè)置了TCP_NODELAY選項,就會禁用Nagle算法,應(yīng)用程序調(diào)用Send發(fā)送的數(shù)據(jù)包會立即被投遞到網(wǎng)絡(luò),而沒有延遲。
            為了在應(yīng)用層優(yōu)化性能,Winsock把應(yīng)用程序調(diào)用Send發(fā)送的數(shù)據(jù)從應(yīng)用程序的緩沖區(qū)復(fù)制到Winsock內(nèi)核緩沖區(qū)。Microsoft TCP棧利用類似Nagle算法的方法,決定什么時候才實際地把數(shù)據(jù)投遞到網(wǎng)絡(luò)。內(nèi)核緩沖區(qū)的默認(rèn)大小是8K,使用SO_SNDBUF選項,可以改變Winsock內(nèi)核緩沖區(qū)的大小。如果有必要的話,Winsock能緩沖大于SO_SNDBUF緩沖區(qū)大小的數(shù)據(jù)。在絕大多數(shù)情況下,應(yīng)用程序完成Send調(diào)用僅僅表明數(shù)據(jù)被復(fù)制到了Winsock內(nèi)核緩沖區(qū),并不能說明數(shù)據(jù)就實際地被投遞到了網(wǎng)絡(luò)上。唯一一種例外的情況是:通過設(shè)置SO_SNDBUT為0禁用了Winsock內(nèi)核緩沖區(qū)。

            Winsock使用下面的規(guī)則來向應(yīng)用程序表明一個Send調(diào)用的完成:
            1、如果socket仍然在SO_SNDBUF限額內(nèi),Winsock復(fù)制應(yīng)用程序要發(fā)送的數(shù)據(jù)到內(nèi)核緩沖區(qū),完成Send調(diào)用。
            2、如果Socket超過了SO_SNDBUF限額并且先前只有一個被緩沖的發(fā)送數(shù)據(jù)在內(nèi)核緩沖區(qū),Winsock復(fù)制要發(fā)送的數(shù)據(jù)到內(nèi)核緩沖區(qū),完成Send調(diào)用。
            3、如果Socket超過了SO_SNDBUF限額并且內(nèi)核緩沖區(qū)有不只一個被緩沖的發(fā)送數(shù)據(jù),Winsock復(fù)制要發(fā)送的數(shù)據(jù)到內(nèi)核緩沖區(qū),然后投遞數(shù)據(jù)到網(wǎng)絡(luò),直到Socket降到SO_SNDBUF限額內(nèi)或者只剩余一個要發(fā)送的數(shù)據(jù),才完成Send調(diào)用。

            案例1
            一個Winsock TCP客戶端需要發(fā)送10000個記錄到Winsock TCP服務(wù)端,保存到數(shù)據(jù)庫。記錄大小從20字節(jié)到100字節(jié)不等。對于簡單的應(yīng)用程序邏輯,可能的設(shè)計方案如下:
            1、客戶端以阻塞方式發(fā)送,服務(wù)端以阻塞方式接收。
            2、客戶端設(shè)置SO_SNDBUF為0,禁用Nagle算法,讓每個數(shù)據(jù)包單獨的發(fā)送。
            3、服務(wù)端在一個循環(huán)中調(diào)用Recv接收數(shù)據(jù)包。給Recv傳遞200字節(jié)的緩沖區(qū)以便讓每個記錄在一次Recv調(diào)用中被獲取到。

            性能:
            在測試中發(fā)現(xiàn),客戶端每秒只能發(fā)送5條數(shù)據(jù)到服務(wù)段,總共10000條記錄,976K字節(jié)左右,用了半個多小時才全部傳到服務(wù)器。

            分析:
            因為客戶端沒有設(shè)置TCP_NODELAY選項,Nagle算法強制TCP棧在發(fā)送數(shù)據(jù)包之前等待前一個數(shù)據(jù)包的ACK確認(rèn)信息。然而,客戶端設(shè)置SO_SNDBUF為0,禁用了內(nèi)核緩沖區(qū)。因此,10000個Send調(diào)用只能一個數(shù)據(jù)包一個數(shù)據(jù)包的發(fā)送和確認(rèn),由于下列原因,每個ACK確認(rèn)信息被延遲200毫秒:
            1、當(dāng)服務(wù)器獲取到一個數(shù)據(jù)包,啟動一個200毫秒的計時器。
            2、服務(wù)端不需要向客戶端發(fā)送任何數(shù)據(jù),所以,ACK確認(rèn)信息不能被發(fā)回的數(shù)據(jù)包順路攜帶。
            3、客戶端在沒有收到前一個數(shù)據(jù)包的確認(rèn)信息前,不能發(fā)送數(shù)據(jù)包。
            4、服務(wù)端的計時器超時后,ACK確認(rèn)信息被發(fā)送到客戶端。

            如何提高性能:
            在這個設(shè)計中存在兩個問題。第一,存在延時問題。客戶端需要能夠在200毫秒內(nèi)發(fā)送兩個數(shù)據(jù)包到服務(wù)端。因為客戶端默認(rèn)情況下使用Nagle算法,應(yīng)該使用默認(rèn)的內(nèi)核緩沖區(qū),不應(yīng)該設(shè)置SO_SNDBUF為0。一旦TCP棧拼接起來的數(shù)據(jù)包超過MTU值,這個數(shù)據(jù)包會立即被發(fā)送,不用等待前一個ACK確認(rèn)信息。第二,這個設(shè)計方案對每一個如此小的的數(shù)據(jù)包都調(diào)用一次Send。發(fā)送這么小的數(shù)據(jù)包是不很有效率的。在這種情況下,應(yīng)該把每個記錄補充到100字節(jié)并且每次調(diào)用Send發(fā)送80個記錄。為了讓服務(wù)端知道一次總共發(fā)送了多少個記錄,客戶端可以在記錄前面帶一個頭信息。

            案例二:
            一個Winsock TCP客戶端程序打開兩個連接和一個提供股票報價服務(wù)的Winsock TCP服務(wù)端通信。第一個連接作為命令通道用來傳輸股票編號到服務(wù)端。第二個連接作為數(shù)據(jù)通道用來接收股票報價。兩個連接被建立后,客戶端通過命令通道發(fā)送股票編號到服務(wù)端,然后在數(shù)據(jù)通道上等待返回的股票報價信息。客戶端在接收到第一個股票報價信息后發(fā)送下一個股票編號請求到服務(wù)端。客戶端和服務(wù)端都沒有設(shè)置SO_SNDBUF和TCP_NODELAY選項。

            性能:
            測試中發(fā)現(xiàn),客戶端每秒只能獲取到5條報價信息。

            分析:

            這個設(shè)計方案一次只允許獲取一條股票信息。第一個股票編號信息通過命令通道發(fā)送到服務(wù)端,立即接收到服務(wù)端通過數(shù)據(jù)通道返回的股票報價信息。然后,客戶端立即發(fā)送第二條請求信息,send調(diào)用立即返回,發(fā)送的數(shù)據(jù)被復(fù)制到內(nèi)核緩沖區(qū)。然而,TCP棧不能立即投遞這個數(shù)據(jù)包到網(wǎng)絡(luò),因為沒有收到前一個數(shù)據(jù)包的ACK確認(rèn)信息。200毫秒后,服務(wù)端的計時器超時,第一個請求數(shù)據(jù)包的ACK確認(rèn)信息被發(fā)送回客戶端,客戶端的第二個請求包才被投遞到網(wǎng)絡(luò)。第二個請求的報價信息立即從數(shù)據(jù)通道返回到客戶端,因為此時,客戶端的計時器已經(jīng)超時,第一個報價信息的ACK確認(rèn)信息已經(jīng)被發(fā)送到服務(wù)端。這個過程循環(huán)發(fā)生。

            如何提高性能:
            在這里,兩個連接的設(shè)計是沒有必要的。如果使用一個連接來請求和接收報價信息,股票請求的ACK確認(rèn)信息會被返回的報價信息立即順路攜帶回來。要進(jìn)一步的提高性能,客戶端應(yīng)該一次調(diào)用Send發(fā)送多個股票請求,服務(wù)端一次返回多個報價信息。如果由于某些特殊原因必須要使用兩個單向的連接,客戶端和服務(wù)端都應(yīng)該設(shè)置TCP_NODELAY選項,讓小數(shù)據(jù)包立即發(fā)送而不用等待前一個數(shù)據(jù)包的ACK確認(rèn)信息。

            提高性能的建議:
            上面兩個案例說明了一些最壞的情況。當(dāng)設(shè)計一個方案解決大量的小數(shù)據(jù)包發(fā)送和接收時,應(yīng)該遵循以下的建議:
            1、如果數(shù)據(jù)片段不需要緊急傳輸?shù)脑挘瑧?yīng)用程序應(yīng)該將他們拼接成更大的數(shù)據(jù)塊,再調(diào)用Send。因為發(fā)送緩沖區(qū)很可能被復(fù)制到內(nèi)核緩沖區(qū),所以緩沖區(qū)不應(yīng)該太大,通常比8K小一點點是很有效率的。只要Winsock內(nèi)核緩沖區(qū)得到一個大于MTU值的數(shù)據(jù)塊,就會發(fā)送若干個數(shù)據(jù)包,剩下最后一個數(shù)據(jù)包。發(fā)送方除了最后一個數(shù)據(jù)包,都不會被200毫秒的計時器觸發(fā)。
            2、如果可能的話,避免單向的Socket數(shù)據(jù)流接連。
            3、不要設(shè)置SO_SNDBUF為0,除非想確保數(shù)據(jù)包在調(diào)用Send完成之后立即被投遞到網(wǎng)絡(luò)。事實上,8K的緩沖區(qū)適合大多數(shù)情況,不需要重新改變,除非新設(shè)置的緩沖區(qū)經(jīng)過測試的確比默認(rèn)大小更高效。
            4、如果數(shù)據(jù)傳輸不用保證可靠性,使用UDP。


            posted on 2011-01-13 16:00 楊粼波 閱讀(1660) 評論(0)  編輯 收藏 引用


            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            国产精品久久精品| 国产精品狼人久久久久影院| 亚洲va中文字幕无码久久不卡 | 久久天天日天天操综合伊人av| 久久国产色av免费看| 久久精品国产国产精品四凭| 欧美大香线蕉线伊人久久| 久久久老熟女一区二区三区| 一级做a爰片久久毛片人呢| 欧美一区二区三区久久综合| 开心久久婷婷综合中文字幕| 香蕉久久一区二区不卡无毒影院 | 久久99精品国产麻豆不卡| 麻豆成人久久精品二区三区免费| 久久免费视频6| 久久99精品久久久久久| 欧美一区二区三区久久综| 久久无码中文字幕东京热| 无码任你躁久久久久久久| 精品久久久久久久中文字幕| 热re99久久精品国产99热| 久久精品中文字幕久久| 久久99热国产这有精品| 国产精品久久一区二区三区| 国产精品一久久香蕉产线看| 99久久久精品| 欧美一区二区三区久久综合| avtt天堂网久久精品| 狠狠色婷婷久久一区二区三区| 欧美精品久久久久久久自慰| 国内精品伊人久久久久av一坑| 97久久久久人妻精品专区 | 精品熟女少妇aⅴ免费久久| 久久精品成人免费国产片小草| 美女久久久久久| 国产精品99久久久久久www| 亚洲精品成人久久久| 国产99久久久国产精品小说| 色播久久人人爽人人爽人人片AV| 国内精品伊人久久久久777| 国产成人精品久久|