一種快速處理數(shù)據(jù)粘包的方法
【技術(shù)領(lǐng)域】
[0001 ]本發(fā)明涉及通信領(lǐng)域,具體說是一種快速處理數(shù)據(jù)粘包的方法。
【背景技術(shù)】
[0002]TCP協(xié)議(Transmiss1n Control ProtocoI)作為Internet最基本的協(xié)議、Internet國際互聯(lián)網(wǎng)絡(luò)通信的基礎(chǔ),由網(wǎng)絡(luò)層的IP協(xié)議(Internet Protocol)和傳輸層的TCP協(xié)議組成。它定義了各種電子設(shè)備如何接入互聯(lián)網(wǎng),以及設(shè)備之間數(shù)據(jù)如何進行傳輸。
[0003]TCP協(xié)議提供了一種可靠的基于流數(shù)據(jù)的無邊界傳輸方式,并且配合滑動窗口的擁塞控制算法進行發(fā)送速率調(diào)整。因此在實際網(wǎng)絡(luò)環(huán)境下TCP協(xié)議的數(shù)據(jù)流在接收端將產(chǎn)生頭尾無法區(qū)分以及完整數(shù)據(jù)包斷裂的粘包情況發(fā)生,并且在例如視頻流這種數(shù)據(jù)長,數(shù)據(jù)量龐大,并且實時性要求高的情況下發(fā)生接收不及時,從而導(dǎo)致?lián)砣刂扑惴ǚe性減少滑動窗口大小,嚴(yán)重降低發(fā)送速率。
[0004]現(xiàn)有的對于粘包拆分的方法局限于在單進程默認堆棧內(nèi)存區(qū)開辟空間進行數(shù)據(jù)報頭解析和緩存達到拆分目的,無法充分的利用如今越來越龐大的內(nèi)存尋址空間并且使用更為優(yōu)秀的數(shù)據(jù)結(jié)構(gòu)。而且現(xiàn)有的拆分粘包過程中對于數(shù)據(jù)緩存保護機制更是消耗大量時間在于進行程序內(nèi)核態(tài)和用戶態(tài)掛起和喚醒的CPU時間片轉(zhuǎn)換,從而導(dǎo)致大量可用內(nèi)存的閑置和接收速率的限制。
【發(fā)明內(nèi)容】
[0005]本發(fā)明的目的在于提供一種快速處理數(shù)據(jù)粘包的方法。
[0006]本發(fā)明的技術(shù)方案在于:一種快速處理數(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)識位和一個緩存空間。
[0007]優(yōu)選的,該讀寫鏈表包含讀開始標(biāo)識符、讀結(jié)束標(biāo)識符、寫開始標(biāo)識符、寫結(jié)束標(biāo)識符以及結(jié)構(gòu)數(shù)組。
[0008]優(yōu)選的,接收線程從網(wǎng)絡(luò)套接字讀取數(shù)據(jù),并且讀取該讀寫鏈表中當(dāng)前可讀數(shù)據(jù)塊,將數(shù)據(jù)寫入到當(dāng)前數(shù)據(jù)塊,如果當(dāng)前鏈表數(shù)據(jù)塊都無法讀取則等待可讀事件的觸發(fā)。
[0009]優(yōu)選的,對該讀寫鏈表的數(shù)據(jù)保護以及同步,使用用戶態(tài)原子鎖方式,防止讀寫鏈表頻繁的陷入用戶態(tài)和內(nèi)核態(tài)轉(zhuǎn)換,耗費大量的CHJ時間片。
[0010]優(yōu)選的,當(dāng)數(shù)據(jù)處理服務(wù)線程接收到數(shù)據(jù)塊,如果是第一次接收到數(shù)據(jù)則需要判斷第一次數(shù)據(jù)塊長度是否滿足最小報文頭,否則原子鎖將不會交換數(shù)據(jù)塊進行鏈表的推進,而是保留當(dāng)前鏈表節(jié)點準(zhǔn)備接收下一次數(shù)據(jù)。
[0011]優(yōu)選的,如果當(dāng)前數(shù)據(jù)塊數(shù)據(jù)長度大于或者等于最小報文頭,程序?qū)㈤_始拆包過程。
[0012]優(yōu)選的,通過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ù),將兩次數(shù)據(jù)合并再拷貝回當(dāng)前鏈表節(jié)點數(shù)據(jù)塊,重新回到鏈表讀寫循環(huán)。
[0013]本發(fā)明能夠保證在準(zhǔn)確的拆分數(shù)據(jù)粘包的前提下,通過文件映射內(nèi)存創(chuàng)建數(shù)據(jù)結(jié)構(gòu)讀寫單鏈表的方式以及原子層面的讀寫保護,極大的提高內(nèi)存利用率以及讀寫速率,解決了現(xiàn)有粘包處理算法上在大數(shù)據(jù)流實時性方面無法很好的利用計算機硬件資源以及速率提升瓶頸上的問題。
【附圖說明】
[0014]圖1為本發(fā)明單循環(huán)的讀寫鏈表數(shù)據(jù)結(jié)構(gòu)示意圖。
[0015]圖2為本發(fā)明block數(shù)據(jù)塊示意圖。
[0016]圖3為本發(fā)明成功處理一數(shù)據(jù)塊獲得完整tcp數(shù)據(jù)包。
[0017]圖4為本發(fā)明數(shù)據(jù)處理流程圖。
【具體實施方式】
[0018]為讓本發(fā)明的上述特征和優(yōu)點能更明顯易懂,下文特舉實施例,并配合附圖,作詳細說明如下,但本發(fā)明并不限于此。
[0019]如圖1所示,本發(fā)明提供一種快速處理數(shù)據(jù)粘包的方法,包括以下步驟:將block數(shù)據(jù)塊通過數(shù)組形式組合成一單循環(huán)的讀寫鏈表數(shù)據(jù)結(jié)構(gòu),并且數(shù)據(jù)處理服務(wù)線程通過內(nèi)存文件映射技術(shù)命名該讀寫鏈表到進程地址空間,寫線程通過名字查找到進程地址空間中該讀寫鏈表內(nèi)存,程序開始等待數(shù)據(jù);其中,如圖2所示,該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)識位和一個所需類型的緩存空間。Tcp數(shù)據(jù)包,其中報文頭包含標(biāo)識當(dāng)前數(shù)據(jù)包完整數(shù)據(jù)長度的信息以及報文頭其他信息;定義最小報文頭長度用于檢測防止接收數(shù)據(jù)不足于一個最小報文頭從而無法提取報文數(shù)據(jù)長度;鏈表中的每個節(jié)點將用于接收原始數(shù)據(jù)以及對數(shù)據(jù)進行解析拼接。
[0020]該讀寫鏈表數(shù)據(jù)結(jié)構(gòu)包含讀開始標(biāo)識符、讀結(jié)束標(biāo)識符、寫開始標(biāo)識符、寫結(jié)束標(biāo)識符以及一定長度的結(jié)構(gòu)數(shù)組,此鏈表總體即為緩存結(jié)構(gòu),鏈表中的每個節(jié)點將用于接收原始數(shù)據(jù)以及對數(shù)據(jù)進行解析拼接。
[0021]接收線程從網(wǎng)絡(luò)套接字讀取數(shù)據(jù),并且讀取該讀寫鏈表數(shù)據(jù)結(jié)構(gòu)中當(dāng)前可讀數(shù)據(jù)塊,將數(shù)據(jù)寫入到當(dāng)前數(shù)據(jù)塊,如果當(dāng)前鏈表數(shù)據(jù)塊都無法讀取則等待可讀事件的觸發(fā)。
[0022]對該讀寫鏈表數(shù)據(jù)結(jié)構(gòu)的數(shù)據(jù)保護以及同步,使用用戶態(tài)原子鎖方式,防止讀寫鏈表頻繁的陷入用戶態(tài)和內(nèi)核態(tài)轉(zhuǎn)換,耗費大量的CHJ時間片。
[0023]當(dāng)數(shù)據(jù)處理服務(wù)線程接收到數(shù)據(jù)塊,如果是第一次接收到數(shù)據(jù)則需要判斷第一次數(shù)據(jù)塊長度是否滿足之前定義的最小報文頭,否則原子鎖將不會交換數(shù)據(jù)塊進行鏈表的推進,而是保留當(dāng)前鏈表節(jié)點準(zhǔn)備接收下一次數(shù)據(jù)。
[0024]如果當(dāng)前數(shù)據(jù)塊數(shù)據(jù)長度大