чтение в C++ сокета, открытого с помощью Java + выравнивание структуры

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

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

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

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

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

person user311906    schedule 16.07.2010    source источник
comment
Трудно предложить какую-либо помощь, не зная, какой протокол и/или формат сериализации использует сервер Java.   -  person Marcelo Cantos    schedule 16.07.2010
comment
Нам нужно знать формат сообщений, которые отправляет Java-сервер.   -  person nos    schedule 16.07.2010


Ответы (1)


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

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

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

person Mark B    schedule 16.07.2010