Проблема с десериализацией данных с помощью protobuf-net, сериализованных с помощью protobuf Google

В настоящее время я работаю над кодом, который сериализуется в одном приложении (C ++) и должен десериализовать его в другом (C #). Я пытаюсь использовать google proto + protobuf-net, но что-то не получается.

Файлы определения сообщений .cc и .cs были созданы соответствующими компиляторами из одного и того же файла .proto.

Данные отправляются через UDP, и сообщения (~ 40B) легко помещаются в единую дейтаграмму.

Что касается размера C ++, boost :: asio используется для передачи данных, соответствующий код:

ProtocolBufferdata data;
...
boost::asio::streambuf b;
std::ostream os(&b);
data.SerializeToOstream(&os);
m_Socket.send_to(b.data(), m_Endpoint);

Я почти уверен, что это работает правильно, поскольку с помощью wirehark я могу по крайней мере видеть все строки, которые я ожидаю в дейтаграмме. На стороне C #, используя Begin / End recieve, мы имеем в обратном вызове следующее:

byte[] buffer ....        

public void ReceiveData(IAsyncResult iar)
{
    try
    {
        Socket remote = (Socket)iar.AsyncState;
        int recv = remote.EndReceive(iar);
        using (MemoryStream memStream = new MemoryStream())
        {
            memStream.Write(buffer, 0, recv);
            ProtoData data = ProtoBuf.Serializer.Deserialize<ProtoData >(memStream);
            onReceive(data);
        }
    }
    catch (Exception ex)
    {
        ...
    }
    finally
    {
        socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveData), socket);
    }
}

В буфере есть ожидаемое количество байтов и контрольные строки. Контейнер protobuf-net имеет все значения по умолчанию.

Я немного озадачен тем, что здесь происходит, и почти невозможно подключить отладчик к клиентскому приложению, поскольку он развертывается как подключаемый модуль к другому приложению, которое плохо работает с удаленным отладчиком. Буду признателен за любой совет, это меня поставило в тупик.


person Chuu    schedule 27.01.2011    source источник


Ответы (1)


Перемотайте поток назад - он в конце, поэтому Read не вернет данных:

memStream.Write(buffer, 0, recv);
memStream.Position = 0; // <===========here
ProtoData data = ProtoBuf.Serializer.Deserialize<ProtoData>(memStream);

в качестве альтернативы используйте перегруженный конструктор для подготовки потока:

using (MemoryStream memStream = new MemoryStream(buffer, 0, recv))
{
    ProtoData data = ProtoBuf.Serializer.Deserialize<ProtoData>(memStream);
person Marc Gravell    schedule 27.01.2011
comment
Ух ты . . . Я чувствую себя действительно глупо. Спасибо за ответ. - person Chuu; 28.01.2011