www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > 芯聞號 > 充電吧
[導(dǎo)讀]本報文格式不能處理粘包問題,因為處理粘包問題的成本太高,會極大的降低服務(wù)端的處理效率以及增加內(nèi)存消耗,如果傳輸速度很高,建議使用UDP,UDP傳輸速度快,并且應(yīng)用層做響應(yīng),增加重傳機(jī)制可以有效的保證數(shù)

本報文格式不能處理粘包問題,因為處理粘包問題的成本太高,會極大的降低服務(wù)端的處理效率以及增加內(nèi)存消耗,如果傳輸速度很高,建議使用UDP,UDP傳輸速度快,并且應(yīng)用層做響應(yīng),增加重傳機(jī)制可以有效的保證數(shù)據(jù)的可靠性,目前我做的RTU升級等功能都是使用UDP完成,服務(wù)器端開銷小,并且不會粘包。

通訊建議:不要做什么握手機(jī)制,直接發(fā)送數(shù)據(jù),服務(wù)器收到了就響應(yīng),收到響應(yīng)后就結(jié)束通訊,握手增加耗電又增加流量消耗,并且在GPRS通訊上是非常浪費資源的,本來網(wǎng)絡(luò)就不可靠,直接發(fā)送數(shù)據(jù),服務(wù)器收到了就響應(yīng)通訊就結(jié)束了,如果弄成握手方式,就是發(fā)送請求,握手成功,發(fā)送數(shù)據(jù),等待響應(yīng),結(jié)束通訊,就增加了1個來回,特別是之前用過MQTT多了幾個來回,太浪費通訊資源了。

?

使用HEX格式的通訊協(xié)議非常高效,不管是發(fā)送打包還是接收拆包,1個結(jié)構(gòu)體就能搞定,無需一個字節(jié)一個字節(jié)解析,如果用字符串json方式,使用單片機(jī)作為客戶端就很為難了,一般內(nèi)存不會很多,并且解析json需要的內(nèi)存會非常多。

?

報文全部使用小端模式,便于C語言處理。

注:由于我之前做了一個支持10W個設(shè)備的數(shù)據(jù)解析軟件,其實占用的內(nèi)存非常少,并且對CPU消耗很低,我們使用了一個很低端的服務(wù)器就能做到每秒1K條以上的數(shù)據(jù)處理,并且每條數(shù)據(jù)都在1秒內(nèi)得到響應(yīng),剛開始的時候還好,后面因為設(shè)備越來越多,導(dǎo)致服務(wù)器搜索設(shè)備變得很漫長(我的設(shè)備數(shù)據(jù)都是放到內(nèi)存中,使用了一個指針數(shù)組進(jìn)行管理),由于設(shè)備會動態(tài)的增加,不能對序列號進(jìn)行排序,因此查找設(shè)備的索引時間將會不可控,解析一條數(shù)據(jù)非常快,存儲是異步的,有1W條的緩存,但是唯獨查找設(shè)備這個看似簡單的過程變得非常復(fù)雜,由于之前的協(xié)議我沒有增加索引,我只能對設(shè)備進(jìn)行分組,我建了1W個指針數(shù)組,根據(jù)設(shè)備尾號后4位進(jìn)行分組,這樣會增加幾十兆的內(nèi)存消耗,但是查找卻變得非常迅速。通過這個事情之后,我決定在協(xié)議中直接增加索引,服務(wù)端收到索引后直接取出當(dāng)前設(shè)備的配置與SN進(jìn)行對比,如果相同就直接解析存儲數(shù)據(jù),如果不相同就進(jìn)行查找即可,沒有就進(jìn)行新建,最后建議將設(shè)備分組與協(xié)議中增加索引進(jìn)行整合,集各自的優(yōu)點,可以最大限度的提高數(shù)據(jù)的解析能力,當(dāng)每個設(shè)備都通訊一次之后,解析任何一個設(shè)備上傳的數(shù)據(jù)的時間都是一樣的,并且是最小的。

禁忌:解析數(shù)據(jù)是千萬不要把配置什么的都放到數(shù)據(jù)庫,數(shù)據(jù)庫相比內(nèi)存實在是慢太多了,而且時間不可控,數(shù)據(jù)庫本身就不是非??煽浚ㄗh將數(shù)據(jù)庫操作做異步處理,中間用FIFO通訊,這樣數(shù)據(jù)解析線程可以以最高效的方式運(yùn)行(一個線程輕松解析成千上萬條數(shù)據(jù),通過增加一個線程可以提高1倍的處理能力)。

?

存儲設(shè)備實時信息方式

我存儲設(shè)備相關(guān)信息的方式是,每個設(shè)備有一個自己的統(tǒng)一的結(jié)構(gòu)體,比如我最大支持10000個設(shè)備,我就會先申請1個指針數(shù)組,大小為10000,占用40000B,也就不到40KB內(nèi)存。然后每添加一個設(shè)備,就給這個指針申請一個內(nèi)存,存放設(shè)備的配置信息,同時會使用托管的線程池異步向數(shù)據(jù)庫中增加一個設(shè)備。

