Sorry, but I think I am going mad. I have this in C++:
std::stringstream message;
protoMsg.SerializeToOstream(&message);
boost::system::error_code ignored_error;
std::cout << "Writing response to socket. Byte size " << protoMsg.ByteSize() << " Buffer " << message.str().length() << std::endl;
for(int i(0);i<(int)message.str().length();i++)
std::cout << (int)message.str().at(i);
std::cout << std::endl;
boost::asio::write(socket, boost::asio::buffer(message.str()), ignored_error);
std::cout << "Done writing." << std::endl;
Which yields this output
Writing response to socket. Byte size 88 Buffer 88
1886811891161111001113278971091012500000000320400480560640730000000081000000008859621061211611110011132115121109789710910111416691201161011141109710832114101113117101115116
Done writing.
And this in Java:
try {
System.out.println("Parsing");
int lenbytes = is.read(buffer);
System.out.println("Read bytes " + lenbytes);
for(int i=0;i<lenbytes;i++)
System.out.print(Integer.toString((int)buffer[i]));
System.out.println("");
EnvInfoProto envInfoProto = EnvInfoProto.parseFrom(buffer);
System.out.println("Done");
return envInfoProto;
} catch(IOException ignore) { System.out.println("Ex: " + ignore.toString(); }
Which yields
Parsing
Read bytes 88
1886811891161111001113278971091012500000000320400480560640730000000081000000008859621061211611110011132115121109789710910111416691201161011141109710832114101113117101115116
Ex: com.google.protobuf.InvalidProtocolBufferException: Protocol message contained an invalid tag (zero).
The binary data is the same. I checked that I am using the right version of the proto files. I am a bit at a loss tbh. Any help appreciated.
You're asking the message to be parsed from the whole of buffer - and my guess is that buffer is more than 88 bytes long.
I can't remember offhand whether parseFrom allows you to specify the maximum amount of data to read, but an alternative would be:
ByteArrayIntputStream stream = new ByteArrayInputStream(buffer, 0, lenbytes);
EnvInfoProto envInfoProto = EnvInfoProto.parseFrom(stream);
Note that this still has the problem that you're assuming you can read all the data from the stream in a single call to read, which is never a good idea - but that's a very separate issue. If you're going to close the socket after writing, you could just parse stream from the socket's InputStream in the Java code, of course. If you're not going to close the stream, I would suggest writing the message length to the socket first (as a 32-bit integer) so you can then read that in Java, and read exactly the right amount of data, knowing when you're finished.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With