чтение в C ++ сокета, открытого с помощью выравнивания структуры Java + - PullRequest
0 голосов
/ 16 июля 2010

Я пытаюсь написать в Linnux клиент на C ++, используя boost::asio данные из сокета.Сервер построен на Java.У меня сейчас проблема в том, что я не могу правильно прочитать некоторую информацию из сокета.Если клиент работает в JAVA, то все в порядке.

В деталях большая ошибка, которую я имею в получении unsigned long и int в приведенной ниже структуре.Я ожидаю, что значение для anInteger должно быть 0x00000005, поэтому 5, но чтение из сокета дает мне 0x03000 (?!?!).Это определенно другое число, и на основе шестнадцатеричной печати у меня меньше цифр (?!?!?).

Для aUnLong я должен получить что-то приближающееся к числу 1279272977799, поэтому в шестнадцатеричном виде это 0x129DA9C8587вместо этого получить что-то вроде 0x00129ffffffdaffffff8fffffff9f5c.Я вижу, что некоторая информация хороша, но она смешана со всеми ff с и откуда я не знаю, откуда они берутся.

Я гарантированно получаю каждый раз 168 байтов (так что фиксированное числобайтов).Вначале я подумал о выравнивании данных моей структуры, поэтому я ввел <strong>attribute</strong>((<strong>packed</strong>)).

label и lbl_2 - строки;Я теперь, когда JAVA использует UTF, но мне не ясно, как эта игра в этом сценарии.

Можете ли вы помочь мне с этим вопросом?

Я очень благодарен вам.

EO

union MyStruct
{
    char buffer[168];

    struct _data{
        char            dash[2];    
        unsigned long   aUnLong;
        char            label[128]; 
        char            lbl_2[24];  
        int         anInteger;  
    } __attribute__((__packed__));

    _data data; // the real data
};

Чтение происходит с использованием этой простой строки

MyStruct obj;
size_t reply_length = asio::read( s,asio::buffer(obj.buffer, 168));

это исходный формат, отправленный

byte 000,001: #
byte 002-010: aLong (8 byte) long - milliseconds since 1-1-1970 in UTC
byte 011-139: label (128 byte 2byte per character) label_1
byte 140-164: lbl2 (24 byte 2byte per character) label2 code
byte 165-169: anInteger (4 byte) integer

1 Ответ

1 голос
/ 16 июля 2010

Ваша структура не имеет размера 168 байт в обычных системах.Если long равен 4 байта (типично для 32-битной компиляции), то ваша структура, вероятно, будет 162 или 164, если упакованные не соблюдаются.Если long равен 8 байтам, то 164 или 168 (если дополняется, что, как вы предполагаете, плохо).

Проверьте sizeof(_data) в вашей программе и посмотрите, что это говорит компилятор.*

Кроме того, информация о вашем исходном формате сбивает с толку.Например, вы говорите «байт 002-010: aLong (8 byte) long», но байты 2-10 - это NINE (9) байтов, а не 8. Есть байт crc или контрольной суммы?

...