" StreamCorruptedException:无效的流头"阅读时的ObjectInputStream从C#客户端发送 [英] "StreamCorruptedException: invalid stream header" when reading ObjectInputStream sent from C# client

查看:153
本文介绍了" StreamCorruptedException:无效的流头"阅读时的ObjectInputStream从C#客户端发送的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题



我试图发送从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(爪哇)




这是ObjectInputStream的反序列化的基本数据和对象的使用ObjectOutputStream [用Java]以前写的。




DataInputSteam(爪哇)




一个数据输入流允许应用程序的读取基本[..]从底层输入流类型 ..




BinaryWriter(C#)




写入原始类型以二进制流,并支持在特定的编码写入字符串。







注:




  • 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 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:

  • 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, and double data-types as they have the same signed nature and bitwise representation in C# and Java.
  • Signed problems can arise for byte (Java, signed) vs byte (C#, unsigned). Thankfully, ProtocolBuffer will automatically handle this if given the appropriate byte[] (Java or C#).
  • Strings can provide additional fun due to slight encoding differences.

这篇关于&QUOT; StreamCorruptedException:无效的流头&QUOT;阅读时的ObjectInputStream从C#客户端发送的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