行發(fā)送。
[0071]此外,在數(shù)據(jù)傳輸過(guò)程中會(huì)出現(xiàn)這一現(xiàn)象:數(shù)據(jù)接收端在接收到數(shù)據(jù)發(fā)送端發(fā)來(lái)的某一數(shù)據(jù)幀后,發(fā)送了一個(gè)應(yīng)答信息至數(shù)據(jù)發(fā)送端,但數(shù)據(jù)發(fā)送端在設(shè)定的時(shí)間內(nèi)卻沒(méi)有接收到所述應(yīng)答信息,從而使得數(shù)據(jù)發(fā)送端重新發(fā)送了所述數(shù)據(jù)幀,這樣就導(dǎo)致數(shù)據(jù)接收端接收到了兩個(gè)相同的數(shù)據(jù)幀。為了防止在數(shù)據(jù)組包處理過(guò)程中將相同的邏輯幀(數(shù)據(jù)幀轉(zhuǎn)換為的邏輯幀)進(jìn)行重復(fù)組包,本實(shí)施例對(duì)數(shù)據(jù)組包處理過(guò)程進(jìn)行了進(jìn)一步的細(xì)化,具體地,判斷當(dāng)前取出的邏輯幀與已組包的邏輯幀中的邏輯幀是否相同,若相同則不對(duì)當(dāng)前取出的邏輯幀進(jìn)行數(shù)據(jù)組包處理,若不相同則對(duì)當(dāng)前取出的邏輯幀進(jìn)行數(shù)據(jù)組包處理。此設(shè)計(jì)方案保證了在組包處理操作中對(duì)相同的邏輯幀僅作一次組包處理。
[0072]本實(shí)施例還提供一種數(shù)據(jù)傳輸系統(tǒng),其包括實(shí)施例2中的數(shù)據(jù)傳輸系統(tǒng)所包括的功能模塊和各功能模塊所具備的功能,此外還包括:所述數(shù)據(jù)發(fā)送端還包括第一判斷單元,所述第一判斷單元用于判斷獲得的邏輯幀的個(gè)數(shù)與所述發(fā)送線程的個(gè)數(shù),若獲得的邏輯幀的個(gè)數(shù)小于所述發(fā)送線程的個(gè)數(shù),則開啟個(gè)數(shù)與獲得的邏輯幀的個(gè)數(shù)相等的發(fā)送線程,否則開啟全部發(fā)送線程。
[0073]而且,在開啟全部發(fā)送線程后,若所述數(shù)據(jù)發(fā)送端接收到所述應(yīng)答信息,則空閑的發(fā)送線程從所述第一集合中再次選取一個(gè)邏輯幀轉(zhuǎn)化為數(shù)據(jù)幀并進(jìn)行發(fā)送,直至所述第一集合中所有的邏輯幀均被發(fā)送。
[0074]此外,所述數(shù)據(jù)接收端還包括第二判斷單元,所述第二判斷單元用于判斷取出的邏輯幀與已組包的邏輯幀中的邏輯幀是否相同,若相同則不對(duì)取出的邏輯幀進(jìn)行數(shù)據(jù)組包處理,若不相同則調(diào)用所述組包處理單元和所述第一解析單元。
[0075]實(shí)施例4
[0076]本實(shí)施例的數(shù)據(jù)傳輸方法包括實(shí)施例3,而且在本實(shí)施例中,邏輯幀中存儲(chǔ)有用于數(shù)據(jù)組包的數(shù)據(jù)包信息,所述數(shù)據(jù)包信息中的部分?jǐn)?shù)據(jù)信息(例如是否需要數(shù)據(jù)接收端返回應(yīng)答幀的信息、當(dāng)前幀是不是應(yīng)答幀的信息等)以可擴(kuò)展邏輯位的方式存儲(chǔ)。此設(shè)計(jì)方式壓縮了傳輸數(shù)據(jù)的報(bào)頭,減小了數(shù)據(jù)的總大小,間接加快了數(shù)據(jù)的傳輸速度。
[0077]上面具體介紹了數(shù)據(jù)處理方法的工作流程,下面具體介紹利用JAVA (面向?qū)ο蟮某绦蛟O(shè)計(jì)語(yǔ)言)開發(fā)語(yǔ)言實(shí)現(xiàn)的數(shù)據(jù)處理方法:
[0078]首先設(shè)定分片大小為4k,應(yīng)答重傳的時(shí)間為500ms。
[0079]如圖5所示的邏輯幀數(shù)據(jù)結(jié)構(gòu),命名為DataGramRaw,數(shù)據(jù)幀包括但并不僅限于以下部分:1)數(shù)據(jù)包數(shù)據(jù)分片data,2) data長(zhǎng)度datalength,3)數(shù)據(jù)包中哪個(gè)位置Order,4)是哪個(gè)數(shù)據(jù)包的邏輯幀Token,5)可擴(kuò)展邏輯位屬性extBM。其中可擴(kuò)展邏輯位屬性extBM共有64位可用,本例子僅用了 3位分別為:需不需要應(yīng)答幀NEED_ACK、是不是應(yīng)答幀ACK_PACKET以及是不是最后一幀END_PACKET。
[0080]用于拆包組包的邏輯幀集合,設(shè)計(jì)成TreeSet結(jié)構(gòu),命名為DatagramRawSet,其中TreeSet為一個(gè)有序集合,TreeSet中的元素將按照升序排列,缺省是按照自然排序進(jìn)行排列。
[0081 ] 待發(fā)送數(shù)據(jù)包命名為DataGram,包括:
[0082]l)Data數(shù)據(jù)頭,保存了 Data的長(zhǎng)度等信息DataHeader。
[0083]2)真正要傳輸?shù)臄?shù)據(jù)即待發(fā)送數(shù)據(jù)Data。
[0084]3) 一個(gè)數(shù)據(jù)幀集合的 InputStream,命名為 RawDatasetReadStream。RawDatasetReadStream的操作,對(duì)應(yīng)著數(shù)據(jù)接收端的邏輯幀集合。從RawDatasetReadStream 中取數(shù)據(jù)的流程是:a)從 DatagramRawSet 中取出 DataGramRaw,b)將DataGramRaw中的數(shù)據(jù)包數(shù)據(jù)分片寫入到DataGram中的Data中,c)循環(huán)運(yùn)行步驟a和b,直到數(shù)據(jù)取完為止。
[0085]4) 一個(gè)數(shù)據(jù)幀集合的 OutputStream,命名為 RawDatasetWriteStream。RawDatasetffriteStream的操作,對(duì)應(yīng)著數(shù)據(jù)發(fā)送端的邏輯幀集合。向RawDatasetWriteStream中寫數(shù)據(jù)的流程是:a)新建DataGramRaw數(shù)據(jù)對(duì)象,從DataGram的要發(fā)送的數(shù)據(jù)中取得分片大小的數(shù)據(jù)放到DataGramRaw數(shù)據(jù)中,b)向DatagramRawSet中放入DataGramRaw,c)循環(huán)運(yùn)行步驟a和b,直到數(shù)據(jù)取完為止。
[0086]應(yīng)答幀數(shù)據(jù)命名為AckRaw,一種特殊的邏輯幀數(shù)據(jù)。應(yīng)答幀數(shù)據(jù)僅包括:a)應(yīng)答哪個(gè)數(shù)據(jù)包的邏輯幀Token,b)應(yīng)答數(shù)據(jù)包中哪個(gè)位置Order,c)是不是應(yīng)答幀,此外應(yīng)答幀數(shù)據(jù)中的其他數(shù)據(jù)均為空。
[0087]數(shù)據(jù)接收端用于接收邏輯幀的緩存,設(shè)計(jì)成隊(duì)列,命名為PacketQueue;數(shù)據(jù)發(fā)送端保存應(yīng)答幀的集合,設(shè)計(jì)成TreeSet。命名為AckSet。
[0088]上面利用JAVA開發(fā)語(yǔ)言對(duì)幾種數(shù)據(jù)結(jié)構(gòu)進(jìn)行了定義,下面具體介紹利用JAVA開發(fā)語(yǔ)言實(shí)現(xiàn)的數(shù)據(jù)發(fā)送流程和數(shù)據(jù)接收流程:
[0089]數(shù)據(jù)發(fā)送流程:
[0090]I)將待發(fā)送的數(shù)據(jù)擴(kuò)展成DataGram ;
[0091]2)如果DataGram數(shù)據(jù)長(zhǎng)度小于或等于分片長(zhǎng)度,則此DataGram數(shù)據(jù)為單幀數(shù)據(jù),直接將此DataGram轉(zhuǎn)換為數(shù)據(jù)幀發(fā)送;如果DataGram數(shù)據(jù)長(zhǎng)度大于分片長(zhǎng)度,則DataGram將自己的數(shù)據(jù)寫入到自己RawDatasetWriteStream中;
[0092]3)按照上述數(shù)據(jù)結(jié)構(gòu)的設(shè)計(jì),進(jìn)行RawDatasetWriteStream寫入的過(guò)程,這其實(shí)就是分片的過(guò)程,也是邏輯幀DataGramRaw和邏輯幀集合DatagramRawSet數(shù)據(jù)寫入的過(guò)程;
[0093]4)新建多發(fā)送線程,搶占式共享DatagramRawSet,將DataGramRaw轉(zhuǎn)換成數(shù)據(jù)幀發(fā)送;
[0094]5)每個(gè)發(fā)送線程發(fā)送完一個(gè)DataGramRaw后,在設(shè)定的應(yīng)答重傳時(shí)間內(nèi),檢查AckSet中有沒(méi)有剛剛發(fā)過(guò)的DataGramRaw返回的AckRaw(通過(guò)Token和Order可以判斷出AckRaw與DataGramRaw的對(duì)應(yīng)關(guān)系),如果收到AckRaw,則搶占式發(fā)送DatagramRawSet剩下的DataGramRaw ;如果沒(méi)有收到AckRaw,則重新發(fā)送已經(jīng)發(fā)過(guò)的DataGramRaw。如此反復(fù),一直到DatagramRawSet中沒(méi)有了 DataGramRaw,則關(guān)閉發(fā)送線程。
[0095]數(shù)據(jù)接收流程:
[0096]I)通過(guò)接收線程接收IP數(shù)據(jù)報(bào),將數(shù)據(jù)幀轉(zhuǎn)換為DataGramRaw,發(fā)送AckRaw至數(shù)據(jù)發(fā)送端;
[0097]2)直接根據(jù)DataGramRaw數(shù)據(jù)的大小判斷是不是單幀數(shù)據(jù),如果是則直接取出Data,如果不是則放入到PacketQueue中;
[0098]3)數(shù)據(jù)接收端有一個(gè)線程一直在監(jiān)聽PacketQueue,只要PacketQueue有DataGramRaw,就會(huì)取出來(lái)并將DataGramRaw數(shù)據(jù)寫入相應(yīng)的DatagramRawSet的中,(通過(guò)DataGramRaw里包含的DataGram信息,得知DataGramRaw屬于哪個(gè)DataGram及在DatagramRawSet中的位置),根據(jù)上文設(shè)計(jì)的數(shù)據(jù)結(jié)構(gòu),由于DatagramRawSet是TreeSet結(jié)構(gòu)(TreeSet結(jié)構(gòu)具有不會(huì)保存重復(fù)數(shù)據(jù)的特性),這樣如果收到重復(fù)的DataGramRaw,則不會(huì)保存;
[0099]4)循環(huán)地從 DatagramRawSet 中取 DataGramRaw 放入到 DataGram 中的 Data 中即從