九九热这里直有精品,1区二区三区在线播放,玖玖爱在线观看资源,国产aⅴ综合网,午夜福利男女,日本亚洲欧美三级,日韩无码黄色导航,内射少妇13区,中文字幕高清网

您身邊的軟件定制專(zhuān)家--9年開(kāi)發(fā)經(jīng)驗(yàn)為您護(hù)航

18678812288
0531-88887250

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

文章作者:濟(jì)南軟件開(kāi)發(fā) 時(shí)間:2016年11月08日

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

  背景:當(dāng)Microsoft TCP棧接收到一個(gè)數(shù)據(jù)包時(shí),會(huì)啟動(dòng)一個(gè)200毫秒的計(jì)時(shí)器。當(dāng)ACK確認(rèn)數(shù)據(jù)包發(fā)出之后,計(jì)時(shí)器會(huì)復(fù)位,接收到下一個(gè)數(shù)據(jù)包時(shí),會(huì)再次啟動(dòng)200毫秒的計(jì)時(shí)器。為了提升應(yīng)用程序在內(nèi)部網(wǎng)和Internet上的傳輸性能,Microsoft TCP棧使用了下面的策略來(lái)決定在接收到數(shù)據(jù)包后什么時(shí)候發(fā)送ACK確認(rèn)數(shù)據(jù)包:

  1、如果在200毫秒的計(jì)時(shí)器超時(shí)之前,接收到下一個(gè)數(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)計(jì)時(shí)器超時(shí),ACK確認(rèn)信息立即發(fā)送。

  為了避免小數(shù)據(jù)包擁塞網(wǎng)絡(luò),Microsoft TCP棧默認(rèn)啟用了Nagle算法,這個(gè)算法能夠?qū)?yīng)用程序多次調(diào)用Send發(fā)送的數(shù)據(jù)拼接起來(lái),當(dāng)收到前一個(gè)數(shù)據(jù)包的ACK確認(rèn)信息時(shí),一起發(fā)送出去。下面是Nagle算法的例外情況:

  1、如果Microsoft TCP棧拼接起來(lái)的數(shù)據(jù)包超過(guò)了MTU值,這個(gè)數(shù)據(jù)會(huì)立即發(fā)送,而不等待前一個(gè)數(shù)據(jù)包的ACK確認(rèn)信息。在以太網(wǎng)中,TCP的MTU(Maximum Transmission Unit)值是1460字節(jié)。

  2、如果設(shè)置了TCP_NODELAY選項(xiàng),就會(huì)禁用Nagle算法,應(yīng)用程序調(diào)用Send發(fā)送的數(shù)據(jù)包會(huì)立即被投遞到網(wǎng)絡(luò),而沒(méi)有延遲。

  為了在應(yīng)用層優(yōu)化性能,Winsock把應(yīng)用程序調(diào)用Send發(fā)送的數(shù)據(jù)從應(yīng)用程序的緩沖區(qū)復(fù)制到Winsock內(nèi)核緩沖區(qū)。Microsoft TCP棧利用類(lèi)似Nagle算法的方法,決定什么時(shí)候才實(shí)際地把數(shù)據(jù)投遞到網(wǎng)絡(luò)。內(nèi)核緩沖區(qū)的默認(rèn)大小是8K,使用SO_SNDBUF選項(xiàng),可以改變Winsock內(nèi)核緩沖區(qū)的大小。如果有必要的話(huà),Winsock能緩沖大于SO_SNDBUF緩沖區(qū)大小的數(shù)據(jù)。在絕大多數(shù)情況下,應(yīng)用程序完成Send調(diào)用僅僅表明數(shù)據(jù)被復(fù)制到了Winsock內(nèi)核緩沖區(qū),并不能說(shuō)明數(shù)據(jù)就實(shí)際地被投遞到了網(wǎng)絡(luò)上。唯一一種例外的情況是:通過(guò)設(shè)置SO_SNDBUT為0禁用了Winsock內(nèi)核緩沖區(qū)。

  Winsock使用下面的規(guī)則來(lái)向應(yīng)用程序表明一個(gè)Send調(diào)用的完成:

  1、如果socket仍然在SO_SNDBUF限額內(nèi),Winsock復(fù)制應(yīng)用程序要發(fā)送的數(shù)據(jù)到內(nèi)核緩沖區(qū),完成Send調(diào)用。

  2、如果Socket超過(guò)了SO_SNDBUF限額并且先前只有一個(gè)被緩沖的發(fā)送數(shù)據(jù)在內(nèi)核緩沖區(qū),Winsock復(fù)制要發(fā)送的數(shù)據(jù)到內(nèi)核緩沖區(qū),完成Send調(diào)用。

  3、如果Socket超過(guò)了SO_SNDBUF限額并且內(nèi)核緩沖區(qū)有不只一個(gè)被緩沖的發(fā)送數(shù)據(jù),Winsock復(fù)制要發(fā)送的數(shù)據(jù)到內(nèi)核緩沖區(qū),然后投遞數(shù)據(jù)到網(wǎng)絡(luò),直到Socket降到SO_SNDBUF限額內(nèi)或者只剩余一個(gè)要發(fā)送的數(shù)據(jù),才完成Send調(diào)用。

  案例1

  一個(gè)Winsock TCP客戶(hù)端需要發(fā)送10000個(gè)記錄到Winsock TCP服務(wù)端,保存到數(shù)據(jù)庫(kù)。記錄大小從20字節(jié)到100字節(jié)不等。對(duì)于簡(jiǎn)單的應(yīng)用程序邏輯,可能的設(shè)計(jì)方案如下:

  1、客戶(hù)端以阻塞方式發(fā)送,服務(wù)端以阻塞方式接收。

  2、客戶(hù)端設(shè)置SO_SNDBUF為0,禁用Nagle算法,讓每個(gè)數(shù)據(jù)包單獨(dú)的發(fā)送。

  3、服務(wù)端在一個(gè)循環(huán)中調(diào)用Recv接收數(shù)據(jù)包。給Recv傳遞200字節(jié)的緩沖區(qū)以便讓每個(gè)記錄在一次Recv調(diào)用中被獲取到。

  性能:

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

  分析:

  因?yàn)榭蛻?hù)端沒(méi)有設(shè)置TCP_NODELAY選項(xiàng),Nagle算法強(qiáng)制TCP棧在發(fā)送數(shù)據(jù)包之前等待前一個(gè)數(shù)據(jù)包的ACK確認(rèn)信息。然而,客戶(hù)端設(shè)置SO_SNDBUF為0,禁用了內(nèi)核緩沖區(qū)。因此,10000個(gè)Send調(diào)用只能一個(gè)數(shù)據(jù)包一個(gè)數(shù)據(jù)包的發(fā)送和確認(rèn),由于下列原因,每個(gè)ACK確認(rèn)信息被延遲200毫秒:

  1、當(dāng)服務(wù)器獲取到一個(gè)數(shù)據(jù)包,啟動(dòng)一個(gè)200毫秒的計(jì)時(shí)器。

  2、服務(wù)端不需要向客戶(hù)端發(fā)送任何數(shù)據(jù),所以,ACK確認(rèn)信息不能被發(fā)回的數(shù)據(jù)包順路攜帶。

  3、客戶(hù)端在沒(méi)有收到前一個(gè)數(shù)據(jù)包的確認(rèn)信息前,不能發(fā)送數(shù)據(jù)包。

  4、服務(wù)端的計(jì)時(shí)器超時(shí)后,ACK確認(rèn)信息被發(fā)送到客戶(hù)端。

  如何提高性能:

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

  案例二:

  一個(gè)Winsock TCP客戶(hù)端程序打開(kāi)兩個(gè)連接和一個(gè)提供股票報(bào)價(jià)服務(wù)的Winsock TCP服務(wù)端通信。第一個(gè)連接作為命令通道用來(lái)傳輸股票編號(hào)到服務(wù)端。第二個(gè)連接作為數(shù)據(jù)通道用來(lái)接收股票報(bào)價(jià)。兩個(gè)連接被建立后,客戶(hù)端通過(guò)命令通道發(fā)送股票編號(hào)到服務(wù)端,然后在數(shù)據(jù)通道上等待返回的股票報(bào)價(jià)信息。客戶(hù)端在接收到第一個(gè)股票報(bào)價(jià)信息后發(fā)送下一個(gè)股票編號(hào)請(qǐng)求到服務(wù)端??蛻?hù)端和服務(wù)端都沒(méi)有設(shè)置SO_SNDBUF和TCP_NODELAY選項(xiàng)。

  性能:

  測(cè)試中發(fā)現(xiàn),客戶(hù)端每秒只能獲取到5條報(bào)價(jià)信息。

  分析:

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

  如何提高性能:

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

  提高性能的建議:

  上面兩個(gè)案例說(shuō)明了一些最壞的情況。當(dāng)設(shè)計(jì)一個(gè)方案解決大量的小數(shù)據(jù)包發(fā)送和接收時(shí),應(yīng)該遵循以下的建議:

  1、如果數(shù)據(jù)片段不需要緊急傳輸?shù)脑?huà),應(yīng)用程序應(yīng)該將他們拼接成更大的數(shù)據(jù)塊,再調(diào)用Send。因?yàn)榘l(fā)送緩沖區(qū)很可能被復(fù)制到內(nèi)核緩沖區(qū),所以緩沖區(qū)不應(yīng)該太大,通常比8K小一點(diǎn)點(diǎn)是很有效率的。只要Winsock內(nèi)核緩沖區(qū)得到一個(gè)大于MTU值的數(shù)據(jù)塊,就會(huì)發(fā)送若干個(gè)數(shù)據(jù)包,剩下最后一個(gè)數(shù)據(jù)包。發(fā)送方除了最后一個(gè)數(shù)據(jù)包,都不會(huì)被200毫秒的計(jì)時(shí)器觸發(fā)。

  2、如果可能的話(huà),避免單向的Socket數(shù)據(jù)流接連。

  3、不要設(shè)置SO_SNDBUF為0,除非想確保數(shù)據(jù)包在調(diào)用Send完成之后立即被投遞到網(wǎng)絡(luò)。事實(shí)上,8K的緩沖區(qū)適合大多數(shù)情況,不需要重新改變,除非新設(shè)置的緩沖區(qū)經(jīng)過(guò)測(cè)試的確比默認(rèn)大小更高效。


想要了解更多詳情歡迎來(lái)電咨詢(xún)18678812288
登陸網(wǎng)址:m.h6244.cn。
聯(lián)系人:王經(jīng)理。

宁河县| 苏州市| 景泰县| 台湾省| 晋城| 常德市| 武乡县| 利津县| 刚察县| 龙泉市| 商城县| 台南县| 陵水| 双鸭山市| 黎平县| 南江县| 南江县| 京山县| 民权县| 黑龙江省| 余干县| 托克托县| 温宿县| 博白县| 利津县| 油尖旺区| 庆城县| 南康市| 泸西县| 花莲县| 建宁县| 英山县| 白朗县| 靖安县| 凤凰县| 绩溪县| 阜康市| 竹山县| 莎车县| 同江市| 开阳县|