在分布式系統的軟體開發過程中,位元組序轉換總是一件令人頭疼的麻煩事,尤其是引數眾多,函式上下層次較多的場合,極易發生某個引數漏轉序的事故……
樣例:/* 靜態結構體位元組序轉換 */
extern vos_bool switchendian(vos_void *pstruct, const vos_char *pcfmt);
typedef struct demo_stru;
int main()
;switchendian(&stdemo, "lh12s2x2c2xq"); // 傳入格式化串,實現位元組序轉換
return 0;
}格式化串中各symbol的說明(與python的語法格式相似,是其簡化版)
symbol type size remark
q u64,i64,double 8*n
l u32,i32,float 4*n
h u16,i16 2*n
c u8, s8 1*n filling each separately
s string 1*n filling all together
x padding 1*n filling zero automacly
space useless seperator python中沒有space,為提高可讀而加
"lh12s2x2c2xq" == "l h 12s 2x 2c 2x q" == demo_stru
結構描述串也是一種領域特定語言,通過簡單的格式對映,將結構體(或二進位制)資訊轉換成程式可識別的格式,讓程式來實現繁瑣且冗長的轉換。
拼接fmt串的建議:
對於靜態結構,格式化字串可以寫死,缺點是結構調整就得更新這個fmt串,這是無法避免的
對於動態結構,格式化字串可以通過sprintf拼接
更智慧型的應用是:將所有待轉序的結構體定義放在同乙個.h中,寫一段python指令碼掃瞄結構自動生成fmt串,這樣即使是結構存在巢狀(被巢狀的結構一定定義在巢狀結構之前),也能準確拼處正確的fmt串
結構體打包,類似python的struct.pack(...)
例項:demo_stru stdemo;
packstruct(&stdemo, "!lh12sxx2c2xq", 0x55667788, 10000, "abcdef", 'a', 'b', -123456.78901);
一句函式呼叫實現多個入參的賦值,fmt串前的!表示賦值的同時還轉序(對於x即填充字段,自動賦0,不用指定引數傳入)。這種寫法比較節省**行數,在串列埠除錯構造結構體引數也非常便利。
計算結構長度,類似python的struct.calcsize(...)
例項:printf("%d == %d\n", sizeof(demo_stru), calcsize("!lh12sxx2c2xq"));
calcsize是按一位元組對齊計算結構尺寸,用來和sizeof結果比較,可以判斷某結構是否緊壓縮,除錯用
結構成員列印,類似python的print:
vos_bool printstruct(vos_void *pstruct, const vos_char *pcfmt);
把結構的每個成員按型別dump出來,用於除錯定位,相比數記憶體看資料高效得多
/*** a specification for symbols in format string
symbol type size remark
q u64,i64,double 8*n
l u32,i32,float 4*n
h u16,i16 2*n
c u8, s8 1*n filling each separately
s string 1*n filling all together
x padding 1*n filling zero automacly
! switch endian indicator
space useless seperator
***/
vos_char getnextsymbol(const vos_char *pcfmt, vos_int *pnoffset, vos_int *pnelecount)
pccurr++;
}return *pccurr; // end symbol
}vos_bool printstruct(vos_void *pstruct, const vos_char *pcfmt)
}#undef set_element
/* 相當於sizeof(),用於校驗 */
vos_int calcsize(const vos_char *pcfmt)
}return false;
}/* 靜態結構體轉序 */
vos_bool switchendian(vos_void *pstruct, const vos_char *pcfmt)
}#undef sw_endian
return false;
}// 按指定格式填充結構體(緊壓縮),支援轉序
vos_bool packstruct(vos_void *pstruct, const vos_char *pcfmt, ...)
}#undef set_element
va_end(parglist);
if (bswendian) switchendian(pstruct, pcfmt);
return true;}
python 網路位元組序轉換 網路位元組序
一.位元組序 位元組序是由於不同的主處理器和作業系統,對大於乙個位元組的變數在記憶體中的存放順序不同而產生的。位元組序通常有大端位元組序列和小端位元組序兩種分類方法。由於主機的千差萬別,主機的位元組序不能做到統一,但是網路上傳輸的數值,它們有統一的規定。網路位元組序 是指多位元組變數在網路傳輸時的表...
主機位元組序和網路位元組序轉換
為什麼要轉換?主機位元組序 整數在記憶體中儲存的順序,不同的處理器對應不容的模式 little endian 將低序位元組儲存在起始位址 big endian 將高序位元組儲存在起始位址 網路位元組序 整數在網路中的傳送順序 網路位元組順序是tcp ip中規定好的一種資料表示格式,它與具體的cpu型...
linux位元組序轉換函式和位址轉換函式
剛才閱讀 的時候看到了乙個位元組排序函式,一時想不起具體用法了。想想學習linux下的網路程式設計也不少時間了,這些位元組排序和轉換的函式還是不太清楚,容易混淆。今天索性把這方面的知識彙總一下,爭取以後能夠熟練的認識和運用。位元組順序函式 小端位元組序 將低序位元組儲存在起始位址。linux 大端位...