于或者等于最小報文頭,程序?qū)㈤_始拆包過程;具體的:通過TCP數(shù)據(jù)包頭的自定義標(biāo)識,獲取數(shù)據(jù)包長度,然后減去當(dāng)前數(shù)據(jù)塊長度以及自定義最小報文頭長度求出數(shù)據(jù)包剩余長度;
如果數(shù)據(jù)包剩余長度結(jié)果小于O,則說明當(dāng)前數(shù)據(jù)塊包含一包完整的TCP數(shù)據(jù)包,接下來,保存當(dāng)前數(shù)據(jù)包長度,當(dāng)前數(shù)據(jù)塊長度減去完整數(shù)據(jù)包長度,保存數(shù)據(jù)塊剩余長度,重置鏈表當(dāng)前節(jié)點,將剩余數(shù)據(jù)完整拷貝進去,重新回到鏈表讀寫循環(huán),并且當(dāng)前塊不進行推進;
如果數(shù)據(jù)包剩余長度結(jié)果大于O,則說明當(dāng)前數(shù)據(jù)塊中的數(shù)據(jù)不足于一個完整的數(shù)據(jù)包,接下來,將當(dāng)前數(shù)據(jù)拷貝進臨時區(qū),推進一步鏈表移動到下一塊數(shù)據(jù),如圖3所示,將兩次數(shù)據(jù)合并再拷貝回當(dāng)前鏈表節(jié)點數(shù)據(jù)塊,重新回到鏈表讀寫循環(huán)。
[0025]如圖4所示,本發(fā)明的快速處理數(shù)據(jù)粘包的方法具體如下:
使用唯一標(biāo)識符命名一段內(nèi)存空間;
開辟數(shù)據(jù)服務(wù)處理線程將上述單循環(huán)的讀寫鏈表使用內(nèi)存文件映射技術(shù),將鏈表空間映射進程序預(yù)留的內(nèi)存空間,并且使用之前唯一標(biāo)識符命名這塊數(shù)據(jù)結(jié)構(gòu)空間;
以單循環(huán)鏈表方式初始化鏈表以及鏈表中節(jié)點結(jié)構(gòu),數(shù)據(jù)處理線程開始循環(huán)接收可讀取數(shù)據(jù)塊;
開辟TCP數(shù)據(jù)接收線程,使用內(nèi)存文件映射技術(shù)在程序內(nèi)存空間中查找到由服務(wù)線程開辟并且命名的內(nèi)存塊名字,并且將其映射進數(shù)據(jù)接收線程空間;
接收線程從網(wǎng)絡(luò)套接字讀取數(shù)據(jù),并且讀取循環(huán)單鏈表中當(dāng)前可讀數(shù)據(jù)塊,將數(shù)據(jù)寫入到當(dāng)前數(shù)據(jù)塊,如果當(dāng)前鏈表數(shù)據(jù)塊都無法讀取則等待可讀事件的觸發(fā);
對單鏈表讀寫數(shù)據(jù)塊的數(shù)據(jù)保護以及同步,使用用戶態(tài)原子鎖方式,防止讀寫鏈表頻繁的陷入用戶態(tài)和內(nèi)核態(tài)轉(zhuǎn)換,耗費大量的(PU時間片;
當(dāng)數(shù)據(jù)處理服務(wù)線程接收到數(shù)據(jù)塊,如果是第一次接收到數(shù)據(jù)則需要判斷第一次數(shù)據(jù)塊長度是否滿足之前定義的最小報文頭,否則原子鎖將不會交換數(shù)據(jù)塊進行鏈表的推進,而是保留當(dāng)前鏈表節(jié)點準(zhǔn)備接收下一次數(shù)據(jù);
如果當(dāng)前數(shù)據(jù)塊數(shù)據(jù)長度大于或者等于最小報文頭,程序?qū)㈤_始拆包過程:首先通過TCP數(shù)據(jù)包頭的自定義標(biāo)識,獲取數(shù)據(jù)包長度,然后減去當(dāng)前數(shù)據(jù)塊長度以及自定義最小報文頭長度求出數(shù)據(jù)包剩余長度;
如果數(shù)據(jù)包剩余長度結(jié)果小于0,則說明當(dāng)前數(shù)據(jù)塊包含一包完整的TCP數(shù)據(jù)包。進一步的,保存當(dāng)前數(shù)據(jù)包長度,當(dāng)前數(shù)據(jù)塊長度減去完整數(shù)據(jù)包長度,保存數(shù)據(jù)塊剩余長度。重置鏈表當(dāng)前節(jié)點,將剩余數(shù)據(jù)完整拷貝進去。重新回到鏈表讀寫循環(huán),并且當(dāng)前塊不進行推進;
如果數(shù)據(jù)包剩余長度結(jié)果大于O說明當(dāng)前數(shù)據(jù)塊中的數(shù)據(jù)不足于一個完整的數(shù)據(jù)包,進一步的,將當(dāng)前數(shù)據(jù)拷貝進臨時區(qū),推進一步鏈表移動到下一塊數(shù)據(jù),將兩次數(shù)據(jù)合并再拷貝回當(dāng)前鏈表節(jié)點數(shù)據(jù)塊,重新回到鏈表讀寫循環(huán);
當(dāng)前數(shù)據(jù)塊如果有剩余數(shù)據(jù),鏈表將不進行推進,重復(fù)進行當(dāng)前數(shù)據(jù)塊處理,將當(dāng)前數(shù)據(jù)塊和后一數(shù)據(jù)塊數(shù)據(jù)進行拼接合并,并且設(shè)置當(dāng)前塊可寫推進鏈表轉(zhuǎn)動。
[0026]以上所述僅為本發(fā)明的較佳實施例,凡依本發(fā)明申請專利范圍所做的均等變化與修飾,皆應(yīng)屬本發(fā)明的涵蓋范圍。
【主權(quán)項】
1.一種快速處理數(shù)據(jù)粘包的方法,其特征在于,包括以下步驟:將block數(shù)據(jù)塊通過數(shù)組形式組合成一單循環(huán)的讀寫鏈表,并且數(shù)據(jù)處理服務(wù)線程通過內(nèi)存文件映射技術(shù)命名該讀寫鏈表到進程地址空間,寫線程通過名字查找到進程地址空間中該讀寫鏈表內(nèi)存,程序開始等待數(shù)據(jù);其中,該block數(shù)據(jù)塊包括當(dāng)前節(jié)點的前一個節(jié)點序數(shù)、后一個節(jié)點序數(shù)、節(jié)點讀完標(biāo)識、節(jié)點寫完標(biāo)識、節(jié)點數(shù)據(jù)長度、預(yù)接收的tcp完整數(shù)據(jù)包長度、不足一個完整tcp數(shù)據(jù)包時剩下還沒接收的長度、當(dāng)前已經(jīng)接收的完整tcp數(shù)據(jù)包長度、預(yù)留標(biāo)識位和一個緩存空間。2.根據(jù)權(quán)利要求1所述的一種快速處理數(shù)據(jù)粘包的方法,其特征在于:該讀寫鏈表包含讀開始標(biāo)識符、讀結(jié)束標(biāo)識符、寫開始標(biāo)識符、寫結(jié)束標(biāo)識符以及結(jié)構(gòu)數(shù)組。3.根據(jù)權(quán)利要求1所述的一種快速處理數(shù)據(jù)粘包的方法,其特征在于:接收線程從網(wǎng)絡(luò)套接字讀取數(shù)據(jù),并且讀取該讀寫鏈表中當(dāng)前可讀數(shù)據(jù)塊,將數(shù)據(jù)寫入到當(dāng)前數(shù)據(jù)塊,如果當(dāng)前鏈表數(shù)據(jù)塊都無法讀取則等待可讀事件的觸發(fā)。4.根據(jù)權(quán)利要求1所述的一種快速處理數(shù)據(jù)粘包的方法,其特征在于:對該讀寫鏈表的數(shù)據(jù)保護以及同步,使用用戶態(tài)原子鎖方式,防止讀寫鏈表頻繁的陷入用戶態(tài)和內(nèi)核態(tài)轉(zhuǎn)換,耗費大量的(PU時間片。5.根據(jù)權(quán)利要求4所述的一種快速處理數(shù)據(jù)粘包的方法,其特征在于:當(dāng)數(shù)據(jù)處理服務(wù)線程接收到數(shù)據(jù)塊,如果是第一次接收到數(shù)據(jù)則需要判斷第一次數(shù)據(jù)塊長度是否滿足最小報文頭,否則原子鎖將不會交換數(shù)據(jù)塊進行鏈表的推進,而是保留當(dāng)前鏈表節(jié)點準(zhǔn)備接收下一次數(shù)據(jù)。6.根據(jù)權(quán)利要求5所述的一種快速處理數(shù)據(jù)粘包的方法,其特征在于:如果當(dāng)前數(shù)據(jù)塊數(shù)據(jù)長度大于或者等于最小報文頭,程序?qū)㈤_始拆包過程。7.根據(jù)權(quán)利要求6所述的一種快速處理數(shù)據(jù)粘包的方法,其特征在于:通過TCP數(shù)據(jù)包頭的自定義標(biāo)識,獲取數(shù)據(jù)包長度,然后減去當(dāng)前數(shù)據(jù)塊長度以及最小報文頭長度求出數(shù)據(jù)包剩余長度; 如果數(shù)據(jù)包剩余長度結(jié)果小于0,則說明當(dāng)前數(shù)據(jù)塊包含一包完整的TCP數(shù)據(jù)包,接下來,保存當(dāng)前數(shù)據(jù)包長度,當(dāng)前數(shù)據(jù)塊長度減去完整數(shù)據(jù)包長度,保存數(shù)據(jù)塊剩余長度,重置鏈表當(dāng)前節(jié)點,將剩余數(shù)據(jù)完整拷貝進去,重新回到鏈表讀寫循環(huán),并且當(dāng)前塊不進行推進; 如果數(shù)據(jù)包剩余長度結(jié)果大于O,則說明當(dāng)前數(shù)據(jù)塊中的數(shù)據(jù)不足于一個完整的數(shù)據(jù)包,接下來,將當(dāng)前數(shù)據(jù)拷貝進臨時區(qū),推進一步鏈表移動到下一塊數(shù)據(jù),將兩次數(shù)據(jù)合并再拷貝回當(dāng)前鏈表節(jié)點數(shù)據(jù)塊,重新回到鏈表讀寫循環(huán)。
【專利摘要】本發(fā)明公開一種快速處理數(shù)據(jù)粘包的方法,其特征在于,包括以下步驟:將block數(shù)據(jù)塊通過數(shù)組形式組合成一單循環(huán)的讀寫鏈表,并且數(shù)據(jù)處理服務(wù)線程通過內(nèi)存文件映射技術(shù)命名該讀寫鏈表到進程地址空間,寫線程通過名字查找到進程地址空間中該讀寫鏈表內(nèi)存,程序開始等待數(shù)據(jù)。本發(fā)明可以充分使用程序內(nèi)存閑置區(qū)和避免不需要的內(nèi)核和用戶態(tài)轉(zhuǎn)換產(chǎn)生的大量CPU時間片以大幅度提高接收速度。
【IPC分類】G06F12/02, H04L29/06, G06F12/126
【公開號】CN105630693
【申請?zhí)枴緾N201510973828
【發(fā)明人】楊智勤
【申請人】羅普特(廈門)科技集團有限公司
【公開日】2016年6月1日
【申請日】2015年12月23日