但是如果有幾千上萬個設(shè)備的時候,尋找這個設(shè)備的配置就變得很吃力了(相對來說,內(nèi)存中遍歷都會比數(shù)據(jù)庫快),這個時候我就會對設(shè)備進(jìn)行分組,比如分100組,最好的情況下每個組有100個設(shè)備,但是不排除有一種可能,一個組中有超過100個設(shè)備的呀,我就要做一個二維指針數(shù)組,分100個數(shù)組,每個數(shù)組中1000個設(shè)備指針,這樣內(nèi)存占用就會是100*1000*4,也還好400K,但是如果一個組超過了1000個就不好辦了,同樣如果是10W個設(shè)備的時候,這個分組就很吃內(nèi)存了,我的做法是每個分組用個變量進(jìn)行記錄,每個組給50個設(shè)備指針,當(dāng)這個組超過50個之后,我重新對這個指針進(jìn)行申請內(nèi)存,大小為上一次的+50個,然后把之前的數(shù)據(jù)拷貝過來,釋放掉之前的數(shù)據(jù),這樣就可以動態(tài)的進(jìn)行分組控制,實現(xiàn)效率的提升與內(nèi)存的最小消耗。


使用分組提高查找的一個例子

	//查找指定SN的設(shè)備索引
	//返回索引;-1:沒有找到
	//2017-12-27?:?會使用分組進(jìn)行快速查找索引,只能在單線程中使用,不要跨線程搜索
	int?FindSN(char?pSN[16])
	{
		DWORD?Hash;
		BYTE?temp[3];
		int?GroupIndex;
		ONE_DEVICE_DATA_TYPE?*pDeviceData;

		if?(pSN?==?nullptr)?return?-1;
		pSN[15]?=?0;
		if(strlen(pSN)?!=?15)?return-1;
		//檢查最后3位是否為000-999
		temp[0]?=?pSN[12]?-?'0';	//字符轉(zhuǎn)換為數(shù)字
		temp[1]?=?pSN[13]?-?'0';	//字符轉(zhuǎn)換為數(shù)字
		temp[2]?=?pSN[14]?-?'0';	//字符轉(zhuǎn)換為數(shù)字
		if?(temp[0]?>?9?||?temp[1]?>?9?||?temp[2]?>?9)
		{
			return?-1;
		}
		GroupIndex?=?temp[0]?*?100?+?temp[1]?*?10?+?temp[2];//計算當(dāng)前設(shè)備的分組索引
		if?(GroupIndex?>=?DEVICE_GROUP_CNT)?return?-1;		//分組索引無效
		Hash?=?USER_LIB.BKDRHash(pSN);		//計算哈希結(jié)果
		//在指定的分組內(nèi)去搜索當(dāng)前設(shè)備
		for?(DWORD?i?=?0;?i?<?this->GroupDeviceCnt[GroupIndex];?i++)
		{
			pDeviceData?=?(ONE_DEVICE_DATA_TYPE?*)this->pDeviceDataGroupPointerBuff[GroupIndex][i];	//遍歷當(dāng)前分組
			if?(pDeviceData->Config.Hash?==?Hash)		//先判斷哈希結(jié)果是否正確
			{
				if?(strcmp(pSN,?pDeviceData->Config.SN)?==?0)?return?pDeviceData->Index;			//找到了,返回索引
			}
		}

		return?-1;
	}


添加設(shè)備的例子,先添加到全局的配置數(shù)組中,然后再把指針存儲一份到分組索引中

