1

The Client sends a 1481 bytes array. The server can read all the 1481 bytes message without any problems but by parsing the given messsage from the received binary array i get this exeption:

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.

Code

byte [] data= IOUtils.toByteArray(br1, "ASCII"); System.out.println("SIZE:" + data.length);
AddressBook adb1 = AddressBook.parseFrom(data); System.out.println("Server: Addressbook:" + adb1.getPersonCount()); System.out.println("Server: Addressbook:" + adb1.getPerson(0).getName());

Question:

I need to find a way to correctly parse the received Adressbook msg from the read 1481 bytes arry.

Thanks.

Kaiser4you
  • 83
  • 2
  • 3
  • 10
  • You mean 1481 bytes, not bits, right? When you say "the binary data is the same" - the same as what? It's hard to follow what's actually going on here. – Jon Skeet Oct 25 '12 at 12:39
  • i mean the length of byteArray is 1481. – Kaiser4you Oct 25 '12 at 12:49
  • Right. It's important to know the difference between bytes and bits, and use the right term. The rest of the question is still vague. – Jon Skeet Oct 25 '12 at 12:50
  • The received binary data is the same as the sent data – Kaiser4you Oct 25 '12 at 12:51
  • the Problem allthough the received binary data is the same as the sent data i get this Exception: com.google.protobuf.InvalidProtocolBufferException: Protocol message contained an invalid tag (zero). – Kaiser4you Oct 25 '12 at 13:00
  • How have you validated that, and have you tried eliminating the network part entirely? I suggest you create a file instead, and try reading that file from both Java and C# code. – Jon Skeet Oct 25 '12 at 13:03
  • for (int i =0; i – Kaiser4you Oct 31 '12 at 19:57
  • no i dont use a file only for loop to compare the received data with the send byte array – Kaiser4you Oct 31 '12 at 19:59
  • I was suggesting that you *should* use a file - but now that you've posted the code (badly formatted, but...), it seems pretty clear what's wrong - see my answer. – Jon Skeet Oct 31 '12 at 20:01
  • Now it works I had mistakes by [Serializing][1] and [Sending][2] the Protocol Buffers Message [1]: http://stackoverflow.com/questions/13165690/serializing-and-sending-a-protocol-buffers-message [2]: http://stackoverflow.com/questions/13186848/streamcorruptedexception-invalid-stream-header-when-reading-objectinputstream – Kaiser4you Nov 06 '12 at 19:09

2 Answers2

2

This is the problem:

br1 = new InputStreamReader(s.getInputStream());

That's trying to treat opaque binary data as text. It's not text, it's binary data. So when you convert that Reader into a byte array, you've lost a load of the original data - no wonder it's an invalid protocol buffer.

Just use:

AddressBook adb1 = AddressBook.parseFrom(s.getInputStream());

and avoid the lossy text conversion. That's assuming you haven't got something equally broken on the C# side, of course.

If you must go via text, you should use base64 encoding on both sides.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • why i lost a load of the original data if i convert that Reader into a byte arry? I tried your proposal but i get the same **exception** : `com.google.protobuf.InvalidProtocolBufferException: Protocol message contained an invalid tag (zero)` – Kaiser4you Oct 31 '12 at 22:36
  • How could i use the base64 encoding on both sides? Thanks! – Kaiser4you Oct 31 '12 at 22:39
  • 1
    @Kaiser4you: No, you **shouldn't use a Reader at all**. That's the whole point. Readers are about *text* data. A protocol buffer message is *binary* data. Just don't do it! You should only resort to base64 if you *absolutely have to use text* - which is unlikely. – Jon Skeet Oct 31 '12 at 22:44
  • Thanks! Ok which I/O steam it is better to use in this case: BuffredInputStream or DataInputStream or ObjectInputStream? – Kaiser4you Nov 01 '12 at 21:45
  • @Kaiser4you: Unless you're *using* any of the features provided by `DataInputStream` or `ObjectInputStream`, don't use them. You may not even need to use `BufferedInputStream`, as IIRC the Protobuf implementation performs buffering. Just use `s.getInputStream()`, as per my answer. – Jon Skeet Nov 01 '12 at 21:49
  • I need the features of ObjectInputStream could I use it? – Kaiser4you Nov 01 '12 at 22:10
  • @Kaiser4you: I fail to see *how* you could use that, given that you're going to ask Protocol Buffers to parse the stream... what would you want to use it for? – Jon Skeet Nov 01 '12 at 22:11
  • When i use it i get this exception: invalid stream header: 0A290A08 – Kaiser4you Nov 01 '12 at 22:25
  • @Kaiser4you: You haven't answered the previous question, and now you've given an error without any clue about where it's being thrown from. I'm afraid it's *very* hard to help you. – Jon Skeet Nov 01 '12 at 22:26
  • But when i use a java client it works....I need the method objectInputStream.readByte(); – Kaiser4you Nov 01 '12 at 22:26
  • java.io.StreamCorruptedException: invalid stream header: 0A290A08 – Kaiser4you Nov 01 '12 at 22:32
  • @Kaiser4you: Still not nearly enough information (what's the stack trace?), and you've never explained why you would need to call `readByte()` when you should be just passing the stream to `AddressBook.parseFrom`. Sorry, I don't have time to get information from you one tiny piece at a time. – Jon Skeet Nov 01 '12 at 22:33
0

Now it works I had same mistake by Serializing and Sending the Protocol Buffers Message

Community
  • 1
  • 1
Kaiser4you
  • 83
  • 2
  • 3
  • 10