Question

I have simple c# client app which sends object to java based server app. Note:I am using protobuf-net on clinet side. For this application I have simple .proto file with only one field and .java class is generated by protoc compiler.

.Proto file:

 message Person {  
 required string  id = 1;       
}

C# client to send object

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 based server to receive object

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

Problem: I not getting the serialized message as sent by the c# app.Even I am not getting any errors. That's why I was unable to figureout the problem.

Was it helpful?

Solution

"Problem: I not getting the serialized message"

This sounds simply like the classic "sockets are streams" issue (second example here: http://marcgravell.blogspot.com/2013/02/how-many-ways-can-you-mess-up-io.html). If you have written data to a stream but haven't closed that stream, the receiving stream does not terminate. It also does not automatically know that the client sent (say) 117 bytes that should be considered a single message. You have two options:

  • close the outbound stream after writing (only suitable for sending single messages, not for continued discussions between two nodes)
  • introduce some form of framing - for example a length-prefix - so that the receiver knows to only try to read a certain amount of data, rather than trying to read to the EOF (which will never come if you haven't closed the outbound stream)

Note: in addition to the "sockets are streams" issue, also keep in mind that protobuf messages are appendable. A protobuf message, by itself, has no notion of where it ends. Fortunately, both the existing bullet points above will address this. But importantly, you can't just write 3 Person object to the stream in a frame (or close the stream), and then expect to be able to get back 3 Person objects at the other end: you will get one Person object. In this scenario, the simplest option is to add a wrapper object, i.e.

message SomeMessage {  
 repeated Person people = 1;       
}

OTHER TIPS

Try adding these attributes to your class in C# and check if the input is ok in Java.

   [ProtoContract]
    class Person 
    {
     [ProtoMember(1)] 
     public string  id = "1";       
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top