//添加一個設(shè)備到配置緩沖區(qū),返回索引,DeviceCnt?>=?DEVICE_MAX_CNT)							//設(shè)備數(shù)量超出范圍
		{
			*pError?=?"設(shè)備配置超出范圍了";
			return?-1;	
		}
		pConfig->SN[15]?=?0;
		if?(strlen(pConfig->SN)?!=?15)
		{
			*pError?=?"設(shè)備序列號必須為15位";
			return?-1;
		}
		//檢查最后3位是否為000-999
		temp[0]?=?pConfig->SN[12]?-?'0';	//字符轉(zhuǎn)換為數(shù)字
		temp[1]?=?pConfig->SN[13]?-?'0';	//字符轉(zhuǎn)換為數(shù)字
		temp[2]?=?pConfig->SN[14]?-?'0';	//字符轉(zhuǎn)換為數(shù)字
		if?(temp[0]?>?9?||?temp[1]?>?9?||?temp[2]?>?9)
		{
			return?-1;
		}
		GroupIndex?=?temp[0]?*?100?+?temp[1]?*?10?+?temp[2];			//計算當(dāng)前設(shè)備的分組索引
		if?(GroupIndex?>=?DEVICE_GROUP_CNT)
		{
			*pError?=?"無效的分組索引";
			return?-1;
		}

		if?(FindSN(pConfig->SN)?>=?0)									//尋找指定地址的設(shè)備是否存在
		{
			*pError?=?"當(dāng)前設(shè)備地址已經(jīng)存在";
			return?-1;
		}
		p?=?new?ONE_DEVICE_DATA_TYPE;									//申請內(nèi)存
		memset(p,?0,?sizeof(ONE_DEVICE_DATA_TYPE));						//清控配置區(qū)域
		memcpy(&p->Config,?pConfig,?sizeof(DEVICE_CONFIG_TYPE));		//拷貝數(shù)據(jù)
		p->Config.Hash?=?USER_LIB.BKDRHash(p->Config.SN);				//生成SN的哈希值
		p->DbStatus.ReadHistCongifCnt?=?p->DbStatus.ReadHistStatusCnt?=?p->DbStatus.WriteHistCongifCnt?=?-1;		//將歷史記錄條數(shù)置為-1無效值

		p->Index?=?this->DeviceCnt;										//記錄當(dāng)前設(shè)備的索引
		//將當(dāng)前設(shè)備編號進(jìn)行分組
		if?(this->AddDeviceToGroup(GroupIndex,?(DWORD)p)?==?false)
		{
			*pError?=?"添加設(shè)備到分組失敗!";
			return?-1;
		}
		U32_DeviceDataPointerBuff[this->DeviceCnt]?=?(DWORD)p;			//存放指針
		pDeviceDataPointerBuff[this->DeviceCnt++]?=?p;					//存儲指針
		

		return?(this->DeviceCnt?-?1);									//返回當(dāng)前的索引
	}


添加設(shè)備到分組中,如果分組滿了將會進(jìn)行擴(kuò)充

//添加一個設(shè)備到指定分組中,如果分組慢,將會申請擴(kuò)容
	//不會進(jìn)行編號等檢查,只能在AddDevice中被調(diào)用
	bool?AddDeviceToGroup(int?GroupIndex,?DWORD?DeviceDataPointer)
	{
		if?(GroupIndex?<?0?||?GroupIndex?>=?DEVICE_GROUP_CNT)?return?false;
		if?(this->GroupSize[GroupIndex]?>=?DEVICE_MAX_CNT)?return?false;		//分組大小不能超過總設(shè)備限制
		if?(this->GroupDeviceCnt[GroupIndex]?>?this->GroupSize[GroupIndex])?return?false;
		if?(this->GroupDeviceCnt[GroupIndex]?==?this->GroupSize[GroupIndex])	//需要擴(kuò)容
		{
			if?(DeviceGroupExpansion(GroupIndex)?==?false)						//擴(kuò)容失敗,返回
			{
				SYS_LOG.Write(__FILE__?+?__LINE__?+?"分組擴(kuò)容失敗,分組索引"?+?GroupIndex+"rn");
				return?false;
			}
			SYS_LOG.Write("分組"?+?GroupIndex?+?"擴(kuò)容成功rn");
		}
		this->pDeviceDataGroupPointerBuff[GroupIndex][this->GroupDeviceCnt[GroupIndex]]?=?DeviceDataPointer;	//保存當(dāng)前設(shè)備指針
		this->GroupDeviceCnt[GroupIndex]?++;									//分組內(nèi)的設(shè)備數(shù)量增加

		return?true;
	}
	//為指定的分組進(jìn)行擴(kuò)容,會先復(fù)制緩沖區(qū),然后重新申請,再釋放之前的緩沖區(qū)(注意:使用分組索引只能在一個線程中使用)
	//必須分組已經(jīng)滿了再調(diào)用
	bool?DeviceGroupExpansion(int?GroupIndex)
	{
		if?(GroupIndex?<?0?||?GroupIndex?>=?DEVICE_GROUP_CNT)?return?false;
		if?(this->GroupSize[GroupIndex]?>=?DEVICE_MAX_CNT)?return?false;	//分組大小不能超過總設(shè)備限制
		DWORD?*p?=?this->pDeviceDataGroupPointerBuff[GroupIndex];			//先復(fù)制之前的指針
		DWORD?Size?=?this->GroupSize[GroupIndex];							//記錄之前分組容量
		this->GroupSize[GroupIndex]?+=?GROUP_DEVICE_INC;					//當(dāng)前分組容量增加
		this->pDeviceDataGroupPointerBuff[GroupIndex]?=?new?DWORD[this->GroupSize[GroupIndex]];	//重新為當(dāng)前分組申請內(nèi)存
		memcpy(this->pDeviceDataGroupPointerBuff[GroupIndex],?p,?Size*sizeof(DWORD));			//將之前的分組設(shè)備信息拷貝到新緩沖區(qū)中
		USER_DELTE(p);														//釋放掉之前的舊緩沖區(qū)

		return?true;
	}


后面我會擴(kuò)展使用這個協(xié)議的下位機(jī)與服務(wù)端框架,并提供相應(yīng)的測試?yán)印?br />

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點: 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運(yùn)營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團(tuán))股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