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!
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="[email protected]";
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 by ObjectOutputStream (Java). In this case the StreamCorruptedException is being generated because the stream is being given invalid data that was not generated by ObjectOutputStream (Java).
Instead, use DataInputStream (Java) to read the data generated by BinaryWriter (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):
An ObjectInputStream deserializes primitive data and objects previously written using an ObjectOutputStream [in Java].
DataInputSteam (Java):
A data input stream lets an application read primitive [..] types from an underlying input stream ..
BinaryWriter (C#):
Writes primitive types in binary to a stream and supports writing strings in a specific encoding.
Notes:
char/character, short, int, long, float, and double data-types as they have the same signed nature and bitwise representation in C# and Java.byte (Java, signed) vs byte (C#, unsigned). Thankfully, ProtocolBuffer will automatically handle this if given the appropriate byte[] (Java or C#).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