У меня есть простое клиентское приложение С#, которое отправляет объект в приложение на базе 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());
Проблема: я не получаю сериализованное сообщение, отправленное приложением С#. Даже я не получаю никаких ошибок. Вот почему я не смог понять проблему.
"Проблема: я не получаю сериализованное сообщение"
Это звучит просто как проблема классических "сокетов - это потоки" (второй пример здесь: http://marcgravell.blogspot.com/2013/02/how-many-ways-can-you-mess-up-io.html). Если вы записывали данные в поток, но не закрывали этот поток, принимающий поток не заканчивается. Он также автоматически не знает, что клиент отправил (скажем) 117 байт, которые следует рассматривать как одно сообщение. У вас есть два варианта:
Примечание: в дополнение к проблеме "сокеты - потоки", также имейте в виду, что сообщения protobuf являются добавочными. Сообщение протобуфа само по себе не имеет понятия о том, где оно заканчивается. К счастью, оба указанных выше пункта будут направлены на это. Но главное, вы не можете просто написать объект 3 Person
для потока в кадре (или закрыть поток), а затем ожидать, что сможете вернуть обратно 3 объекта Person
на другом конце: вы получите один объект Person
. В этом сценарии самым простым вариантом является добавление объекта-оболочки, т.е.
message SomeMessage {
repeated Person people = 1;
}
Попробуйте добавить эти атрибуты в свой класс на С# и проверить, хорошо ли введен в Java.
[ProtoContract]
class Person
{
[ProtoMember(1)]
public string id = "1";
}