0

TCPパケットのバイト配列に変換できるように、いくつかのオブジェクトをシリアル化しました。サーバープログラムからクライアントプログラムにオブジェクトを送信する場合、問題はなく、正常に動作します。ただし、サーバーとクライアント間のコードは同じですが、クライアントからサーバーにオブジェクトを送信しようとすると、無効なヘッダーが表示されます。

シリアル化するオブジェクトは次のとおりです。

    public static byte[] serialize(Hand c) throws IOException
    {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(c);
        return baos.toByteArray();
    }

    public static Hand deserialize(byte[] bytes) throws IOException, ClassNotFoundException
    {
        ByteArrayInputStream b = new ByteArrayInputStream(bytes);
        ObjectInputStream o = new ObjectInputStream(b);
        return (Hand) o.readObject();
    }

    public static byte[] serialize(Card c) throws IOException
    {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(c);
        return baos.toByteArray();
    }

    public static Card deserialize(byte[] bytes) throws IOException, ClassNotFoundException
    {
        ByteArrayInputStream b = new ByteArrayInputStream(bytes);
        ObjectInputStream o = new ObjectInputStream(b);
        return (Card) o.readObject();
    }

これらは両方ともサーバープログラムから取得されますが、シリアル化のコードはサーバーとクライアントで同じです。このようなエラーが発生しないように、サーバーからクライアントへのCardクラスとHandクラスを正確に重要視しています。

サーバーはカードまたはハンドをbyte[]に変換し、DataOutputStreamを介してクライアントに書き込むことができ、クライアントはDataInputStreamを介してカードまたはハンドを受信し、逆シリアル化して、問題なく読み取ることができます。しかし、クライアントからサーバーにカードまたはハンドを送信しようとすると、それが機能することはめったになく、通常は

Exception in thread "main" java.io.StreamCorruptedException: invalid stream header: 434B0005
    at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
    at java.io.ObjectInputStream.<init>(Unknown Source)
    at Hand.deserialize(Hand.java:29)
    at KoiKoi_TCP_Server.takeClientTurn(KoiKoi_TCP_Server.java:321)
    at KoiKoi_TCP_Server.main(KoiKoi_TCP_Server.java:380)

ここで、Hand.java.29は行を指しています

        ObjectInputStream o = new ObjectInputStream(b);

ハンドデシリアライズ方式で。

ヘッダーが無効であると言っていることを理解しています。一方向にしか壊れず、コードも同じなので、修正方法がわかりません。提案?

一度に送信するのは1つのオブジェクトのみなので、複数のObjectInputStreamsなどを初期化することはありません。

4

1 に答える 1

1

複数の ObjectOutputStreams などを初期化していません。

はい、そうです。すべてのオブジェクトに対して新しい ObjectOutputStream を初期化しています。次に、各オブジェクトを受信するために読み取るバイト数を知るという追加の問題を自分自身に与えており、それが間違っているため、同期が取れていません。 .

これをすべて取り除きます。あなたはそれを必要としません。問題を追加しているだけです。ソケットの存続期間中、単一の ObjectOutputStream と ObjectInputStream を直接使用し、ソケット ストリーム上に直接構築し、オブジェクトを送信する場合は writeObject() を呼び出し、オブジェクトを読み取りたい場合は readObject() を呼び出します。2 行のコード。バイト配列と ByteArray/DataInput/OutputStreams を完全に忘れてください。

于 2013-03-11T03:29:09.663 に答える