2016-06-30 44 views
0

我發送一個c結構寫入服務器。結構和寫看起來像這樣。C中的未知字節寫入結構

typedef struct MyStruct { 
    uint8_t   flag; 
    char   str[50]; 
    int32_t   number; 
    time_t   time; 

} MyStruct ; 

... 

// Create mystruct 

memset(&mystruct->flag, '\1', sizeof(uint8_t)); 
memset(&mystruct->str, '\0', sizeof(char) * 50); 
memset(&mystruct->number, '\2', sizeof(int32_t)); 
memset(&mystruct->time, '\3', sizeof(time_t)); 

write(sockfd, mystruct, sizeof(MyStruct)); 

的服務器,在Java中,接收在NIO ByteBuffer的信息,然後用得到一個ByteBuffer.arraybyte[]。當我檢查byte[]其內容是:

[ 0]   = 1 
[ 1] to [50] = 0 
[51]   = 70 
[52] to [55] = 2 
[56] to [63] = 3 

如果添加了長度可達1 + 50 + 4 + 8你63,但與奇70字節長度爲64

爲什麼70字節在這裏?它與網絡或C結構有關嗎?還有,如果可以的話,如何去除它?

+3

請不要這樣做。你正在尋求一個痛苦的世界。如果您打算使用發送字節流的通道,請準確定義您要交換的字節流。不要說「我會發送任何C結構碰巧是,並希望它發生對另一方有意義」。 –

+0

另外,你是否意識到'memset(&mystruct-> number,'\ 2',sizeof(int32_t));'將變量設置爲0x02020202或十進制'33686018'? –

+0

@WeatherVane是的,這只是我調試它。 – ezPaint

回答

2

爲什麼70字節在這裏?它是否與網絡 或c結構有關?還有,如果可以的話,如何去除它?

它可能與結構padding有關。如果是這種情況,你可以嘗試序列化結構的每個成員。

而且here爲柱,這也解釋了所有與序列化的陷阱中C.

序列化在C更棘手的比說,在C#或我想也是在Java中,例如在C#中,你知道整數總是4個字節大小,在C中不是這種情況,整數的大小可以在平臺上變化。

+0

所以通過序列化,在C中,我應該創建一個方法,創建一個字節數組設置我想要的方式? – ezPaint

+0

@ezPaint是檢查我的答案中的鏈接 –

+0

@ezPaint還有一些像雜注包一樣的 - 但經常建議不要 –

2

這幾乎肯定是由於結構填充;最有可能的是,您的編譯器/處理器要求32位值對齊32位,因此,由於您的uint8_t和您的char[50]合計爲51字節,因此在strnumber之間有一個1字節的焊盤。

正如在評論中提到的 - 你真的想明確處理你的序列化。有許多庫可以處理定義Java和C/C++類型,以及用於在每種語言中序列化/反序列化的方法。