" StreamCorruptedException:无效的流头"阅读时的ObjectInputStream从C#客户端发送 [英] "StreamCorruptedException: invalid stream header" when reading ObjectInputStream sent from C# client
问题描述
问题
我试图发送从C#客户端protobuf的消息,这个Java服务器,但我得到这个异常:
<预类=郎无prettyprint-覆盖>
java.io.StreamCorruptedException:无效的流头:0A290A08
java.io.StreamCorruptedException :无效的流头:0A290A08
在java.io.ObjectInputStream.readStreamHeader(来源不明)LT
在java.io.ObjectInputStream中的&;&初始化GT;(未知来源)
我有点茫然,说实话。任何帮助表示赞赏。谢谢!
- Java服务器
<预类=郎-java的prettyprint-覆盖>
公共ControllerThread(套接字s){
this.s = S;尝试{
this.objectInputStream =新的ObjectInputStream(s.getInputStream());
字节大小= objectInputStream.readByte();的System.out.println(服务器:个字节的+大小);
字节[]字节=新的字节[大小]
objectInputStream.readFully(字节);
通讯簿ADB = AddressBook.parseFrom(字节);
的System.out.println(服务器:地址簿:+ adb.getPersonCount());
}赶上(IOException异常五){
的System.out.println(服务器:奥德的BufferedReader冯的PrintWriter ThermoClient konnte nicht标准化。创建werden);
e.printStackTrace(); }
}}
C#代码
公共地址簿InitializeAdressBook()
{
的人newContact =新的Person();
通讯簿addressBookBuilder =新地址簿();
人约翰=新的Person();
//john.id=1234;
john.name =李四;
john.email =jdoe@example.com;
Person.PhoneNumber NR =新Person.PhoneNumber();
nr.number =5554321;
john.phone.Add(NR);
addressBookBuilder.person.Add(约翰);
TextBox.Text + =(客户端:Initialisiert+ addressBookBuilder.ToString())+\t+\\\
TextBox.Text + =Erster人+ addressBookBuilder.person.First()名+\t+\\\
返回addressBookBuilder;
}
C#的OutputStream
公共无效的SendMessage(NS流,字节[] MSG)
{
字节大小=(字节)msg.Length;
试
{
ns.WriteByte(大小);
ns.Write(味精,0,msg.Length);
ns.Flush();
ns.Close();
}
赶上(ArgumentNullException ANE)
{
TextBox.Text + =ArgumentNullException:{0}+ ane.ToString();
}
赶上(例外五)
{
TextBox.Text + =(意外的异常:{0}+ e.ToString());
}
}
tldr; 这个问题可以用的ObjectInputStream(爪哇)
其中的只能的使用所产生的数据通过的ObjectOutputStream(爪哇)
。在这种情况下, StreamCorruptedException
正在生成因为报错流的按<$产生无效的数据,这是的不的C $ C>的ObjectOutputStream(爪哇)。
相反,使用 DataInputStream所(爪哇)
读取由的BinaryWriter产生的数据(C#)
。这两个唯一支持原始类型。只要的 的是的使用和的 签署馅 是根据需要进行:整数,浮点数,双打(但不是小数),和字节数组可以安全地发送这样
这是ObjectInputStream的反序列化的基本数据和对象的使用ObjectOutputStream [用Java]以前写的。
块引用>
一个数据输入流允许应用程序的读取基本[..]从底层输入流类型 ..
块引用>
写入原始类型以二进制流,并支持在特定的编码写入字符串。
注:
- DataInputSteam(爪哇)是大端,但是的的BinaryWriter(C#)必须转换为大端。
- 有没有问题(除了字节序)传输时
字符/字符
,短
,INT
,长
,浮动
和双击
数据类型,因为他们已经签署了相同的自然和位代表在C#和Java。
- 签名可能会出现问题的
字节(Java中,签字)
VS字节(C#,无符号)
。值得庆幸的是, ProtocolBuffer会自动处理的,如果给予适当的字节[](Java或C#)
。
- 字符串可以因细微差别编码提供更多的乐趣。
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 theStreamCorruptedException
is 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.An ObjectInputStream deserializes primitive data and objects previously written using an ObjectOutputStream [in Java].
A data input stream lets an application read primitive [..] types from an underlying input stream ..
Writes primitive types in binary to a stream and supports writing strings in a specific encoding.
Notes:
- DataInputSteam (Java) is big-endian, but BinaryWriter (C#) must be converted to big-endian.
- There are no issues (aside from endianness) when transferring the
char/character
,short
,int
,long
,float
, anddouble
data-types as they have the same signed nature and bitwise representation in C# and Java.- Signed problems can arise for
byte (Java, signed)
vsbyte (C#, unsigned)
. Thankfully, ProtocolBuffer will automatically handle this if given the appropriatebyte[] (Java or C#)
.- Strings can provide additional fun due to slight encoding differences.
这篇关于" StreamCorruptedException:无效的流头"阅读时的ObjectInputStream从C#客户端发送的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!