李 國,鞏光志,王冬冬
(中國民航大學(xué) a.計算機(jī)學(xué)院;b.航空自動化學(xué)院,天津 300300)
常用的網(wǎng)絡(luò)數(shù)據(jù)傳輸協(xié)議有TCP和UDP[1-2],TCP是面向連接的協(xié)議,包含了專門的傳遞保證機(jī)制,具有高度可靠性,但效率很低;傳統(tǒng)的UDP協(xié)議通信效率高,但是可靠性差,不適合那些對可靠性要求較高、實(shí)時性較強(qiáng)的應(yīng)用環(huán)境。隨著網(wǎng)絡(luò)傳輸?shù)目焖侔l(fā)展,在某些特定環(huán)境中,對大量聲音數(shù)據(jù)的可靠性和高效性要求都較高,TCP協(xié)議不能滿足效率上的要求,UDP又不能滿足可靠性的要求。
目前,已有多種基于UDP的數(shù)據(jù)可靠傳輸協(xié)議產(chǎn)生,但是擁塞控制策略中大都仍然是傳統(tǒng)的停等協(xié)議或滑動窗口協(xié)議。但是人們希望發(fā)送端能根據(jù)網(wǎng)絡(luò)情況的好壞來自動調(diào)整發(fā)送數(shù)據(jù)的速度,當(dāng)網(wǎng)絡(luò)帶寬充足時,盡量多發(fā)數(shù)據(jù)以避免帶寬的浪費(fèi),網(wǎng)絡(luò)情況不好時盡量少發(fā)數(shù)據(jù)或不發(fā)數(shù)據(jù)來避免網(wǎng)絡(luò)的擁塞。為此,本文針對特定的聲音數(shù)據(jù),提出一種新的基于UDP的數(shù)據(jù)可靠傳輸方法,詳細(xì)分析了分區(qū)確認(rèn)及分包重組算法,基于選擇重發(fā)策略,采用對網(wǎng)絡(luò)傳輸狀況自適應(yīng)的擁塞控制策略,有效提高網(wǎng)絡(luò)帶寬的利用率。
從計算機(jī)網(wǎng)絡(luò)體系結(jié)構(gòu)的角度來說,該協(xié)議的層次結(jié)構(gòu)類似于UDT[1],屬于應(yīng)用層級別的面向連接協(xié)議。本協(xié)議的體系結(jié)構(gòu)延用了UDT的結(jié)構(gòu),即在傳輸層和應(yīng)用層之間添加了一層具有數(shù)據(jù)包確認(rèn)、重發(fā)和擁塞控制功能的控制協(xié)議[3],添加的新協(xié)議層可以保證數(shù)據(jù)傳輸?shù)目煽啃?,而UDP仍然真正負(fù)責(zé)數(shù)據(jù)的傳輸,協(xié)議結(jié)構(gòu)圖如圖1所示。
圖1 協(xié)議結(jié)構(gòu)圖Fig.1 Protocol structure
UDT協(xié)議包含了可靠控制和擁塞控制策略,UDT協(xié)議是面向連接的,進(jìn)行數(shù)據(jù)傳輸之前雙方必須建立連接才能進(jìn)行通信[4]。其數(shù)據(jù)傳輸過程的具體實(shí)現(xiàn)如下:首先是連接建立的過程,UDT的服務(wù)器端先啟動,客戶端連接時向其發(fā)送握手包;服務(wù)器端收到握手包之后向客戶端發(fā)送握手響應(yīng)包,而客戶端定時的向服務(wù)器發(fā)送相同的握手包,直到接收到握手響應(yīng)包才停止,客戶端只要收到一個握手響應(yīng)包,就準(zhǔn)備進(jìn)行數(shù)據(jù)的接收和發(fā)送,對后續(xù)收到的握手響應(yīng)包直接丟棄處理;服務(wù)器端每接到一個客戶端的握手包就會返回一個響應(yīng)包,這樣可以避免發(fā)生客戶端收不到握手響應(yīng)包的情況,服務(wù)器端收到對方發(fā)來的第一個握手包開始,就直接進(jìn)入數(shù)據(jù)接收和發(fā)送的準(zhǔn)備就緒狀態(tài)。當(dāng)數(shù)據(jù)發(fā)送完畢進(jìn)行關(guān)閉連接時,數(shù)據(jù)發(fā)送端會發(fā)送關(guān)閉請求到接收端,接收端接收到這個請求以后就立即關(guān)閉連接并釋放資源。因?yàn)檎埱笾噶钍峭ㄟ^UDP協(xié)議傳輸,所以接收端就不一定能收到這個關(guān)閉請求,此時接收端判斷等待數(shù)據(jù)接收的時間是否超過指定值,超過時就關(guān)閉連接。UDT協(xié)議在傳輸數(shù)據(jù)時,發(fā)送端會定時向?qū)Ψ桨l(fā)送心跳包,如果在某一指定時間內(nèi)沒有收到任何數(shù)據(jù)包,就判定此時連接已經(jīng)被中斷,然后再進(jìn)行重連。
本文協(xié)議也是面向連接的協(xié)議,建立連接的過程和UDT一樣,但是連接關(guān)閉的方法與UDT不同。UDT協(xié)議是通過時間溢出機(jī)制來關(guān)閉,如果網(wǎng)絡(luò)情況很差,接收方收不到發(fā)來的數(shù)據(jù),發(fā)送方就會對數(shù)據(jù)一直進(jìn)行重發(fā),但是接收方收不到數(shù)據(jù)的時間到達(dá)指定的溢出時間就會判定為數(shù)據(jù)傳送完畢,而實(shí)際上發(fā)送方并沒有發(fā)送關(guān)閉信息,這樣雙方就不得不重新進(jìn)行連接來傳送數(shù)據(jù),而且建立連接的過程耗時較多。而本文協(xié)議關(guān)閉連接過程和建立連接的過程類似,當(dāng)發(fā)送方發(fā)完數(shù)據(jù)之后,每隔一段時間就發(fā)送一個關(guān)閉信息到對方,之后等待接收關(guān)閉信息返回包,當(dāng)接收到返回包時發(fā)送方就最后一次發(fā)送一個最終返回包信息,然后關(guān)閉連接;而接收端每收到一個關(guān)閉信息就向發(fā)送方返回三次同一個數(shù)據(jù)包(這樣發(fā)送方未收到返回包的概率降低了兩倍),告訴發(fā)送方已經(jīng)收到了關(guān)閉信息,當(dāng)收到最終返回包之后關(guān)閉連接,因?yàn)樽罱K返回包可能收不到,這時接收方就通過時間溢出機(jī)制關(guān)閉連接,雖然這樣會比UDT多了一道關(guān)閉程序,但避免了協(xié)議誤判關(guān)閉信息而導(dǎo)致連接中斷的情況。
另一方面,本文協(xié)議中是采用分區(qū)確認(rèn)的方法,本質(zhì)上是用空間換時間的思想,內(nèi)存空間中開辟相同的幾個區(qū),同時使用進(jìn)行傳輸數(shù)據(jù),可以很大程度地提高數(shù)據(jù)的傳輸效率。二者使用的擁塞控制算法也不一樣,UDT協(xié)議采用常見的AIMD(加性增加乘性減少)算法[5-7],該算法的基本思想是,當(dāng)發(fā)送端收到ACK,并且沒有檢測到丟包事件,則擁塞窗口加1,當(dāng)TCP發(fā)送端檢測到丟包事件后,擁塞窗口就減半。增加擁塞窗口使得向網(wǎng)絡(luò)中發(fā)送的數(shù)據(jù)量急劇增加,網(wǎng)絡(luò)中的有用資源能夠被較快速的使用;而當(dāng)擁塞發(fā)生時,向網(wǎng)絡(luò)中發(fā)送的數(shù)據(jù)量會急劇減少。數(shù)據(jù)的發(fā)送速率就會表現(xiàn)為較大的振蕩性,致使AIMD算法欠缺網(wǎng)絡(luò)使用的公平性和穩(wěn)定性。而本文協(xié)議采用本文提出的MIRD擁塞控制算法,使得數(shù)據(jù)發(fā)送速率對網(wǎng)絡(luò)繁忙程度自動適應(yīng),從而實(shí)現(xiàn)帶寬利用的公平性和穩(wěn)定性。
本文提出一種新的分包與重組[4]方法,基于分區(qū)確認(rèn)的確認(rèn)機(jī)制的基本思想是:發(fā)送端在內(nèi)存中開辟四個大小相同的區(qū)域(A,B,C,D),每個區(qū)結(jié)構(gòu)相同,數(shù)據(jù)包括該區(qū)名稱,數(shù)據(jù)標(biāo)志、計時變量、超時標(biāo)志、等待標(biāo)志、丟包標(biāo)志、重發(fā)數(shù)據(jù)以及分包數(shù)據(jù)區(qū)域等。其中重發(fā)數(shù)據(jù)中存放需要重發(fā)的包序號,分包數(shù)據(jù)區(qū)域存放已編碼排序的待發(fā)送數(shù)據(jù)包,總數(shù)用一個變量記錄。而接收端開辟四個區(qū)域與發(fā)送端對應(yīng),存放發(fā)送端各區(qū)發(fā)來的數(shù)據(jù),并用重組算法對數(shù)據(jù)進(jìn)行提取。
數(shù)據(jù)傳輸?shù)恼w流程圖如圖2所示,心跳包計時器是用來設(shè)置心跳包的定時器開始時間,總體上完成數(shù)據(jù)的拆分和發(fā)送。每個分區(qū)里的數(shù)據(jù)分配流程如圖3所示,對某一分區(qū)分配數(shù)據(jù)之后,都要重新設(shè)置該區(qū)各個標(biāo)志位,并重置該區(qū)重發(fā)機(jī)制中的超時定時器。
圖2的數(shù)據(jù)分配模塊中分配數(shù)據(jù)時,是按照A、B、C、D的優(yōu)先級先后分配數(shù)據(jù)。數(shù)據(jù)傳輸過程中,網(wǎng)絡(luò)傳輸速率大時,A區(qū)很快就能收到接收方發(fā)來的確認(rèn)包,在第二次分配數(shù)據(jù)之前,若A區(qū)數(shù)據(jù)得到確認(rèn),則分配數(shù)據(jù)時仍然只對A區(qū)進(jìn)行分配,從而B、C、D區(qū)就處于備用狀態(tài)。當(dāng)網(wǎng)絡(luò)速率變小時,A區(qū)數(shù)據(jù)就有可能得不到及時確認(rèn)而不能被分配數(shù)據(jù),從而B、C、D區(qū)開始被分配數(shù)據(jù),以減小A區(qū)的開銷。
發(fā)送數(shù)據(jù)時是按各區(qū)順序發(fā)送,每一次數(shù)據(jù)的發(fā)送都要掃描完4個區(qū)才完畢,這樣可以確保各區(qū)數(shù)據(jù)能夠全部發(fā)送。以A區(qū)為例,具體流程如圖4所示,該流程完成了各區(qū)數(shù)據(jù)的全部發(fā)送工作和丟包之后的重發(fā)工作。
對于接收端來說,如果接收端A區(qū)數(shù)據(jù)包全部收到,接收端處理用戶數(shù)據(jù),之后給對方發(fā)送ACK包,并且初始化該區(qū)并重置各個標(biāo)志位;若A區(qū)數(shù)據(jù)未收完,但是該區(qū)接收定時器達(dá)到一定值,則接收端給對方發(fā)送NCK包,NCK數(shù)據(jù)包包括該區(qū)名稱及所丟失包的序號,只需要求對方重傳丟失的包即可。其它區(qū)數(shù)據(jù)處理也一樣。
在程序設(shè)計中,數(shù)據(jù)確認(rèn)模塊是一個單獨(dú)的線程,通過判斷接收過來的確認(rèn)包是ACK還是NCK,發(fā)送端決定是將該區(qū)數(shù)據(jù)清空還是重新發(fā)送。發(fā)送端對確認(rèn)包的處理過程是:當(dāng)收到的確認(rèn)包為ACK時,發(fā)送端就把該區(qū)重新初始化,等待下次分配數(shù)據(jù);若收到的是NCK確認(rèn)包,則該區(qū)的丟包序號將被提取出來,而且丟包標(biāo)志被置1以表明該區(qū)發(fā)生了丟包情況。具體流程如圖5所示。
另外還有定時器線程,當(dāng)數(shù)據(jù)發(fā)送完畢時,由數(shù)據(jù)發(fā)送線程關(guān)閉掉其它線程即可。
傳輸數(shù)據(jù)分包的目的是使接收方能夠?qū)⒁幌盗袩o序到達(dá)的報文進(jìn)行正確重組[5]。以太網(wǎng)的最大傳送單元(maximum transfer unit,MTU)為 1 500 kb,其他網(wǎng)絡(luò)環(huán)境有的限制為128 kb或更少。若需要發(fā)送的數(shù)據(jù)報總長為L字節(jié),當(dāng)前網(wǎng)絡(luò)MTU為M字節(jié),網(wǎng)絡(luò)當(dāng)前丟包率為Pb,則接收端全部收到該數(shù)據(jù)報的概率為:Pbk=(1-Pb)L/M。由此可知,當(dāng)數(shù)據(jù)報總長大于MTU時,減小數(shù)據(jù)報總長可明顯提高數(shù)據(jù)報到達(dá)概率。
數(shù)據(jù)報在分包時,每個數(shù)據(jù)包必須加上一個包頭,以便重組數(shù)據(jù)。若包頭長度為Sh,數(shù)據(jù)包中的用戶數(shù)據(jù)長度為Su,則實(shí)際數(shù)據(jù)報利用效率為η=Su/(Sh+Su)。即包頭長度一定時,增大每個包內(nèi)的用戶數(shù)據(jù)長度可以提高網(wǎng)絡(luò)利用率。綜合數(shù)據(jù)報的到達(dá)概率和有效利用率兩個矛盾因素,本文選用1 kb的固定分包長度。A、B、C、D各區(qū)的分包數(shù)據(jù)區(qū)域中存放著待發(fā)送的數(shù)據(jù)包,發(fā)送的數(shù)據(jù)包分包形式為:
確認(rèn)包格式為:
分包序號是指分配數(shù)據(jù)之后,該數(shù)據(jù)包是該區(qū)的第幾個待發(fā)送的數(shù)據(jù)包。分包總數(shù)是指該區(qū)分配數(shù)據(jù)之后總共多少個數(shù)據(jù)包,為了減少包頭長度,規(guī)定最多是9個數(shù)據(jù)包。分配次數(shù)是指該區(qū)第幾次分配數(shù)據(jù),這樣在接收端重復(fù)發(fā)送同一個ACK包的情況下,可以避免發(fā)送端誤認(rèn)確認(rèn)信息。如接收端某區(qū)數(shù)據(jù)接收完畢,則發(fā)送ACK給對方,因?yàn)锳CK包本身長度很小,為增加ACK包的到達(dá)概率,接收端每次都連續(xù)三次發(fā)送相同的ACK給對方,然后清空接收端該區(qū)數(shù)據(jù)。若發(fā)送端收到一個接收端返回的ACK包,則先判斷該區(qū)的分配次數(shù)和ACK包中的分配次數(shù)是否一樣,若相同則會清空發(fā)送端該區(qū)的數(shù)據(jù),下次分配數(shù)據(jù)時則可能會將該區(qū)填入數(shù)據(jù);若分配次數(shù)不能匹配,則對該ACK包置之不理,以避免相同的ACK包確認(rèn)了剛剛重新分配數(shù)據(jù)的該區(qū)。若三次ACK包都沒有到達(dá)對方(此情況出現(xiàn)概率很?。?,則通過發(fā)送端的重發(fā)機(jī)制,把該區(qū)數(shù)據(jù)重發(fā)給接收端,再次等待確認(rèn)即可。當(dāng)接收端未完全接收數(shù)據(jù),每當(dāng)定時器到時,則會發(fā)送NCK給對方,此時會把當(dāng)前未收到的數(shù)據(jù)包的序號存放到一個長度為9的數(shù)組中,以字符格式隨NCK發(fā)送給接收端,使得發(fā)送端重新發(fā)送接收端要求重傳的數(shù)據(jù)包。另外,發(fā)送端定時發(fā)送心跳包,格式為:
心跳包信息包含4個區(qū)的等待狀態(tài)及分配次數(shù)。其中的等待標(biāo)志只能取0或1,0表示未等待確認(rèn),1表示該區(qū)正處于等待確認(rèn)狀態(tài)。這樣接收端就可以通過心跳包來決定是否需要重發(fā)確認(rèn)包了。
分區(qū)確認(rèn)機(jī)制中發(fā)送數(shù)據(jù)時,各區(qū)都設(shè)置有一個超時間隔,時間超過這個值,才會發(fā)送該區(qū)數(shù)據(jù),若超時間隔設(shè)為0,則每當(dāng)分配完數(shù)據(jù),該區(qū)就會將數(shù)據(jù)立刻發(fā)送。所以不同的超時間隔取值,就可以控制數(shù)據(jù)的發(fā)送速率,取值越大,發(fā)送速率就越小。
傳統(tǒng)的基于滑動窗口的端到端擁塞控制方法大都采用AIMD算法,本文對時間變量進(jìn)行控制,采用乘性增加減性減少(MIRD)算法。算法思想是當(dāng)發(fā)送速率不斷增加時,使其速率的增量不斷減小。所以總體上發(fā)送速率仍然是增加的,但是會增加的越來越慢,這樣可以更公平地利用網(wǎng)絡(luò)帶寬。算法為:
t為超時間隔,α(t)為每次減少的時間值,二者單位為ms,α(t)是基于接收端的帶寬估計,表達(dá)式為
若接收到ACK包且控制計時到時,則t=t-α(t),t值最小為0;
若接收到NCK包,則t=(1+β)×t,本文中β=0.5。
式(1)中:x是包發(fā)送速率;L是基于接收端的帶寬估計值;S是分區(qū)數(shù)據(jù)中待發(fā)送的數(shù)據(jù)包長度;C(x)是一函數(shù),C(x)=x× S× 8,即把包發(fā)送速率單位轉(zhuǎn)換為bit/s;SYN是同步時間。按照式(1)計算,當(dāng)發(fā)送速率每提高10倍,α(t)也幾乎減少10倍。t的初值定為100 ms,當(dāng)數(shù)據(jù)剛開始傳輸時,數(shù)據(jù)發(fā)送速率很低,接收端帶寬被占用較少,即L-C的值較大,則α(t)就會較大,相應(yīng)的超時間隔就會變小,從而使發(fā)送速率增加。當(dāng)數(shù)據(jù)發(fā)送速率較高時,L與C的值幾乎相等,此時α(t)的值就接近于0,使得發(fā)送速率幾乎不再增加,即對網(wǎng)絡(luò)繁忙程度自動適應(yīng),從而實(shí)現(xiàn)帶寬利用的公平性和穩(wěn)定性。
針對該協(xié)議,實(shí)驗(yàn)平臺采用Linux操作系統(tǒng)(Fedora 10、Fedora 14),通過對比試驗(yàn),把該協(xié)議與傳統(tǒng)的TCP、UDP協(xié)議在總體效率、丟包率、傳輸?shù)攘繑?shù)據(jù)所用時間等方面進(jìn)行性能分析和研究,實(shí)驗(yàn)證明,該協(xié)議的效率和可靠性比傳統(tǒng)的UDP協(xié)議有了明顯的提高。
發(fā)送文件為本地計算機(jī)的機(jī)場噪聲錄音文件,大小為7 909 kb,利用本算法、UDP、TCP在總體接收數(shù)據(jù)量、所耗時間方面各測試30多次,結(jié)果如圖6和7所示。
圖6中,圓點(diǎn)曲線是使用TCP協(xié)議接收的數(shù)據(jù)量7 909 kb,與發(fā)送數(shù)據(jù)量一致,沒有丟包;下三角曲線是本文協(xié)議的接收效果,存在很多丟包的情況,總體上比UDP可靠性要高;上三角曲線是使用傳統(tǒng)的UDP協(xié)議接收的數(shù)據(jù)效果,基本每次收到數(shù)據(jù)量都是5 000 kb左右,缺乏可靠性。圖7中,圓點(diǎn)曲線是TCP協(xié)議完成接收數(shù)據(jù)所用時間,上三角是本文協(xié)議接收數(shù)據(jù)所用時間,方框曲線是UDP協(xié)議所用時間??梢钥闯鍪褂帽疚膮f(xié)議傳輸數(shù)據(jù)比傳統(tǒng)的UDP協(xié)議可靠性要高,比傳統(tǒng)的TCP協(xié)議速率要快。
本文針對傳統(tǒng)UDP協(xié)議傳輸不可靠的問題,提出一種基于UDP的可靠傳輸協(xié)議,并引入按分區(qū)確認(rèn)的確認(rèn)、重發(fā)機(jī)制,解決了UDT協(xié)議數(shù)據(jù)傳輸過程中可能出現(xiàn)誤判關(guān)閉請求而導(dǎo)致連接中斷的問題,保證了該協(xié)議的傳輸可靠性,提高了數(shù)據(jù)傳輸效率。程序設(shè)計是在Linux操作系統(tǒng)下采用多線程方式實(shí)現(xiàn)傳輸數(shù)據(jù)的分包與重組,并對各區(qū)的超時間隔采用乘性增加減性減少的自適應(yīng)擁塞控制策略,可以滿足較高的實(shí)時性要求,有效節(jié)約了網(wǎng)絡(luò)資源,并實(shí)現(xiàn)帶寬利用的公平性和穩(wěn)定性。
[1]DANILO VALEROS BERNARDO,DOAN B HOANG.End-to-End Security Methods for UDT Data Transmissions[C]//Eds:FGIT2010,LNCS 6485:383-393.
[2]GU YUNHONG,GROSSMAN R L.UDT:UDP-based data transfer for high-speed wide area networks[J].Computer Betworks:The International Journal of Computer and Telecommunications Networking,2007,51(7):1777-1799.
[3] Szakáll Tibor,Péter Dukán,Borislav Odad?ic.Realization of Reliable High Speed Data Transfer Over UDP with Continuous Storage[C]//Proc of the IEEE International Symposium on Computational Intelligence and Informatics,Budapest,Hungary,IEEE,2010,12:307-309.
[4] 王艷芳,戴 永.基于UDP的數(shù)據(jù)可靠傳輸技術(shù)研究與應(yīng)用[J].計算機(jī)工程與應(yīng)用,2010,46(3):105.
[5]JIGANG WANG,GUOCHANG GU,SHIBO XIE,et al.Reliable and Efficient Data Transfer ProtocolBased on UDP in Cluster System[C]//Proc of IMSCCS′06:Hangzhou,China,2006.
[6] 徐世波.新型可靠數(shù)據(jù)報傳輸協(xié)議[J].科技資訊,2011(19):8-11.
[7]JIANG,XIAOQIANG.Research of multimedia data transmission based on UDP[C]//Proc of ICMMT 2010,Chongqing,China,IEEE,2010:1291-1295.