c++ - 网络编程和字节对齐的问题?
天蓬老师
天蓬老师 2017-04-17 13:14:46
0
6
735
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)。这样的话,通过网络发送这个缓冲区里的数据的话就不包含字节对齐的值了吧,这就是序列化的意义吗?

求大神告诉我理解的对不对?不对的话我的哪些地方没有理解对呢?

天蓬老师
天蓬老师

欢迎选择我的课程,让我们一起见证您的进步~~

全部回覆(6)
伊谢尔伦

記憶體佈局不可移植. 而且還有空隙.
序列化就是為了移植. 各種語言遵守序列化的方式, 就可以反序列化出來物件, 可以把一個物件序列化. 這樣就可以跨語言互動.

左手右手慢动作

序列化的意義在於,定義一種程式中的資料到位元組字串的對應關係(及其逆關係),以便用來儲存、傳輸。這種關係是標準,與實作無關、與平台無關(不管你用什麼 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
{

int32 a;
int32 _reversed;
double b;

};
否則不同編譯選項編譯出來結果是不一樣的,不一定都是16位元組。

伊谢尔伦

既然樓主這麼虛心請教,就直說一下樓主理解的不對的地方吧:

把這個demo物件序列化為二進位的話

demo 這個 struct 原本就已經是二進位的了,write(sockfd, &demo, sizeof(demo)) 發送的就是二進位資料。

是不是就是把demo裡的int和double的值複製到一個緩衝區裡

複製?緩衝區?樓主是從哪裡看來的這些概念,完全不是這樣的…

值的長度就是12位元組了(int + double)

為節省記憶體不浪費一個位元組,可以用巨集 #pragma pack(1) 來搞定。

伊谢尔伦

http://www.cppblog.com/vczh/archive/2009/03/10/76098.html

看我博客,詳細解答

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板