Отправка объекта сериализации protobuf из C # на сервер Java не работает?

1

У меня есть простое клиентское приложение С#, которое отправляет объект в приложение на базе Java. Примечание. Я использую protobuf-net на стороне клиенте. Для этого приложения у меня есть простой файл.proto с одним полем, а класс.java создается компилятором protoc.

.Proto файл:

 message Person {  
 required string  id = 1;       
}

Клиент С# для отправки объекта

MemoryStream ms = new MemoryStream();
            Person per = new Person();            
            per.id = "TestId001";           
            Serializer.Serialize<Person>(ms, per);
            byte[] buffer = ms.ToArray();
            clientSocket.SendTo(buffer, hostEP);

Сервер на основе Java для получения объекта

DataInputStream inputStream=new DataInputStream(socket.getInputStream());    
Person person = Person.parseFrom(socket.getInputStream());                          
System.out.println("Id:  " + person.getId());

Проблема: я не получаю сериализованное сообщение, отправленное приложением С#. Даже я не получаю никаких ошибок. Вот почему я не смог понять проблему.

  • 1
    Вы добавили атрибуты ProtoContract и ProtoParam в свой класс клиента?
  • 0
    Включите класс Person, который вы используете в C # и Java, и сообщите нам значение, полученное в inputStream.
Теги:
sockets
serialization
protobuf-net

2 ответа

1
Лучший ответ

"Проблема: я не получаю сериализованное сообщение"

Это звучит просто как проблема классических "сокетов - это потоки" (второй пример здесь: http://marcgravell.blogspot.com/2013/02/how-many-ways-can-you-mess-up-io.html). Если вы записывали данные в поток, но не закрывали этот поток, принимающий поток не заканчивается. Он также автоматически не знает, что клиент отправил (скажем) 117 байт, которые следует рассматривать как одно сообщение. У вас есть два варианта:

  • закройте исходящий поток после записи (подходит только для отправки отдельных сообщений, а не для продолжения обсуждения между двумя узлами)
  • введите некоторую форму кадрирования - например, префикс длины - так, чтобы получатель знал, что пытается только прочитать определенный объем данных, вместо того, чтобы пытаться прочитать EOF (который никогда не придет, если вы не закрыли исходящий поток)

Примечание: в дополнение к проблеме "сокеты - потоки", также имейте в виду, что сообщения protobuf являются добавочными. Сообщение протобуфа само по себе не имеет понятия о том, где оно заканчивается. К счастью, оба указанных выше пункта будут направлены на это. Но главное, вы не можете просто написать объект 3 Person для потока в кадре (или закрыть поток), а затем ожидать, что сможете вернуть обратно 3 объекта Person на другом конце: вы получите один объект Person. В этом сценарии самым простым вариантом является добавление объекта-оболочки, т.е.

message SomeMessage {  
 repeated Person people = 1;       
}
  • 0
    спасибо, это сработало.
0

Попробуйте добавить эти атрибуты в свой класс на С# и проверить, хорошо ли введен в Java.

   [ProtoContract]
    class Person 
    {
     [ProtoMember(1)] 
     public string  id = "1";       
    }
  • 0
    Я сильно подозреваю , что эта проблема не является на самом деле ничего общего с Protobuf вообще ...

Ещё вопросы

Сообщество Overcoder
Наверх
Меню