[英]“StreamCorruptedException: invalid stream header” when reading ObjectInputStream sent from C# client
问题
我正在尝试从C#客户端向此Java Server发送protobuf消息,但我得到以下异常:
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)
说实话,我有点不知所措。 任何帮助表示赞赏。 谢谢!
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#代码
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; 问题是使用ObjectInputStream (Java)
, 它只适用于ObjectOutputStream (Java)
生成的数据。 在这种情况下, StreamCorruptedException
正在生成由于流是以报错不是由产生的无效数据ObjectOutputStream (Java)
。
而是使用DataInputStream (Java)
读取BinaryWriter (C#)
生成的数据。 这两者都只支持“原始”类型。 只要正确的字节顺序被使用并签署馅是根据需要进行:整数,浮点数,双打(但不是小数),和字节数组可以安全地发送这种方式。
ObjectInputStream对先前使用ObjectOutputStream [在Java中]编写的原始数据和对象进行反序列化。
数据输入流允许应用程序从基础输入流中读取原语[..]类型 。
将二进制中的原始类型写入流并支持以特定编码写入字符串。
笔记:
char/character
, short
, int
, long
, float
和double
数据类型时没有问题(除了字节顺序),因为它们在C#和Java中具有相同的带符号性质和按位表示。 byte (Java, signed)
和byte (C#, unsigned)
可能会出现签名问题。 值得庆幸的是,如果给定适当的byte[] (Java or C#)
, ProtocolBuffer将自动处理此问题 。 所以用这个c#OutputStream方法和DataInputStream (Java)代替ObjectOutputSteam它没有任何问题
public void SendEndianBinaryMsg(Stream ns, byte[] msg)
{
byte size = (byte)msg.Length;
try
{
EndianBinaryWriter writer = new EndianBinaryWriter(EndianBitConverter.Big, ns);
writer.Write(size);
writer.Write(msg);
writer.Flush();
ns.Close();
}
catch (ArgumentNullException ane)
{
TextBox.Text += "ArgumentNullException : {0}" + ane.ToString();
}
catch (Exception e)
{
TextBox.Text += ("Unexpected exception : {0}" + e.ToString());
}
}
笔记:
我从MiscUtil获得EndianBinaryWriter和EndianBitConverter 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.