Problem
I’m trying to send a protobuf message from a C# client to this Java Server but I get this exception:
java.io.StreamCorruptedException: invalid stream header: 0A290A08
java.io.StreamCorruptedException: invalid stream header: 0A290A08
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
I’m a bit at a loss to be honest. Any help is appreciated. Thanks!
- Java server
public ControllerThread(Socket s){
this.s = s; try {
this.objectInputStream = new ObjectInputStream(s.getInputStream());
byte size = objectInputStream.readByte();System.out.println("Server: BYTES SIZE:" + size);
byte[] bytes = new byte[size];
objectInputStream.readFully(bytes);
AddressBook adb = AddressBook.parseFrom(bytes);
System.out.println("Server: Addressbook:" + adb.getPersonCount());
} catch (IOException e) {
System.out.println("Server: BufferedReader oder PrintWriter von ThermoClient konnte nicht erstellt werden");
e.printStackTrace(); }
} }
C# code
public AddressBook InitializeAdressBook()
{
Person newContact = new Person();
AddressBook addressBookBuilder = new AddressBook();
Person john = new Person();
//john.id=1234;
john.name="John Doe";
john.email="jdoe@example.com";
Person.PhoneNumber nr = new Person.PhoneNumber();
nr.number="5554321";
john.phone.Add(nr);
addressBookBuilder.person.Add(john);
TextBox.Text += ("Client: Initialisiert? " + addressBookBuilder.ToString()) + "\t" + "\n";
TextBox.Text += " Erster Person " + addressBookBuilder.person.First().name + "\t" + "\n";
return addressBookBuilder;
}
c# OutputStream
public void SendMessage(Stream ns, byte[] msg)
{
byte size = (byte)msg.Length;
try
{
ns.WriteByte(size);
ns.Write(msg, 0, msg.Length);
ns.Flush();
ns.Close();
}
catch (ArgumentNullException ane)
{
TextBox.Text += "ArgumentNullException : {0}" + ane.ToString();
}
catch (Exception e)
{
TextBox.Text += ("Unexpected exception : {0}" + e.ToString());
}
}
tldr; The problem is using
ObjectInputStream (Java)which only works with data generated byObjectOutputStream (Java). In this case theStreamCorruptedExceptionis being generated because the stream is being given invalid data that was not generated byObjectOutputStream (Java).Instead, use
DataInputStream (Java)to read the data generated byBinaryWriter (C#). Both of these only support “primitive” types. As long as the correct endianess is used and sign stuffing is performed as needed: integers, floats, doubles (but not Decimals), and byte arrays can be safely sent this way.ObjectInputStream (Java):DataInputSteam (Java):BinaryWriter (C#):Notes:
char/character,short,int,long,float, anddoubledata-types as they have the same signed nature and bitwise representation in C# and Java.byte (Java, signed)vsbyte (C#, unsigned). Thankfully, ProtocolBuffer will automatically handle this if given the appropriatebyte[] (Java or C#).