struct TestClass
{
int a;
double b;
};
这个结构体占用的内存的大小是16字节(windows下),它在内存里面按照double的字节大小对齐。
TestClass demo = {1, 1.1};
定义一个对象后,通过网络把这个demo对象发出去。
write(sockfd, &demo, sizeof(demo));
这样是发出去16个字节对吧?这样发出去的数据就包含了编译器字节对齐插进去的4个字节了吧?我的理解对吗?
如果把这个demo对象序列化为二进制的话是不是就是把demo里的int和double的值复制到一个缓冲区里,这样这个缓冲区的里面的值的长度就是12字节了(int + double)。这样的话,通过网络发送这个缓冲区里的数据的话就不包含字节对齐的值了吧,这就是序列化的意义吗?
求大神告诉我理解的对不对?不对的话我的哪些地方没有理解对呢?
記憶體佈局不可移植. 而且還有空隙.
序列化就是為了移植. 各種語言遵守序列化的方式, 就可以反序列化出來物件, 可以把一個物件序列化. 這樣就可以跨語言互動.
序列化的意義在於,定義一種程式中的資料到位元組字串的對應關係(及其逆關係),以便用來儲存、傳輸。這種關係是標準,與實作無關、與平台無關(不管你用什麼 CPU,什麼作業系統,什麼編譯器,什麼程式語言,序列化的資料的解釋方法都是預先定義好的)。
當然也有侷限於特定程式語言的序列化方案(如 Python 的 pickle)。但那隻是只有那種語言的實作而已,理論上你可以寫它語言的程式來解釋這些資料。
1.
write(sockfd, &demo, sizeof(demo));
這樣發出去確實是16位元組。
但你要明白write函數本身是跟位元組對齊沒關的。 write函數本身只知道從哪個位址開始,發送多少位元組的內容,write函數本身可不知道你的demo是什麼結構。之所以會發送16個字節,是因為sizeof(demo)算出來是16字節。
2.序列化是一些程式語言的函式庫提供的,可以將資料映射為bytes用來儲存或傳輸。反序列化就是從bytes重新進行載入還原。這兩個過程是庫本身提供的,而庫的開發者會確保這個過程在所有平台上都是可移植的。
說點題外話,網路程式設計最好明確pack,如64位元機器依64位元設計結構
struct TestClass
{
};
否則不同編譯選項編譯出來結果是不一樣的,不一定都是16位元組。
既然樓主這麼虛心請教,就直說一下樓主理解的不對的地方吧:
demo 這個 struct 原本就已經是二進位的了,write(sockfd, &demo, sizeof(demo)) 發送的就是二進位資料。
複製?緩衝區?樓主是從哪裡看來的這些概念,完全不是這樣的…
為節省記憶體不浪費一個位元組,可以用巨集 #pragma pack(1) 來搞定。
http://www.cppblog.com/vczh/archive/2009/03/10/76098.html
看我博客,詳細解答