從零開始的激光通訊(軟件篇 第1章 協議棧)——3、提取數據包

從零開始的激光通訊(軟件篇 第1章 協議棧)——3、提取數據包

github

https://github.com/HaHaHaHaHaGe/mynetstack

簡介

數據包的提取其實原理並不複雜,就像拼積木一樣,見下圖:
在這裏插入圖片描述
這些字是我隨便打出來的,現在這串字符串中,我說包含了三個數據包,需要提取出來
規則如下:
碰到數字:1234 代表後面的將是需要提取的數據
具體提取幾個呢,提取1234後面那個數字的個數
如:12345關懷和分化.
1234是開頭
5是提取的個數
後面的5個字就是待提取的數據
1234叫做 包頭
5叫做 數據長度

這是最簡單的情況,但是實際應用中會有些複雜,

首先我們要知道,在傳輸數據的時候,任何數據都可能被傳輸
也就是說我現在定義:若遇到1234則代表後面的將是需要提取的數據
但若傳輸的數據中恰好包含1234會怎麼樣呢?
在這裏插入圖片描述
就像這個樣子,處理肯定會出現錯誤,所以我們需要對原始數據進行一下轉化比如在每個數據面前增加一個符號’/’
在這裏插入圖片描述

其次我們知道在實際應用中,難免會有干擾
有干擾就意味着很可能數據傳輸出現錯誤
原本發送的是1110接受端接收到的可能就變成1100了

所以在此基礎上還需要增加校驗,也就是說有專門的一個數來表示這段數據是不是正確的
在這裏插入圖片描述
到現在爲止,一個比較可靠的基本數據包結構就完成了

當然在實際應用中我們不會直接使用字符去傳輸數據,更不會使用字符’/'去分割數據,這樣做太浪費資源了
那麼我們會怎麼做呢?
在這裏插入圖片描述

這是截取開頭的一段真實數據包,首先0xff 0xff 0xff 0xff是數據包頭,00 00 04 00是數據長度 ,1F 2A 56 01 是CRC32 校驗,對包頭、數據長度、數據進行校驗,後面的就是數據了。

但是不知有沒有發現’/'是怎麼實現的呢?
實際上後面的所有的數據都是已經進行過處理的,它們的第8位恆爲零,這就保證永遠不可能出現0xFF,哪怕由於干擾出現了0xFF 那麼連續出現四個0xFF的概率微乎其微,但是這種做法也會增加額外的傳輸負擔,比如若我想要傳輸56個字節,那麼由於第八位已經被設置位固定0 所以我只能往後移一位,去佔用下一個字節的空間。以此類推,到最後,真正傳輸的字節就會變成:
(56*8)/7 = 64
最終我們原始數據從56字節,變成了64字節

函數說明

有關數據包提取的文件在\mynetstack\Source\BasicDataStream\inc 與\mynetstack\Source\BasicDataStream\src 中
名稱爲 packeg_taken.c 與 packeg_taken.h

注:程序還在更新,以GITHUB爲準

/*
從拼接的兩段數組中尋找正確的數據包
數據包格式:
-------------------------------------------------------
0-3		4-7		8-11	12-N
包頭	數據長	CRC32	數據
-------------------------------------------------------
入口參數:
src1:第一個數組
src2:第二個數組
len1:第一個數組大小
len2:第二個數組大小
rdata_1:返回數據的第一指針
rdata_2:返回數據的第二指針
rlen_1:返回數據第一指針指向的數據段長度
rlen_2:返回數據第二指針指向的數據段長度
stop_ptr:返回停止查找的位置(被阻斷查找的原因包括:成功找到數據包,找到損壞數據包,找到截斷數據包)
返回值:
是否找到數據包
*/
u8 search_packeg(u8*src1, u8*src2, u32 len1, u32 len2, u8**rdata_1, u8**rdata_2, u32*rlen_1, u32*rlen_2, u8** stop_ptr);


/*
從拼接的兩段數組中尋找正確的數據包並進行7bit->8bit轉化
重新分配內存並保存數據
src1:第一個數組
src2:第二個數組
len1:第一個數組大小
len2:第二個數組大小
返回值:
如果沒有正確數據包返回NULL_PTR
否則返回新分配的內存地址(指向轉化完畢的數據包)
*/
u8* unpacking(u8* src1, u8* src2, u32 len1, u32 len2);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章