__attribute__ ((packed))

網絡通訊一般分爲基於數據結構的和基於流的。HTTP協議就是後者的一個例子。
    有時爲了提升程序的處理速度和數據處理的方便,會使用基於數據結構的通訊(不須要對流進行解析)。可是,當須要在多平臺間進行通訊時,基於數據結構的通訊,每每要十分注意如下幾個方面:
[1] 字節序
[2] 變量長度
[3] 內存對齊
    在常見的系統架構中(Linux X86,Windows),非單字節長度的變量類型,都是低字節在前,而在某些特定系統中,如Soalris Sparc平臺,高字節在前。若是在發送數據前不進行處理,那麼由Linux X86發向Soalris Sparc平臺的數據值,勢必會有極大的誤差,進而程序運行過程當中沒法出現預計的正常結果,更嚴重時,會致使段錯誤。
    對於此種狀況,咱們每每使用同一的字節序。在系統中,有ntohXXX(), htonXXX()等函數,負責將數據在網絡字節序和本地字節序之間轉換。雖然每種系統的本地字節序不一樣,可是對於全部系統來講,網絡字節序是固定的 -----高字節在前。因此,能夠以網絡字節序爲通訊的標準,發送前,數據都轉換爲網絡字節序。
    轉換的過程,也建議使用ntohXXX(), htonXXX()等標準函數,這樣代碼能夠輕鬆地在各平臺間進行移植(像通訊這種不多依賴系統API的代碼,作成通用版本是不錯的選擇)。

    變量的長度,在不一樣的系統之間會有差異,如同是Linux2.6.18的平臺,在64位系統中,指針的長度爲8個字節,而在32位系統中,指針又是4個字 節的長度---此處只是舉個例子,不多有人會將指針做爲數據發送出去。下面是我整理的在64位Linux系統和32位Linux系統中,幾種常見C語言變 量的長度:
                short    int    long    long long    ptr    time_t
32位           2         4       4             8               4        4
64位           2         4       8             8               8        8
    在定義通訊用的結構體時,應該考慮使用定常的數據類型,如uint32_t,4字節的固定長度,而且這屬於標準C庫(C99),在各系統中均可使用。

    內存對齊的問題,也與系統是64位仍是32位有關。若是你手頭有32位和64位系統,不妨寫個簡單的程序測試一下,你就會看到同一個結構體,即使使用了定 常的數據類型,在不一樣系統中的大小是不一樣的。對齊每每是以4字節或8字節爲準的,只要你寫的測試程序,變量所佔空間沒有對齊到4或8的倍數便可,舉個簡單 的測試用的結構體的例子吧:
struct student
{
    char name[7];
    uint32_t id;
    char subject[5];
};
    在每一個系統上看下這個結構體的長度吧。
    內存對齊,每每是由編譯器來作的,若是你使用的是gcc,能夠在定義變量時,添加__attribute__,來決定是否使用內存對齊,或是內存對齊到幾個字節,以上面的結構體爲例:
 1)到4字節,一樣可指定對齊到8字節。
struct student
{
    char name[7];
    uint32_t id;
    char subject[5];
} __attribute__ ((aligned(4))); 

2)不對齊,結構體的長度,就是各個變量長度的和
struct student
{
    char name[7];
    uint32_t id;
    char subject[5];
} __attribute__ ((packed));網絡

相關文章
相關標籤/搜索