Странное поведение десериализации Apache Thrift в.Net

Я использую Apache Thrift в своих приложениях для обмена данными между несколькими машинами.

Я получаю данные из космоса, создаю транспорт, протоколирую и десериализую полученные данные в объект. Вот мой код:

using (var memoryStream = new MemoryStream(data))
        {
            using (var transport = new TStreamTransport(memoryStream, memoryStream))
            {
                transport.Open();
                using (var protocolo = new TBinaryProtocol(transport))
                {
                    var result = new TCciUserLoginV1.cciUserLoginV1_result();

                    while (result.Success== null)
                    {
                        try
                        {
                            result.Read(protocolo);
                        }
                        catch { }
                    }

                    if (result.Success != null)
                    {
                        res = new RequestResult(result.Success);
                    }
                    else
                    {
                        res = new RequestResult(ResultCodes.LOCAL_ERROR");
                    }
                }
            }
        }

Я знаю, что получаю двоичный сериализованный TCciUserLoginV1.cciUserLoginV1_result, потому что десериализация других типов вызывает исключение. Но нормальная десериализация свойства result.Success происходит только после 10-й итерации цикла while. Вот почему я использовал пока. Кто-нибудь может сказать мне, что происходит?

Заранее спасибо.

1 ответ

Похоже, что входящий буфер данных содержит мусор, см. Рисунок. Ваши данные показаны сверху, правильный пример сообщения с использованием той же настройки ниже.

Первый байт данных должен быть байтом кода типа, за которым следует 16-битный идентификатор поля, но в вашем примере оба числа абсолютно безумны: 48 не является допустимым кодом типа, а -32248 не похож на правильный идентификатор поля,

Если присмотреться к изображению поближе и сравнить с правильным образцом, используя те же определения IDL, становится ясно, что сообщение начинается не в начале, а где-то посередине со смещением 0x59. Таким образом, данные, отправленные в Thrift для десериализации, не являются действительным блоком данных, это точно.

Другим показателем того, что что-то серьезно не так, может быть разница в размерах между двумя выборками данных: 2093 байта против 93 байтов.

анализ

но разработчики этого сервиса уверяют, что весь мой код корректен, и после перевода его на Java все работает нормально без циклов.

Это может указывать на то, что проблема заключается в том, что вы получаете, а что выходит из Decrypt() рутина. Дикая догадка, но это будет следующая вещь, чтобы проверить. Я бы сравнил то, что было зашифровано на другой стороне, и что получилось. В качестве альтернативы, сравните BLOB-данные с тем, что видит рабочий тестовый код Java после расшифровки. Где-то должна быть разница.

Другие вопросы по тегам