2016-06-30 3 views
0

Я отправляю c-структуру с записью на сервер. Структура и запись выглядят так.Неизвестный байт в C писать struct

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, а затем получает byte[] с ByteBuffer.array. Когда я анализирую в 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 structs? И как, если смогу, избавиться от него?

Возможно, это связано со структурой padding. Вы можете попробовать и сериализовать каждый член структуры отдельно, если это так.

Также here является пост, который хорошо объясняет все подводные камни с сериализации в С.

Сериализация в C является более сложным, чем, скажем, в C# или я думаю, что и в Java, например, в C# вы знаете, что целое число всегда 4 байта, что не так в C, где размер целого может различаться на платформах.

+0

Итак, сериализуем, в C, я должен сделать метод, который создает массив байтов, как я хочу? – ezPaint

+0

@ezPaint Да проверить ссылку в моем ответе –

+0

@ezPaint Существует также smth, как прагма-пакет, но часто советуют против –

2

Это почти наверняка из-за прокладки конструкции; скорее всего, ваш компилятор/процессор требует 32-битных значений для 32-битного выравнивания, так как ваши uint8_t и ваш char[50] содержат до 51 байта, есть однобайтовая панель между str и number.

Как уже упоминалось в комментариях - вы действительно хотите обработать свою сериализацию явно. Существует ряд библиотек, которые могут обрабатывать определенные типы Java и C/C++, а также методы сериализации/десериализации на каждом языке.

Смежные вопросы